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