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