1 //===-- SBThread.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/API/SBThread.h"
10 #include "lldb/Utility/ReproducerInstrumentation.h"
11 #include "Utils.h"
12 #include "lldb/API/SBAddress.h"
13 #include "lldb/API/SBDebugger.h"
14 #include "lldb/API/SBEvent.h"
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/API/SBFrame.h"
17 #include "lldb/API/SBProcess.h"
18 #include "lldb/API/SBStream.h"
19 #include "lldb/API/SBStructuredData.h"
20 #include "lldb/API/SBSymbolContext.h"
21 #include "lldb/API/SBThreadCollection.h"
22 #include "lldb/API/SBThreadPlan.h"
23 #include "lldb/API/SBValue.h"
24 #include "lldb/Breakpoint/BreakpointLocation.h"
25 #include "lldb/Core/Debugger.h"
26 #include "lldb/Core/StreamFile.h"
27 #include "lldb/Core/StructuredDataImpl.h"
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Symbol/CompileUnit.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/Queue.h"
34 #include "lldb/Target/StopInfo.h"
35 #include "lldb/Target/SystemRuntime.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Target/ThreadPlan.h"
39 #include "lldb/Target/ThreadPlanStepInRange.h"
40 #include "lldb/Target/ThreadPlanStepInstruction.h"
41 #include "lldb/Target/ThreadPlanStepOut.h"
42 #include "lldb/Target/ThreadPlanStepRange.h"
43 #include "lldb/Utility/State.h"
44 #include "lldb/Utility/Stream.h"
45 #include "lldb/Utility/StructuredData.h"
46 #include "lldb/lldb-enumerations.h"
47 
48 #include <memory>
49 
50 using namespace lldb;
51 using namespace lldb_private;
52 
53 const char *SBThread::GetBroadcasterClassName() {
54   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
55                                     GetBroadcasterClassName);
56 
57   return Thread::GetStaticBroadcasterClass().AsCString();
58 }
59 
60 // Constructors
61 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
62   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
63 }
64 
65 SBThread::SBThread(const ThreadSP &lldb_object_sp)
66     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
67   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
68 }
69 
70 SBThread::SBThread(const SBThread &rhs) {
71   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
72 
73   m_opaque_sp = clone(rhs.m_opaque_sp);
74 }
75 
76 // Assignment operator
77 
78 const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
79   LLDB_RECORD_METHOD(const lldb::SBThread &,
80                      SBThread, operator=,(const lldb::SBThread &), rhs);
81 
82   if (this != &rhs)
83     m_opaque_sp = clone(rhs.m_opaque_sp);
84   return *this;
85 }
86 
87 // Destructor
88 SBThread::~SBThread() = default;
89 
90 lldb::SBQueue SBThread::GetQueue() const {
91   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
92 
93   SBQueue sb_queue;
94   QueueSP queue_sp;
95   std::unique_lock<std::recursive_mutex> lock;
96   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
97 
98   if (exe_ctx.HasThreadScope()) {
99     Process::StopLocker stop_locker;
100     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
101       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
102       if (queue_sp) {
103         sb_queue.SetQueue(queue_sp);
104       }
105     }
106   }
107 
108   return sb_queue;
109 }
110 
111 bool SBThread::IsValid() const {
112   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
113   return this->operator bool();
114 }
115 SBThread::operator bool() const {
116   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
117 
118   std::unique_lock<std::recursive_mutex> lock;
119   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
120 
121   Target *target = exe_ctx.GetTargetPtr();
122   Process *process = exe_ctx.GetProcessPtr();
123   if (target && process) {
124     Process::StopLocker stop_locker;
125     if (stop_locker.TryLock(&process->GetRunLock()))
126       return m_opaque_sp->GetThreadSP().get() != nullptr;
127   }
128   // Without a valid target & process, this thread can't be valid.
129   return false;
130 }
131 
132 void SBThread::Clear() {
133   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
134 
135   m_opaque_sp->Clear();
136 }
137 
138 StopReason SBThread::GetStopReason() {
139   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
140 
141   StopReason reason = eStopReasonInvalid;
142   std::unique_lock<std::recursive_mutex> lock;
143   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
144 
145   if (exe_ctx.HasThreadScope()) {
146     Process::StopLocker stop_locker;
147     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
148       return exe_ctx.GetThreadPtr()->GetStopReason();
149     }
150   }
151 
152   return reason;
153 }
154 
155 size_t SBThread::GetStopReasonDataCount() {
156   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
157 
158   std::unique_lock<std::recursive_mutex> lock;
159   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
160 
161   if (exe_ctx.HasThreadScope()) {
162     Process::StopLocker stop_locker;
163     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
164       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
165       if (stop_info_sp) {
166         StopReason reason = stop_info_sp->GetStopReason();
167         switch (reason) {
168         case eStopReasonInvalid:
169         case eStopReasonNone:
170         case eStopReasonTrace:
171         case eStopReasonExec:
172         case eStopReasonPlanComplete:
173         case eStopReasonThreadExiting:
174         case eStopReasonInstrumentation:
175         case eStopReasonProcessorTrace:
176         case eStopReasonVForkDone:
177           // There is no data for these stop reasons.
178           return 0;
179 
180         case eStopReasonBreakpoint: {
181           break_id_t site_id = stop_info_sp->GetValue();
182           lldb::BreakpointSiteSP bp_site_sp(
183               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
184                   site_id));
185           if (bp_site_sp)
186             return bp_site_sp->GetNumberOfOwners() * 2;
187           else
188             return 0; // Breakpoint must have cleared itself...
189         } break;
190 
191         case eStopReasonWatchpoint:
192           return 1;
193 
194         case eStopReasonSignal:
195           return 1;
196 
197         case eStopReasonException:
198           return 1;
199 
200         case eStopReasonFork:
201           return 1;
202 
203         case eStopReasonVFork:
204           return 1;
205         }
206       }
207     }
208   }
209   return 0;
210 }
211 
212 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
213   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
214                      idx);
215 
216   std::unique_lock<std::recursive_mutex> lock;
217   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
218 
219   if (exe_ctx.HasThreadScope()) {
220     Process::StopLocker stop_locker;
221     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
222       Thread *thread = exe_ctx.GetThreadPtr();
223       StopInfoSP stop_info_sp = thread->GetStopInfo();
224       if (stop_info_sp) {
225         StopReason reason = stop_info_sp->GetStopReason();
226         switch (reason) {
227         case eStopReasonInvalid:
228         case eStopReasonNone:
229         case eStopReasonTrace:
230         case eStopReasonExec:
231         case eStopReasonPlanComplete:
232         case eStopReasonThreadExiting:
233         case eStopReasonInstrumentation:
234         case eStopReasonProcessorTrace:
235         case eStopReasonVForkDone:
236           // There is no data for these stop reasons.
237           return 0;
238 
239         case eStopReasonBreakpoint: {
240           break_id_t site_id = stop_info_sp->GetValue();
241           lldb::BreakpointSiteSP bp_site_sp(
242               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
243                   site_id));
244           if (bp_site_sp) {
245             uint32_t bp_index = idx / 2;
246             BreakpointLocationSP bp_loc_sp(
247                 bp_site_sp->GetOwnerAtIndex(bp_index));
248             if (bp_loc_sp) {
249               if (idx & 1) {
250                 // Odd idx, return the breakpoint location ID
251                 return bp_loc_sp->GetID();
252               } else {
253                 // Even idx, return the breakpoint ID
254                 return bp_loc_sp->GetBreakpoint().GetID();
255               }
256             }
257           }
258           return LLDB_INVALID_BREAK_ID;
259         } break;
260 
261         case eStopReasonWatchpoint:
262           return stop_info_sp->GetValue();
263 
264         case eStopReasonSignal:
265           return stop_info_sp->GetValue();
266 
267         case eStopReasonException:
268           return stop_info_sp->GetValue();
269 
270         case eStopReasonFork:
271           return stop_info_sp->GetValue();
272 
273         case eStopReasonVFork:
274           return stop_info_sp->GetValue();
275         }
276       }
277     }
278   }
279   return 0;
280 }
281 
282 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
283   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
284                      (lldb::SBStream &), stream);
285 
286   Stream &strm = stream.ref();
287 
288   std::unique_lock<std::recursive_mutex> lock;
289   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
290 
291   if (!exe_ctx.HasThreadScope())
292     return false;
293 
294   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
295   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
296   if (!info)
297     return false;
298 
299   info->Dump(strm);
300 
301   return true;
302 }
303 
304 SBThreadCollection
305 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
306   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
307                      GetStopReasonExtendedBacktraces,
308                      (lldb::InstrumentationRuntimeType), type);
309 
310   SBThreadCollection threads;
311 
312   std::unique_lock<std::recursive_mutex> lock;
313   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
314 
315   if (!exe_ctx.HasThreadScope())
316     return SBThreadCollection();
317 
318   ProcessSP process_sp = exe_ctx.GetProcessSP();
319 
320   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
321   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
322   if (!info)
323     return threads;
324 
325   threads = process_sp->GetInstrumentationRuntime(type)
326                 ->GetBacktracesFromExtendedStopInfo(info);
327   return threads;
328 }
329 
330 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
331   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t),
332                      dst, "", dst_len);
333 
334   std::unique_lock<std::recursive_mutex> lock;
335   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
336 
337   if (dst)
338     *dst = 0;
339 
340   if (!exe_ctx.HasThreadScope())
341     return 0;
342 
343   Process::StopLocker stop_locker;
344   if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
345     return 0;
346 
347   std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription();
348   if (thread_stop_desc.empty())
349     return 0;
350 
351   if (dst)
352     return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1;
353 
354   // NULL dst passed in, return the length needed to contain the
355   // description.
356   return thread_stop_desc.size() + 1; // Include the NULL byte for size
357 }
358 
359 SBValue SBThread::GetStopReturnValue() {
360   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
361 
362   ValueObjectSP return_valobj_sp;
363   std::unique_lock<std::recursive_mutex> lock;
364   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
365 
366   if (exe_ctx.HasThreadScope()) {
367     Process::StopLocker stop_locker;
368     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
369       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
370       if (stop_info_sp) {
371         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
372       }
373     }
374   }
375 
376   return SBValue(return_valobj_sp);
377 }
378 
379 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
380   m_opaque_sp->SetThreadSP(lldb_object_sp);
381 }
382 
383 lldb::tid_t SBThread::GetThreadID() const {
384   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
385 
386   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
387   if (thread_sp)
388     return thread_sp->GetID();
389   return LLDB_INVALID_THREAD_ID;
390 }
391 
392 uint32_t SBThread::GetIndexID() const {
393   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
394 
395   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
396   if (thread_sp)
397     return thread_sp->GetIndexID();
398   return LLDB_INVALID_INDEX32;
399 }
400 
401 const char *SBThread::GetName() const {
402   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
403 
404   const char *name = nullptr;
405   std::unique_lock<std::recursive_mutex> lock;
406   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
407 
408   if (exe_ctx.HasThreadScope()) {
409     Process::StopLocker stop_locker;
410     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
411       name = exe_ctx.GetThreadPtr()->GetName();
412     }
413   }
414 
415   return name;
416 }
417 
418 const char *SBThread::GetQueueName() const {
419   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
420 
421   const char *name = nullptr;
422   std::unique_lock<std::recursive_mutex> lock;
423   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
424 
425   if (exe_ctx.HasThreadScope()) {
426     Process::StopLocker stop_locker;
427     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
428       name = exe_ctx.GetThreadPtr()->GetQueueName();
429     }
430   }
431 
432   return name;
433 }
434 
435 lldb::queue_id_t SBThread::GetQueueID() const {
436   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
437 
438   queue_id_t id = LLDB_INVALID_QUEUE_ID;
439   std::unique_lock<std::recursive_mutex> lock;
440   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
441 
442   if (exe_ctx.HasThreadScope()) {
443     Process::StopLocker stop_locker;
444     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
445       id = exe_ctx.GetThreadPtr()->GetQueueID();
446     }
447   }
448 
449   return id;
450 }
451 
452 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
453   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
454                      (const char *, lldb::SBStream &), path, strm);
455 
456   bool success = false;
457   std::unique_lock<std::recursive_mutex> lock;
458   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
459 
460   if (exe_ctx.HasThreadScope()) {
461     Process::StopLocker stop_locker;
462     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
463       Thread *thread = exe_ctx.GetThreadPtr();
464       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
465       if (info_root_sp) {
466         StructuredData::ObjectSP node =
467             info_root_sp->GetObjectForDotSeparatedPath(path);
468         if (node) {
469           if (node->GetType() == eStructuredDataTypeString) {
470             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
471             success = true;
472           }
473           if (node->GetType() == eStructuredDataTypeInteger) {
474             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
475             success = true;
476           }
477           if (node->GetType() == eStructuredDataTypeFloat) {
478             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
479             success = true;
480           }
481           if (node->GetType() == eStructuredDataTypeBoolean) {
482             if (node->GetAsBoolean()->GetValue())
483               strm.Printf("true");
484             else
485               strm.Printf("false");
486             success = true;
487           }
488           if (node->GetType() == eStructuredDataTypeNull) {
489             strm.Printf("null");
490             success = true;
491           }
492         }
493       }
494     }
495   }
496 
497   return success;
498 }
499 
500 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
501                                 ThreadPlan *new_plan) {
502   SBError sb_error;
503 
504   Process *process = exe_ctx.GetProcessPtr();
505   if (!process) {
506     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
507     return sb_error;
508   }
509 
510   Thread *thread = exe_ctx.GetThreadPtr();
511   if (!thread) {
512     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
513     return sb_error;
514   }
515 
516   // User level plans should be Controlling Plans so they can be interrupted,
517   // other plans executed, and then a "continue" will resume the plan.
518   if (new_plan != nullptr) {
519     new_plan->SetIsControllingPlan(true);
520     new_plan->SetOkayToDiscard(false);
521   }
522 
523   // Why do we need to set the current thread by ID here???
524   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
525 
526   if (process->GetTarget().GetDebugger().GetAsyncExecution())
527     sb_error.ref() = process->Resume();
528   else
529     sb_error.ref() = process->ResumeSynchronous(nullptr);
530 
531   return sb_error;
532 }
533 
534 void SBThread::StepOver(lldb::RunMode stop_other_threads) {
535   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
536                      stop_other_threads);
537 
538   SBError error; // Ignored
539   StepOver(stop_other_threads, error);
540 }
541 
542 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
543   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
544                      stop_other_threads, error);
545 
546   std::unique_lock<std::recursive_mutex> lock;
547   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
548 
549   if (!exe_ctx.HasThreadScope()) {
550     error.SetErrorString("this SBThread object is invalid");
551     return;
552   }
553 
554   Thread *thread = exe_ctx.GetThreadPtr();
555   bool abort_other_plans = false;
556   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
557 
558   Status new_plan_status;
559   ThreadPlanSP new_plan_sp;
560   if (frame_sp) {
561     if (frame_sp->HasDebugInformation()) {
562       const LazyBool avoid_no_debug = eLazyBoolCalculate;
563       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
564       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
565           abort_other_plans, sc.line_entry, sc, stop_other_threads,
566           new_plan_status, avoid_no_debug);
567     } else {
568       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
569           true, abort_other_plans, stop_other_threads, new_plan_status);
570     }
571   }
572   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
573 }
574 
575 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
576   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
577                      stop_other_threads);
578 
579   StepInto(nullptr, stop_other_threads);
580 }
581 
582 void SBThread::StepInto(const char *target_name,
583                         lldb::RunMode stop_other_threads) {
584   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
585                      target_name, stop_other_threads);
586 
587   SBError error; // Ignored
588   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
589 }
590 
591 void SBThread::StepInto(const char *target_name, uint32_t end_line,
592                         SBError &error, lldb::RunMode stop_other_threads) {
593   LLDB_RECORD_METHOD(void, SBThread, StepInto,
594                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
595                      target_name, end_line, error, stop_other_threads);
596 
597 
598   std::unique_lock<std::recursive_mutex> lock;
599   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
600 
601   if (!exe_ctx.HasThreadScope()) {
602     error.SetErrorString("this SBThread object is invalid");
603     return;
604   }
605 
606   bool abort_other_plans = false;
607 
608   Thread *thread = exe_ctx.GetThreadPtr();
609   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
610   ThreadPlanSP new_plan_sp;
611   Status new_plan_status;
612 
613   if (frame_sp && frame_sp->HasDebugInformation()) {
614     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
615     AddressRange range;
616     if (end_line == LLDB_INVALID_LINE_NUMBER)
617       range = sc.line_entry.range;
618     else {
619       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
620         return;
621     }
622 
623     const LazyBool step_out_avoids_code_without_debug_info =
624         eLazyBoolCalculate;
625     const LazyBool step_in_avoids_code_without_debug_info =
626         eLazyBoolCalculate;
627     new_plan_sp = thread->QueueThreadPlanForStepInRange(
628         abort_other_plans, range, sc, target_name, stop_other_threads,
629         new_plan_status, step_in_avoids_code_without_debug_info,
630         step_out_avoids_code_without_debug_info);
631   } else {
632     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
633         false, abort_other_plans, stop_other_threads, new_plan_status);
634   }
635 
636   if (new_plan_status.Success())
637     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
638   else
639     error.SetErrorString(new_plan_status.AsCString());
640 }
641 
642 void SBThread::StepOut() {
643   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
644 
645   SBError error; // Ignored
646   StepOut(error);
647 }
648 
649 void SBThread::StepOut(SBError &error) {
650   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
651 
652   std::unique_lock<std::recursive_mutex> lock;
653   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
654 
655   if (!exe_ctx.HasThreadScope()) {
656     error.SetErrorString("this SBThread object is invalid");
657     return;
658   }
659 
660   bool abort_other_plans = false;
661   bool stop_other_threads = false;
662 
663   Thread *thread = exe_ctx.GetThreadPtr();
664 
665   const LazyBool avoid_no_debug = eLazyBoolCalculate;
666   Status new_plan_status;
667   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
668       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
669       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
670 
671   if (new_plan_status.Success())
672     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
673   else
674     error.SetErrorString(new_plan_status.AsCString());
675 }
676 
677 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
678   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
679                      sb_frame);
680 
681   SBError error; // Ignored
682   StepOutOfFrame(sb_frame, error);
683 }
684 
685 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
686   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
687                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
688 
689 
690   std::unique_lock<std::recursive_mutex> lock;
691   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
692 
693   if (!sb_frame.IsValid()) {
694     error.SetErrorString("passed invalid SBFrame object");
695     return;
696   }
697 
698   StackFrameSP frame_sp(sb_frame.GetFrameSP());
699 
700   if (!exe_ctx.HasThreadScope()) {
701     error.SetErrorString("this SBThread object is invalid");
702     return;
703   }
704 
705   bool abort_other_plans = false;
706   bool stop_other_threads = false;
707   Thread *thread = exe_ctx.GetThreadPtr();
708   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
709     error.SetErrorString("passed a frame from another thread");
710     return;
711   }
712 
713   Status new_plan_status;
714   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
715       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
716       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
717 
718   if (new_plan_status.Success())
719     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
720   else
721     error.SetErrorString(new_plan_status.AsCString());
722 }
723 
724 void SBThread::StepInstruction(bool step_over) {
725   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
726 
727   SBError error; // Ignored
728   StepInstruction(step_over, error);
729 }
730 
731 void SBThread::StepInstruction(bool step_over, SBError &error) {
732   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
733                      step_over, error);
734 
735   std::unique_lock<std::recursive_mutex> lock;
736   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
737 
738   if (!exe_ctx.HasThreadScope()) {
739     error.SetErrorString("this SBThread object is invalid");
740     return;
741   }
742 
743   Thread *thread = exe_ctx.GetThreadPtr();
744   Status new_plan_status;
745   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
746       step_over, true, true, new_plan_status));
747 
748   if (new_plan_status.Success())
749     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
750   else
751     error.SetErrorString(new_plan_status.AsCString());
752 }
753 
754 void SBThread::RunToAddress(lldb::addr_t addr) {
755   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
756 
757   SBError error; // Ignored
758   RunToAddress(addr, error);
759 }
760 
761 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
762   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
763                      (lldb::addr_t, lldb::SBError &), addr, error);
764 
765   std::unique_lock<std::recursive_mutex> lock;
766   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
767 
768   if (!exe_ctx.HasThreadScope()) {
769     error.SetErrorString("this SBThread object is invalid");
770     return;
771   }
772 
773   bool abort_other_plans = false;
774   bool stop_other_threads = true;
775 
776   Address target_addr(addr);
777 
778   Thread *thread = exe_ctx.GetThreadPtr();
779 
780   Status new_plan_status;
781   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
782       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
783 
784   if (new_plan_status.Success())
785     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
786   else
787     error.SetErrorString(new_plan_status.AsCString());
788 }
789 
790 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
791                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
792   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
793                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
794                      sb_file_spec, line);
795 
796   SBError sb_error;
797   char path[PATH_MAX];
798 
799   std::unique_lock<std::recursive_mutex> lock;
800   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
801 
802   StackFrameSP frame_sp(sb_frame.GetFrameSP());
803 
804   if (exe_ctx.HasThreadScope()) {
805     Target *target = exe_ctx.GetTargetPtr();
806     Thread *thread = exe_ctx.GetThreadPtr();
807 
808     if (line == 0) {
809       sb_error.SetErrorString("invalid line argument");
810       return sb_error;
811     }
812 
813     if (!frame_sp) {
814       frame_sp = thread->GetSelectedFrame();
815       if (!frame_sp)
816         frame_sp = thread->GetStackFrameAtIndex(0);
817     }
818 
819     SymbolContext frame_sc;
820     if (!frame_sp) {
821       sb_error.SetErrorString("no valid frames in thread to step");
822       return sb_error;
823     }
824 
825     // If we have a frame, get its line
826     frame_sc = frame_sp->GetSymbolContext(
827         eSymbolContextCompUnit | eSymbolContextFunction |
828         eSymbolContextLineEntry | eSymbolContextSymbol);
829 
830     if (frame_sc.comp_unit == nullptr) {
831       sb_error.SetErrorStringWithFormat(
832           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
833       return sb_error;
834     }
835 
836     FileSpec step_file_spec;
837     if (sb_file_spec.IsValid()) {
838       // The file spec passed in was valid, so use it
839       step_file_spec = sb_file_spec.ref();
840     } else {
841       if (frame_sc.line_entry.IsValid())
842         step_file_spec = frame_sc.line_entry.file;
843       else {
844         sb_error.SetErrorString("invalid file argument or no file for frame");
845         return sb_error;
846       }
847     }
848 
849     // Grab the current function, then we will make sure the "until" address is
850     // within the function.  We discard addresses that are out of the current
851     // function, and then if there are no addresses remaining, give an
852     // appropriate error message.
853 
854     bool all_in_function = true;
855     AddressRange fun_range = frame_sc.function->GetAddressRange();
856 
857     std::vector<addr_t> step_over_until_addrs;
858     const bool abort_other_plans = false;
859     const bool stop_other_threads = false;
860     // TODO: Handle SourceLocationSpec column information
861     SourceLocationSpec location_spec(
862         step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true,
863         /*exact_match=*/false);
864 
865     SymbolContextList sc_list;
866     frame_sc.comp_unit->ResolveSymbolContext(location_spec,
867                                              eSymbolContextLineEntry, sc_list);
868     const uint32_t num_matches = sc_list.GetSize();
869     if (num_matches > 0) {
870       SymbolContext sc;
871       for (uint32_t i = 0; i < num_matches; ++i) {
872         if (sc_list.GetContextAtIndex(i, sc)) {
873           addr_t step_addr =
874               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
875           if (step_addr != LLDB_INVALID_ADDRESS) {
876             if (fun_range.ContainsLoadAddress(step_addr, target))
877               step_over_until_addrs.push_back(step_addr);
878             else
879               all_in_function = false;
880           }
881         }
882       }
883     }
884 
885     if (step_over_until_addrs.empty()) {
886       if (all_in_function) {
887         step_file_spec.GetPath(path, sizeof(path));
888         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
889                                           line);
890       } else
891         sb_error.SetErrorString("step until target not in current function");
892     } else {
893       Status new_plan_status;
894       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
895           abort_other_plans, &step_over_until_addrs[0],
896           step_over_until_addrs.size(), stop_other_threads,
897           frame_sp->GetFrameIndex(), new_plan_status));
898 
899       if (new_plan_status.Success())
900         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
901       else
902         sb_error.SetErrorString(new_plan_status.AsCString());
903     }
904   } else {
905     sb_error.SetErrorString("this SBThread object is invalid");
906   }
907   return sb_error;
908 }
909 
910 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
911   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
912                      (const char *), script_class_name);
913 
914   return StepUsingScriptedThreadPlan(script_class_name, true);
915 }
916 
917 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
918                                             bool resume_immediately) {
919   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
920                      (const char *, bool), script_class_name,
921                      resume_immediately);
922 
923   lldb::SBStructuredData no_data;
924   return StepUsingScriptedThreadPlan(script_class_name, no_data,
925                                      resume_immediately);
926 }
927 
928 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
929                                               SBStructuredData &args_data,
930                                               bool resume_immediately) {
931   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
932                      (const char *, lldb::SBStructuredData &, bool),
933                      script_class_name, args_data, resume_immediately);
934 
935   SBError error;
936 
937   std::unique_lock<std::recursive_mutex> lock;
938   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
939 
940   if (!exe_ctx.HasThreadScope()) {
941     error.SetErrorString("this SBThread object is invalid");
942     return error;
943   }
944 
945   Thread *thread = exe_ctx.GetThreadPtr();
946   Status new_plan_status;
947   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
948 
949   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
950       false, script_class_name, obj_sp, false, new_plan_status);
951 
952   if (new_plan_status.Fail()) {
953     error.SetErrorString(new_plan_status.AsCString());
954     return error;
955   }
956 
957   if (!resume_immediately)
958     return error;
959 
960   if (new_plan_status.Success())
961     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
962   else
963     error.SetErrorString(new_plan_status.AsCString());
964 
965   return error;
966 }
967 
968 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
969   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
970                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
971 
972   SBError sb_error;
973 
974   std::unique_lock<std::recursive_mutex> lock;
975   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
976 
977   if (!exe_ctx.HasThreadScope()) {
978     sb_error.SetErrorString("this SBThread object is invalid");
979     return sb_error;
980   }
981 
982   Thread *thread = exe_ctx.GetThreadPtr();
983 
984   Status err = thread->JumpToLine(file_spec.ref(), line, true);
985   sb_error.SetError(err);
986   return sb_error;
987 }
988 
989 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
990   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
991                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
992 
993   SBError sb_error;
994 
995   std::unique_lock<std::recursive_mutex> lock;
996   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
997 
998   if (exe_ctx.HasThreadScope()) {
999     Thread *thread = exe_ctx.GetThreadPtr();
1000     sb_error.SetError(
1001         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1002   }
1003 
1004   return sb_error;
1005 }
1006 
1007 SBError SBThread::UnwindInnermostExpression() {
1008   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1009                              UnwindInnermostExpression);
1010 
1011   SBError sb_error;
1012 
1013   std::unique_lock<std::recursive_mutex> lock;
1014   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1015 
1016   if (exe_ctx.HasThreadScope()) {
1017     Thread *thread = exe_ctx.GetThreadPtr();
1018     sb_error.SetError(thread->UnwindInnermostExpression());
1019     if (sb_error.Success())
1020       thread->SetSelectedFrameByIndex(0, false);
1021   }
1022 
1023   return sb_error;
1024 }
1025 
1026 bool SBThread::Suspend() {
1027   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1028 
1029   SBError error; // Ignored
1030   return Suspend(error);
1031 }
1032 
1033 bool SBThread::Suspend(SBError &error) {
1034   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1035 
1036   std::unique_lock<std::recursive_mutex> lock;
1037   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1038 
1039   bool result = false;
1040   if (exe_ctx.HasThreadScope()) {
1041     Process::StopLocker stop_locker;
1042     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1043       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1044       result = true;
1045     } else {
1046       error.SetErrorString("process is running");
1047     }
1048   } else
1049     error.SetErrorString("this SBThread object is invalid");
1050   return result;
1051 }
1052 
1053 bool SBThread::Resume() {
1054   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1055 
1056   SBError error; // Ignored
1057   return Resume(error);
1058 }
1059 
1060 bool SBThread::Resume(SBError &error) {
1061   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1062 
1063   std::unique_lock<std::recursive_mutex> lock;
1064   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1065 
1066   bool result = false;
1067   if (exe_ctx.HasThreadScope()) {
1068     Process::StopLocker stop_locker;
1069     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1070       const bool override_suspend = true;
1071       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1072       result = true;
1073     } else {
1074       error.SetErrorString("process is running");
1075     }
1076   } else
1077     error.SetErrorString("this SBThread object is invalid");
1078   return result;
1079 }
1080 
1081 bool SBThread::IsSuspended() {
1082   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1083 
1084   std::unique_lock<std::recursive_mutex> lock;
1085   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1086 
1087   if (exe_ctx.HasThreadScope())
1088     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1089   return false;
1090 }
1091 
1092 bool SBThread::IsStopped() {
1093   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1094 
1095   std::unique_lock<std::recursive_mutex> lock;
1096   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1097 
1098   if (exe_ctx.HasThreadScope())
1099     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1100   return false;
1101 }
1102 
1103 SBProcess SBThread::GetProcess() {
1104   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1105 
1106   SBProcess sb_process;
1107   std::unique_lock<std::recursive_mutex> lock;
1108   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1109 
1110   if (exe_ctx.HasThreadScope()) {
1111     // Have to go up to the target so we can get a shared pointer to our
1112     // process...
1113     sb_process.SetSP(exe_ctx.GetProcessSP());
1114   }
1115 
1116   return sb_process;
1117 }
1118 
1119 uint32_t SBThread::GetNumFrames() {
1120   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1121 
1122   uint32_t num_frames = 0;
1123   std::unique_lock<std::recursive_mutex> lock;
1124   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1125 
1126   if (exe_ctx.HasThreadScope()) {
1127     Process::StopLocker stop_locker;
1128     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1129       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1130     }
1131   }
1132 
1133   return num_frames;
1134 }
1135 
1136 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1137   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1138 
1139   SBFrame sb_frame;
1140   StackFrameSP frame_sp;
1141   std::unique_lock<std::recursive_mutex> lock;
1142   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1143 
1144   if (exe_ctx.HasThreadScope()) {
1145     Process::StopLocker stop_locker;
1146     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1147       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1148       sb_frame.SetFrameSP(frame_sp);
1149     }
1150   }
1151 
1152   return sb_frame;
1153 }
1154 
1155 lldb::SBFrame SBThread::GetSelectedFrame() {
1156   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1157 
1158   SBFrame sb_frame;
1159   StackFrameSP frame_sp;
1160   std::unique_lock<std::recursive_mutex> lock;
1161   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1162 
1163   if (exe_ctx.HasThreadScope()) {
1164     Process::StopLocker stop_locker;
1165     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1166       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1167       sb_frame.SetFrameSP(frame_sp);
1168     }
1169   }
1170 
1171   return sb_frame;
1172 }
1173 
1174 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1175   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1176                      idx);
1177 
1178   SBFrame sb_frame;
1179   StackFrameSP frame_sp;
1180   std::unique_lock<std::recursive_mutex> lock;
1181   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1182 
1183   if (exe_ctx.HasThreadScope()) {
1184     Process::StopLocker stop_locker;
1185     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1186       Thread *thread = exe_ctx.GetThreadPtr();
1187       frame_sp = thread->GetStackFrameAtIndex(idx);
1188       if (frame_sp) {
1189         thread->SetSelectedFrame(frame_sp.get());
1190         sb_frame.SetFrameSP(frame_sp);
1191       }
1192     }
1193   }
1194 
1195   return sb_frame;
1196 }
1197 
1198 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1199   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1200                             (const lldb::SBEvent &), event);
1201 
1202   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1203 }
1204 
1205 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1206   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1207                             (const lldb::SBEvent &), event);
1208 
1209   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1210 }
1211 
1212 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1213   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1214                             (const lldb::SBEvent &), event);
1215 
1216   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1217 }
1218 
1219 bool SBThread::operator==(const SBThread &rhs) const {
1220   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1221                            rhs);
1222 
1223   return m_opaque_sp->GetThreadSP().get() ==
1224          rhs.m_opaque_sp->GetThreadSP().get();
1225 }
1226 
1227 bool SBThread::operator!=(const SBThread &rhs) const {
1228   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1229                            rhs);
1230 
1231   return m_opaque_sp->GetThreadSP().get() !=
1232          rhs.m_opaque_sp->GetThreadSP().get();
1233 }
1234 
1235 bool SBThread::GetStatus(SBStream &status) const {
1236   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1237                            status);
1238 
1239   Stream &strm = status.ref();
1240 
1241   std::unique_lock<std::recursive_mutex> lock;
1242   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1243 
1244   if (exe_ctx.HasThreadScope()) {
1245     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1246   } else
1247     strm.PutCString("No status");
1248 
1249   return true;
1250 }
1251 
1252 bool SBThread::GetDescription(SBStream &description) const {
1253   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1254                            description);
1255 
1256   return GetDescription(description, false);
1257 }
1258 
1259 bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1260   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1261                            (lldb::SBStream &, bool), description, stop_format);
1262 
1263   Stream &strm = description.ref();
1264 
1265   std::unique_lock<std::recursive_mutex> lock;
1266   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1267 
1268   if (exe_ctx.HasThreadScope()) {
1269     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
1270                                                     LLDB_INVALID_THREAD_ID,
1271                                                     stop_format);
1272     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1273     // exe_ctx.GetThreadPtr()->GetID());
1274   } else
1275     strm.PutCString("No value");
1276 
1277   return true;
1278 }
1279 
1280 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1281   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1282                      (const char *), type);
1283 
1284   std::unique_lock<std::recursive_mutex> lock;
1285   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1286   SBThread sb_origin_thread;
1287 
1288   Process::StopLocker stop_locker;
1289   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1290     if (exe_ctx.HasThreadScope()) {
1291       ThreadSP real_thread(exe_ctx.GetThreadSP());
1292       if (real_thread) {
1293         ConstString type_const(type);
1294         Process *process = exe_ctx.GetProcessPtr();
1295         if (process) {
1296           SystemRuntime *runtime = process->GetSystemRuntime();
1297           if (runtime) {
1298             ThreadSP new_thread_sp(
1299                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1300             if (new_thread_sp) {
1301               // Save this in the Process' ExtendedThreadList so a strong
1302               // pointer retains the object.
1303               process->GetExtendedThreadList().AddThread(new_thread_sp);
1304               sb_origin_thread.SetThread(new_thread_sp);
1305             }
1306           }
1307         }
1308       }
1309     }
1310   }
1311 
1312   return sb_origin_thread;
1313 }
1314 
1315 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1316   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1317                              GetExtendedBacktraceOriginatingIndexID);
1318 
1319   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1320   if (thread_sp)
1321     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1322   return LLDB_INVALID_INDEX32;
1323 }
1324 
1325 SBValue SBThread::GetCurrentException() {
1326   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1327 
1328   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1329   if (!thread_sp)
1330     return SBValue();
1331 
1332   return SBValue(thread_sp->GetCurrentException());
1333 }
1334 
1335 SBThread SBThread::GetCurrentExceptionBacktrace() {
1336   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1337                              GetCurrentExceptionBacktrace);
1338 
1339   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1340   if (!thread_sp)
1341     return SBThread();
1342 
1343   return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1344 }
1345 
1346 bool SBThread::SafeToCallFunctions() {
1347   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1348 
1349   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1350   if (thread_sp)
1351     return thread_sp->SafeToCallFunctions();
1352   return true;
1353 }
1354 
1355 lldb_private::Thread *SBThread::operator->() {
1356   return get();
1357 }
1358 
1359 lldb_private::Thread *SBThread::get() {
1360   return m_opaque_sp->GetThreadSP().get();
1361 }
1362