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/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
50using namespace lldb;
51using namespace lldb_private;
52
53const char *SBThread::GetBroadcasterClassName() {
54  LLDB_INSTRUMENT();
55
56  return Thread::GetStaticBroadcasterClass().AsCString();
57}
58
59// Constructors
60SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
61  LLDB_INSTRUMENT_VA(this);
62}
63
64SBThread::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
69SBThread::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
77const 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
86SBThread::~SBThread() = default;
87
88lldb::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
109bool SBThread::IsValid() const {
110  LLDB_INSTRUMENT_VA(this);
111  return this->operator bool();
112}
113SBThread::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
130void SBThread::Clear() {
131  LLDB_INSTRUMENT_VA(this);
132
133  m_opaque_sp->Clear();
134}
135
136StopReason 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
153size_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 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
210uint64_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->GetConstituentAtIndex(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
279bool 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
300SBThreadCollection
301SBThread::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
324size_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
352SBValue 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
372void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
373  m_opaque_sp->SetThreadSP(lldb_object_sp);
374}
375
376lldb::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
385uint32_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
394const char *SBThread::GetName() const {
395  LLDB_INSTRUMENT_VA(this);
396
397  std::unique_lock<std::recursive_mutex> lock;
398  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399
400  if (!exe_ctx.HasThreadScope())
401    return nullptr;
402
403  Process::StopLocker stop_locker;
404  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
405    return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString();
406
407  return nullptr;
408}
409
410const char *SBThread::GetQueueName() const {
411  LLDB_INSTRUMENT_VA(this);
412
413  std::unique_lock<std::recursive_mutex> lock;
414  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
415
416  if (!exe_ctx.HasThreadScope())
417    return nullptr;
418
419  Process::StopLocker stop_locker;
420  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
421    return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString();
422
423  return nullptr;
424}
425
426lldb::queue_id_t SBThread::GetQueueID() const {
427  LLDB_INSTRUMENT_VA(this);
428
429  queue_id_t id = LLDB_INVALID_QUEUE_ID;
430  std::unique_lock<std::recursive_mutex> lock;
431  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
432
433  if (exe_ctx.HasThreadScope()) {
434    Process::StopLocker stop_locker;
435    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
436      id = exe_ctx.GetThreadPtr()->GetQueueID();
437    }
438  }
439
440  return id;
441}
442
443bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
444  LLDB_INSTRUMENT_VA(this, path, strm);
445
446  bool success = false;
447  std::unique_lock<std::recursive_mutex> lock;
448  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
449
450  if (exe_ctx.HasThreadScope()) {
451    Process::StopLocker stop_locker;
452    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
453      Thread *thread = exe_ctx.GetThreadPtr();
454      StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
455      if (info_root_sp) {
456        StructuredData::ObjectSP node =
457            info_root_sp->GetObjectForDotSeparatedPath(path);
458        if (node) {
459          if (node->GetType() == eStructuredDataTypeString) {
460            strm.ref() << node->GetAsString()->GetValue();
461            success = true;
462          }
463          if (node->GetType() == eStructuredDataTypeInteger) {
464            strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue());
465            success = true;
466          }
467          if (node->GetType() == eStructuredDataTypeFloat) {
468            strm.Printf("0x%f", node->GetAsFloat()->GetValue());
469            success = true;
470          }
471          if (node->GetType() == eStructuredDataTypeBoolean) {
472            if (node->GetAsBoolean()->GetValue())
473              strm.Printf("true");
474            else
475              strm.Printf("false");
476            success = true;
477          }
478          if (node->GetType() == eStructuredDataTypeNull) {
479            strm.Printf("null");
480            success = true;
481          }
482        }
483      }
484    }
485  }
486
487  return success;
488}
489
490SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
491                                ThreadPlan *new_plan) {
492  SBError sb_error;
493
494  Process *process = exe_ctx.GetProcessPtr();
495  if (!process) {
496    sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
497    return sb_error;
498  }
499
500  Thread *thread = exe_ctx.GetThreadPtr();
501  if (!thread) {
502    sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
503    return sb_error;
504  }
505
506  // User level plans should be Controlling Plans so they can be interrupted,
507  // other plans executed, and then a "continue" will resume the plan.
508  if (new_plan != nullptr) {
509    new_plan->SetIsControllingPlan(true);
510    new_plan->SetOkayToDiscard(false);
511  }
512
513  // Why do we need to set the current thread by ID here???
514  process->GetThreadList().SetSelectedThreadByID(thread->GetID());
515
516  if (process->GetTarget().GetDebugger().GetAsyncExecution())
517    sb_error.ref() = process->Resume();
518  else
519    sb_error.ref() = process->ResumeSynchronous(nullptr);
520
521  return sb_error;
522}
523
524void SBThread::StepOver(lldb::RunMode stop_other_threads) {
525  LLDB_INSTRUMENT_VA(this, stop_other_threads);
526
527  SBError error; // Ignored
528  StepOver(stop_other_threads, error);
529}
530
531void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
532  LLDB_INSTRUMENT_VA(this, stop_other_threads, error);
533
534  std::unique_lock<std::recursive_mutex> lock;
535  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
536
537  if (!exe_ctx.HasThreadScope()) {
538    error.SetErrorString("this SBThread object is invalid");
539    return;
540  }
541
542  Thread *thread = exe_ctx.GetThreadPtr();
543  bool abort_other_plans = false;
544  StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
545
546  Status new_plan_status;
547  ThreadPlanSP new_plan_sp;
548  if (frame_sp) {
549    if (frame_sp->HasDebugInformation()) {
550      const LazyBool avoid_no_debug = eLazyBoolCalculate;
551      SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
552      new_plan_sp = thread->QueueThreadPlanForStepOverRange(
553          abort_other_plans, sc.line_entry, sc, stop_other_threads,
554          new_plan_status, avoid_no_debug);
555    } else {
556      new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
557          true, abort_other_plans, stop_other_threads, new_plan_status);
558    }
559  }
560  error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
561}
562
563void SBThread::StepInto(lldb::RunMode stop_other_threads) {
564  LLDB_INSTRUMENT_VA(this, stop_other_threads);
565
566  StepInto(nullptr, stop_other_threads);
567}
568
569void SBThread::StepInto(const char *target_name,
570                        lldb::RunMode stop_other_threads) {
571  LLDB_INSTRUMENT_VA(this, target_name, stop_other_threads);
572
573  SBError error; // Ignored
574  StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
575}
576
577void SBThread::StepInto(const char *target_name, uint32_t end_line,
578                        SBError &error, lldb::RunMode stop_other_threads) {
579  LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads);
580
581  std::unique_lock<std::recursive_mutex> lock;
582  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
583
584  if (!exe_ctx.HasThreadScope()) {
585    error.SetErrorString("this SBThread object is invalid");
586    return;
587  }
588
589  bool abort_other_plans = false;
590
591  Thread *thread = exe_ctx.GetThreadPtr();
592  StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
593  ThreadPlanSP new_plan_sp;
594  Status new_plan_status;
595
596  if (frame_sp && frame_sp->HasDebugInformation()) {
597    SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
598    AddressRange range;
599    if (end_line == LLDB_INVALID_LINE_NUMBER)
600      range = sc.line_entry.range;
601    else {
602      if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
603        return;
604    }
605
606    const LazyBool step_out_avoids_code_without_debug_info =
607        eLazyBoolCalculate;
608    const LazyBool step_in_avoids_code_without_debug_info =
609        eLazyBoolCalculate;
610    new_plan_sp = thread->QueueThreadPlanForStepInRange(
611        abort_other_plans, range, sc, target_name, stop_other_threads,
612        new_plan_status, step_in_avoids_code_without_debug_info,
613        step_out_avoids_code_without_debug_info);
614  } else {
615    new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
616        false, abort_other_plans, stop_other_threads, new_plan_status);
617  }
618
619  if (new_plan_status.Success())
620    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
621  else
622    error.SetErrorString(new_plan_status.AsCString());
623}
624
625void SBThread::StepOut() {
626  LLDB_INSTRUMENT_VA(this);
627
628  SBError error; // Ignored
629  StepOut(error);
630}
631
632void SBThread::StepOut(SBError &error) {
633  LLDB_INSTRUMENT_VA(this, error);
634
635  std::unique_lock<std::recursive_mutex> lock;
636  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
637
638  if (!exe_ctx.HasThreadScope()) {
639    error.SetErrorString("this SBThread object is invalid");
640    return;
641  }
642
643  bool abort_other_plans = false;
644  bool stop_other_threads = false;
645
646  Thread *thread = exe_ctx.GetThreadPtr();
647
648  const LazyBool avoid_no_debug = eLazyBoolCalculate;
649  Status new_plan_status;
650  ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
651      abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
652      eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
653
654  if (new_plan_status.Success())
655    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
656  else
657    error.SetErrorString(new_plan_status.AsCString());
658}
659
660void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
661  LLDB_INSTRUMENT_VA(this, sb_frame);
662
663  SBError error; // Ignored
664  StepOutOfFrame(sb_frame, error);
665}
666
667void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
668  LLDB_INSTRUMENT_VA(this, sb_frame, error);
669
670  std::unique_lock<std::recursive_mutex> lock;
671  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
672
673  if (!sb_frame.IsValid()) {
674    error.SetErrorString("passed invalid SBFrame object");
675    return;
676  }
677
678  StackFrameSP frame_sp(sb_frame.GetFrameSP());
679
680  if (!exe_ctx.HasThreadScope()) {
681    error.SetErrorString("this SBThread object is invalid");
682    return;
683  }
684
685  bool abort_other_plans = false;
686  bool stop_other_threads = false;
687  Thread *thread = exe_ctx.GetThreadPtr();
688  if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
689    error.SetErrorString("passed a frame from another thread");
690    return;
691  }
692
693  Status new_plan_status;
694  ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
695      abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
696      eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
697
698  if (new_plan_status.Success())
699    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
700  else
701    error.SetErrorString(new_plan_status.AsCString());
702}
703
704void SBThread::StepInstruction(bool step_over) {
705  LLDB_INSTRUMENT_VA(this, step_over);
706
707  SBError error; // Ignored
708  StepInstruction(step_over, error);
709}
710
711void SBThread::StepInstruction(bool step_over, SBError &error) {
712  LLDB_INSTRUMENT_VA(this, step_over, error);
713
714  std::unique_lock<std::recursive_mutex> lock;
715  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
716
717  if (!exe_ctx.HasThreadScope()) {
718    error.SetErrorString("this SBThread object is invalid");
719    return;
720  }
721
722  Thread *thread = exe_ctx.GetThreadPtr();
723  Status new_plan_status;
724  ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
725      step_over, true, true, new_plan_status));
726
727  if (new_plan_status.Success())
728    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
729  else
730    error.SetErrorString(new_plan_status.AsCString());
731}
732
733void SBThread::RunToAddress(lldb::addr_t addr) {
734  LLDB_INSTRUMENT_VA(this, addr);
735
736  SBError error; // Ignored
737  RunToAddress(addr, error);
738}
739
740void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
741  LLDB_INSTRUMENT_VA(this, addr, error);
742
743  std::unique_lock<std::recursive_mutex> lock;
744  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
745
746  if (!exe_ctx.HasThreadScope()) {
747    error.SetErrorString("this SBThread object is invalid");
748    return;
749  }
750
751  bool abort_other_plans = false;
752  bool stop_other_threads = true;
753
754  Address target_addr(addr);
755
756  Thread *thread = exe_ctx.GetThreadPtr();
757
758  Status new_plan_status;
759  ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
760      abort_other_plans, target_addr, stop_other_threads, new_plan_status));
761
762  if (new_plan_status.Success())
763    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
764  else
765    error.SetErrorString(new_plan_status.AsCString());
766}
767
768SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
769                                lldb::SBFileSpec &sb_file_spec, uint32_t line) {
770  LLDB_INSTRUMENT_VA(this, sb_frame, sb_file_spec, line);
771
772  SBError sb_error;
773  char path[PATH_MAX];
774
775  std::unique_lock<std::recursive_mutex> lock;
776  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
777
778  StackFrameSP frame_sp(sb_frame.GetFrameSP());
779
780  if (exe_ctx.HasThreadScope()) {
781    Target *target = exe_ctx.GetTargetPtr();
782    Thread *thread = exe_ctx.GetThreadPtr();
783
784    if (line == 0) {
785      sb_error.SetErrorString("invalid line argument");
786      return sb_error;
787    }
788
789    if (!frame_sp) {
790      // We don't want to run SelectMostRelevantFrame here, for instance if
791      // you called a sequence of StepOverUntil's you wouldn't want the
792      // frame changed out from under you because you stepped into a
793      // recognized frame.
794      frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
795      if (!frame_sp)
796        frame_sp = thread->GetStackFrameAtIndex(0);
797    }
798
799    SymbolContext frame_sc;
800    if (!frame_sp) {
801      sb_error.SetErrorString("no valid frames in thread to step");
802      return sb_error;
803    }
804
805    // If we have a frame, get its line
806    frame_sc = frame_sp->GetSymbolContext(
807        eSymbolContextCompUnit | eSymbolContextFunction |
808        eSymbolContextLineEntry | eSymbolContextSymbol);
809
810    if (frame_sc.comp_unit == nullptr) {
811      sb_error.SetErrorStringWithFormat(
812          "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
813      return sb_error;
814    }
815
816    FileSpec step_file_spec;
817    if (sb_file_spec.IsValid()) {
818      // The file spec passed in was valid, so use it
819      step_file_spec = sb_file_spec.ref();
820    } else {
821      if (frame_sc.line_entry.IsValid())
822        step_file_spec = frame_sc.line_entry.file;
823      else {
824        sb_error.SetErrorString("invalid file argument or no file for frame");
825        return sb_error;
826      }
827    }
828
829    // Grab the current function, then we will make sure the "until" address is
830    // within the function.  We discard addresses that are out of the current
831    // function, and then if there are no addresses remaining, give an
832    // appropriate error message.
833
834    bool all_in_function = true;
835    AddressRange fun_range = frame_sc.function->GetAddressRange();
836
837    std::vector<addr_t> step_over_until_addrs;
838    const bool abort_other_plans = false;
839    const bool stop_other_threads = false;
840    // TODO: Handle SourceLocationSpec column information
841    SourceLocationSpec location_spec(
842        step_file_spec, line, /*column=*/std::nullopt, /*check_inlines=*/true,
843        /*exact_match=*/false);
844
845    SymbolContextList sc_list;
846    frame_sc.comp_unit->ResolveSymbolContext(location_spec,
847                                             eSymbolContextLineEntry, sc_list);
848    for (const SymbolContext &sc : sc_list) {
849      addr_t step_addr =
850          sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
851      if (step_addr != LLDB_INVALID_ADDRESS) {
852        if (fun_range.ContainsLoadAddress(step_addr, target))
853          step_over_until_addrs.push_back(step_addr);
854        else
855          all_in_function = false;
856      }
857    }
858
859    if (step_over_until_addrs.empty()) {
860      if (all_in_function) {
861        step_file_spec.GetPath(path, sizeof(path));
862        sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
863                                          line);
864      } else
865        sb_error.SetErrorString("step until target not in current function");
866    } else {
867      Status new_plan_status;
868      ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
869          abort_other_plans, &step_over_until_addrs[0],
870          step_over_until_addrs.size(), stop_other_threads,
871          frame_sp->GetFrameIndex(), new_plan_status));
872
873      if (new_plan_status.Success())
874        sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
875      else
876        sb_error.SetErrorString(new_plan_status.AsCString());
877    }
878  } else {
879    sb_error.SetErrorString("this SBThread object is invalid");
880  }
881  return sb_error;
882}
883
884SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
885  LLDB_INSTRUMENT_VA(this, script_class_name);
886
887  return StepUsingScriptedThreadPlan(script_class_name, true);
888}
889
890SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
891                                            bool resume_immediately) {
892  LLDB_INSTRUMENT_VA(this, script_class_name, resume_immediately);
893
894  lldb::SBStructuredData no_data;
895  return StepUsingScriptedThreadPlan(script_class_name, no_data,
896                                     resume_immediately);
897}
898
899SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
900                                              SBStructuredData &args_data,
901                                              bool resume_immediately) {
902  LLDB_INSTRUMENT_VA(this, script_class_name, args_data, resume_immediately);
903
904  SBError error;
905
906  std::unique_lock<std::recursive_mutex> lock;
907  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
908
909  if (!exe_ctx.HasThreadScope()) {
910    error.SetErrorString("this SBThread object is invalid");
911    return error;
912  }
913
914  Thread *thread = exe_ctx.GetThreadPtr();
915  Status new_plan_status;
916  StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
917
918  ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
919      false, script_class_name, obj_sp, false, new_plan_status);
920
921  if (new_plan_status.Fail()) {
922    error.SetErrorString(new_plan_status.AsCString());
923    return error;
924  }
925
926  if (!resume_immediately)
927    return error;
928
929  if (new_plan_status.Success())
930    error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
931  else
932    error.SetErrorString(new_plan_status.AsCString());
933
934  return error;
935}
936
937SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
938  LLDB_INSTRUMENT_VA(this, file_spec, line);
939
940  SBError sb_error;
941
942  std::unique_lock<std::recursive_mutex> lock;
943  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
944
945  if (!exe_ctx.HasThreadScope()) {
946    sb_error.SetErrorString("this SBThread object is invalid");
947    return sb_error;
948  }
949
950  Thread *thread = exe_ctx.GetThreadPtr();
951
952  Status err = thread->JumpToLine(file_spec.ref(), line, true);
953  sb_error.SetError(err);
954  return sb_error;
955}
956
957SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
958  LLDB_INSTRUMENT_VA(this, frame, return_value);
959
960  SBError sb_error;
961
962  std::unique_lock<std::recursive_mutex> lock;
963  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
964
965  if (exe_ctx.HasThreadScope()) {
966    Thread *thread = exe_ctx.GetThreadPtr();
967    sb_error.SetError(
968        thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
969  }
970
971  return sb_error;
972}
973
974SBError SBThread::UnwindInnermostExpression() {
975  LLDB_INSTRUMENT_VA(this);
976
977  SBError sb_error;
978
979  std::unique_lock<std::recursive_mutex> lock;
980  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
981
982  if (exe_ctx.HasThreadScope()) {
983    Thread *thread = exe_ctx.GetThreadPtr();
984    sb_error.SetError(thread->UnwindInnermostExpression());
985    if (sb_error.Success())
986      thread->SetSelectedFrameByIndex(0, false);
987  }
988
989  return sb_error;
990}
991
992bool SBThread::Suspend() {
993  LLDB_INSTRUMENT_VA(this);
994
995  SBError error; // Ignored
996  return Suspend(error);
997}
998
999bool SBThread::Suspend(SBError &error) {
1000  LLDB_INSTRUMENT_VA(this, error);
1001
1002  std::unique_lock<std::recursive_mutex> lock;
1003  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1004
1005  bool result = false;
1006  if (exe_ctx.HasThreadScope()) {
1007    Process::StopLocker stop_locker;
1008    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1009      exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1010      result = true;
1011    } else {
1012      error.SetErrorString("process is running");
1013    }
1014  } else
1015    error.SetErrorString("this SBThread object is invalid");
1016  return result;
1017}
1018
1019bool SBThread::Resume() {
1020  LLDB_INSTRUMENT_VA(this);
1021
1022  SBError error; // Ignored
1023  return Resume(error);
1024}
1025
1026bool SBThread::Resume(SBError &error) {
1027  LLDB_INSTRUMENT_VA(this, error);
1028
1029  std::unique_lock<std::recursive_mutex> lock;
1030  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1031
1032  bool result = false;
1033  if (exe_ctx.HasThreadScope()) {
1034    Process::StopLocker stop_locker;
1035    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1036      const bool override_suspend = true;
1037      exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1038      result = true;
1039    } else {
1040      error.SetErrorString("process is running");
1041    }
1042  } else
1043    error.SetErrorString("this SBThread object is invalid");
1044  return result;
1045}
1046
1047bool SBThread::IsSuspended() {
1048  LLDB_INSTRUMENT_VA(this);
1049
1050  std::unique_lock<std::recursive_mutex> lock;
1051  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1052
1053  if (exe_ctx.HasThreadScope())
1054    return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1055  return false;
1056}
1057
1058bool SBThread::IsStopped() {
1059  LLDB_INSTRUMENT_VA(this);
1060
1061  std::unique_lock<std::recursive_mutex> lock;
1062  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1063
1064  if (exe_ctx.HasThreadScope())
1065    return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1066  return false;
1067}
1068
1069SBProcess SBThread::GetProcess() {
1070  LLDB_INSTRUMENT_VA(this);
1071
1072  SBProcess sb_process;
1073  std::unique_lock<std::recursive_mutex> lock;
1074  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1075
1076  if (exe_ctx.HasThreadScope()) {
1077    // Have to go up to the target so we can get a shared pointer to our
1078    // process...
1079    sb_process.SetSP(exe_ctx.GetProcessSP());
1080  }
1081
1082  return sb_process;
1083}
1084
1085uint32_t SBThread::GetNumFrames() {
1086  LLDB_INSTRUMENT_VA(this);
1087
1088  uint32_t num_frames = 0;
1089  std::unique_lock<std::recursive_mutex> lock;
1090  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1091
1092  if (exe_ctx.HasThreadScope()) {
1093    Process::StopLocker stop_locker;
1094    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1095      num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1096    }
1097  }
1098
1099  return num_frames;
1100}
1101
1102SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1103  LLDB_INSTRUMENT_VA(this, idx);
1104
1105  SBFrame sb_frame;
1106  StackFrameSP frame_sp;
1107  std::unique_lock<std::recursive_mutex> lock;
1108  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1109
1110  if (exe_ctx.HasThreadScope()) {
1111    Process::StopLocker stop_locker;
1112    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1113      frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1114      sb_frame.SetFrameSP(frame_sp);
1115    }
1116  }
1117
1118  return sb_frame;
1119}
1120
1121lldb::SBFrame SBThread::GetSelectedFrame() {
1122  LLDB_INSTRUMENT_VA(this);
1123
1124  SBFrame sb_frame;
1125  StackFrameSP frame_sp;
1126  std::unique_lock<std::recursive_mutex> lock;
1127  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1128
1129  if (exe_ctx.HasThreadScope()) {
1130    Process::StopLocker stop_locker;
1131    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1132      frame_sp =
1133          exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame);
1134      sb_frame.SetFrameSP(frame_sp);
1135    }
1136  }
1137
1138  return sb_frame;
1139}
1140
1141lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1142  LLDB_INSTRUMENT_VA(this, idx);
1143
1144  SBFrame sb_frame;
1145  StackFrameSP frame_sp;
1146  std::unique_lock<std::recursive_mutex> lock;
1147  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1148
1149  if (exe_ctx.HasThreadScope()) {
1150    Process::StopLocker stop_locker;
1151    if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1152      Thread *thread = exe_ctx.GetThreadPtr();
1153      frame_sp = thread->GetStackFrameAtIndex(idx);
1154      if (frame_sp) {
1155        thread->SetSelectedFrame(frame_sp.get());
1156        sb_frame.SetFrameSP(frame_sp);
1157      }
1158    }
1159  }
1160
1161  return sb_frame;
1162}
1163
1164bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1165  LLDB_INSTRUMENT_VA(event);
1166
1167  return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1168}
1169
1170SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1171  LLDB_INSTRUMENT_VA(event);
1172
1173  return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1174}
1175
1176SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1177  LLDB_INSTRUMENT_VA(event);
1178
1179  return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1180}
1181
1182bool SBThread::operator==(const SBThread &rhs) const {
1183  LLDB_INSTRUMENT_VA(this, rhs);
1184
1185  return m_opaque_sp->GetThreadSP().get() ==
1186         rhs.m_opaque_sp->GetThreadSP().get();
1187}
1188
1189bool SBThread::operator!=(const SBThread &rhs) const {
1190  LLDB_INSTRUMENT_VA(this, rhs);
1191
1192  return m_opaque_sp->GetThreadSP().get() !=
1193         rhs.m_opaque_sp->GetThreadSP().get();
1194}
1195
1196bool SBThread::GetStatus(SBStream &status) const {
1197  LLDB_INSTRUMENT_VA(this, status);
1198
1199  Stream &strm = status.ref();
1200
1201  std::unique_lock<std::recursive_mutex> lock;
1202  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1203
1204  if (exe_ctx.HasThreadScope()) {
1205    exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1206  } else
1207    strm.PutCString("No status");
1208
1209  return true;
1210}
1211
1212bool SBThread::GetDescription(SBStream &description) const {
1213  LLDB_INSTRUMENT_VA(this, description);
1214
1215  return GetDescription(description, false);
1216}
1217
1218bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1219  LLDB_INSTRUMENT_VA(this, description, stop_format);
1220
1221  Stream &strm = description.ref();
1222
1223  std::unique_lock<std::recursive_mutex> lock;
1224  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1225
1226  if (exe_ctx.HasThreadScope()) {
1227    exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(
1228        strm, LLDB_INVALID_THREAD_ID, stop_format);
1229  } else
1230    strm.PutCString("No value");
1231
1232  return true;
1233}
1234
1235SBError SBThread::GetDescriptionWithFormat(const SBFormat &format,
1236                                           SBStream &output) {
1237  Stream &strm = output.ref();
1238
1239  SBError error;
1240  if (!format) {
1241    error.SetErrorString("The provided SBFormat object is invalid");
1242    return error;
1243  }
1244
1245  std::unique_lock<std::recursive_mutex> lock;
1246  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1247
1248  if (exe_ctx.HasThreadScope()) {
1249    if (exe_ctx.GetThreadPtr()->DumpUsingFormat(
1250            strm, LLDB_INVALID_THREAD_ID, format.GetFormatEntrySP().get())) {
1251      return error;
1252    }
1253  }
1254
1255  error.SetErrorStringWithFormat(
1256      "It was not possible to generate a thread description with the given "
1257      "format string '%s'",
1258      format.GetFormatEntrySP()->string.c_str());
1259  return error;
1260}
1261
1262SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1263  LLDB_INSTRUMENT_VA(this, type);
1264
1265  std::unique_lock<std::recursive_mutex> lock;
1266  ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1267  SBThread sb_origin_thread;
1268
1269  Process::StopLocker stop_locker;
1270  if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1271    if (exe_ctx.HasThreadScope()) {
1272      ThreadSP real_thread(exe_ctx.GetThreadSP());
1273      if (real_thread) {
1274        ConstString type_const(type);
1275        Process *process = exe_ctx.GetProcessPtr();
1276        if (process) {
1277          SystemRuntime *runtime = process->GetSystemRuntime();
1278          if (runtime) {
1279            ThreadSP new_thread_sp(
1280                runtime->GetExtendedBacktraceThread(real_thread, type_const));
1281            if (new_thread_sp) {
1282              // Save this in the Process' ExtendedThreadList so a strong
1283              // pointer retains the object.
1284              process->GetExtendedThreadList().AddThread(new_thread_sp);
1285              sb_origin_thread.SetThread(new_thread_sp);
1286            }
1287          }
1288        }
1289      }
1290    }
1291  }
1292
1293  return sb_origin_thread;
1294}
1295
1296uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1297  LLDB_INSTRUMENT_VA(this);
1298
1299  ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1300  if (thread_sp)
1301    return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1302  return LLDB_INVALID_INDEX32;
1303}
1304
1305SBValue SBThread::GetCurrentException() {
1306  LLDB_INSTRUMENT_VA(this);
1307
1308  ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1309  if (!thread_sp)
1310    return SBValue();
1311
1312  return SBValue(thread_sp->GetCurrentException());
1313}
1314
1315SBThread SBThread::GetCurrentExceptionBacktrace() {
1316  LLDB_INSTRUMENT_VA(this);
1317
1318  ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1319  if (!thread_sp)
1320    return SBThread();
1321
1322  return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1323}
1324
1325bool SBThread::SafeToCallFunctions() {
1326  LLDB_INSTRUMENT_VA(this);
1327
1328  ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1329  if (thread_sp)
1330    return thread_sp->SafeToCallFunctions();
1331  return true;
1332}
1333
1334lldb_private::Thread *SBThread::operator->() {
1335  return get();
1336}
1337
1338lldb_private::Thread *SBThread::get() {
1339  return m_opaque_sp->GetThreadSP().get();
1340}
1341
1342SBValue SBThread::GetSiginfo() {
1343  LLDB_INSTRUMENT_VA(this);
1344
1345  ThreadSP thread_sp = m_opaque_sp->GetThreadSP();
1346  if (!thread_sp)
1347    return SBValue();
1348  return thread_sp->GetSiginfoValue();
1349}
1350