xref: /freebsd/contrib/llvm-project/lldb/source/API/SBThread.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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 
50 using namespace lldb;
51 using namespace lldb_private;
52 
GetBroadcasterClassName()53 const char *SBThread::GetBroadcasterClassName() {
54   LLDB_INSTRUMENT();
55 
56   return ConstString(Thread::GetStaticBroadcasterClass()).AsCString();
57 }
58 
59 // Constructors
SBThread()60 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
61   LLDB_INSTRUMENT_VA(this);
62 }
63 
SBThread(const ThreadSP & lldb_object_sp)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 
SBThread(const SBThread & rhs)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 
operator =(const SBThread & rhs)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 
GetQueue() const88 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 
IsValid() const109 bool SBThread::IsValid() const {
110   LLDB_INSTRUMENT_VA(this);
111   return this->operator bool();
112 }
operator bool() const113 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 
Clear()130 void SBThread::Clear() {
131   LLDB_INSTRUMENT_VA(this);
132 
133   m_opaque_sp->Clear();
134 }
135 
GetStopReason()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 
GetStopReasonDataCount()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 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 
GetStopReasonDataAtIndex(uint32_t idx)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->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 
GetStopReasonExtendedInfoAsJSON(lldb::SBStream & stream)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
GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type)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 
GetStopDescription(char * dst,size_t dst_len)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 
GetStopReturnValue()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 
SetThread(const ThreadSP & lldb_object_sp)372 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
373   m_opaque_sp->SetThreadSP(lldb_object_sp);
374 }
375 
GetThreadID() const376 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 
GetIndexID() const385 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 
GetName() const394 const 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 
GetQueueName() const410 const 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 
GetQueueID() const426 lldb::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 
GetInfoItemByPathAsString(const char * path,SBStream & strm)443 bool 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 
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)490 SBError 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 
StepOver(lldb::RunMode stop_other_threads)524 void 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 
StepOver(lldb::RunMode stop_other_threads,SBError & error)531 void 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 
StepInto(lldb::RunMode stop_other_threads)563 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
564   LLDB_INSTRUMENT_VA(this, stop_other_threads);
565 
566   StepInto(nullptr, stop_other_threads);
567 }
568 
StepInto(const char * target_name,lldb::RunMode stop_other_threads)569 void 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 
StepInto(const char * target_name,uint32_t end_line,SBError & error,lldb::RunMode stop_other_threads)577 void 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 
StepOut()625 void SBThread::StepOut() {
626   LLDB_INSTRUMENT_VA(this);
627 
628   SBError error; // Ignored
629   StepOut(error);
630 }
631 
StepOut(SBError & error)632 void 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 
StepOutOfFrame(SBFrame & sb_frame)660 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
661   LLDB_INSTRUMENT_VA(this, sb_frame);
662 
663   SBError error; // Ignored
664   StepOutOfFrame(sb_frame, error);
665 }
666 
StepOutOfFrame(SBFrame & sb_frame,SBError & error)667 void 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 
StepInstruction(bool step_over)704 void SBThread::StepInstruction(bool step_over) {
705   LLDB_INSTRUMENT_VA(this, step_over);
706 
707   SBError error; // Ignored
708   StepInstruction(step_over, error);
709 }
710 
StepInstruction(bool step_over,SBError & error)711 void 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, false, 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 
RunToAddress(lldb::addr_t addr)733 void SBThread::RunToAddress(lldb::addr_t addr) {
734   LLDB_INSTRUMENT_VA(this, addr);
735 
736   SBError error; // Ignored
737   RunToAddress(addr, error);
738 }
739 
RunToAddress(lldb::addr_t addr,SBError & error)740 void 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 
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)768 SBError 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.GetFile();
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 
StepUsingScriptedThreadPlan(const char * script_class_name)884 SBError 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 
StepUsingScriptedThreadPlan(const char * script_class_name,bool resume_immediately)890 SBError 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 
StepUsingScriptedThreadPlan(const char * script_class_name,SBStructuredData & args_data,bool resume_immediately)899 SBError 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 
JumpToLine(lldb::SBFileSpec & file_spec,uint32_t line)937 SBError 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 
ReturnFromFrame(SBFrame & frame,SBValue & return_value)957 SBError 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 
UnwindInnermostExpression()974 SBError 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 
Suspend()992 bool SBThread::Suspend() {
993   LLDB_INSTRUMENT_VA(this);
994 
995   SBError error; // Ignored
996   return Suspend(error);
997 }
998 
Suspend(SBError & error)999 bool 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 
Resume()1019 bool SBThread::Resume() {
1020   LLDB_INSTRUMENT_VA(this);
1021 
1022   SBError error; // Ignored
1023   return Resume(error);
1024 }
1025 
Resume(SBError & error)1026 bool 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 
IsSuspended()1047 bool 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 
IsStopped()1058 bool 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 
GetProcess()1069 SBProcess 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 
GetNumFrames()1085 uint32_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 
GetFrameAtIndex(uint32_t idx)1102 SBFrame 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 
GetSelectedFrame()1121 lldb::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 
SetSelectedFrame(uint32_t idx)1141 lldb::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 
EventIsThreadEvent(const SBEvent & event)1164 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1165   LLDB_INSTRUMENT_VA(event);
1166 
1167   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1168 }
1169 
GetStackFrameFromEvent(const SBEvent & event)1170 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1171   LLDB_INSTRUMENT_VA(event);
1172 
1173   return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1174 }
1175 
GetThreadFromEvent(const SBEvent & event)1176 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1177   LLDB_INSTRUMENT_VA(event);
1178 
1179   return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1180 }
1181 
operator ==(const SBThread & rhs) const1182 bool 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 
operator !=(const SBThread & rhs) const1189 bool 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 
GetStatus(SBStream & status) const1196 bool 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 
GetDescription(SBStream & description) const1212 bool SBThread::GetDescription(SBStream &description) const {
1213   LLDB_INSTRUMENT_VA(this, description);
1214 
1215   return GetDescription(description, false);
1216 }
1217 
GetDescription(SBStream & description,bool stop_format) const1218 bool 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 
GetDescriptionWithFormat(const SBFormat & format,SBStream & output)1235 SBError 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 
GetExtendedBacktraceThread(const char * type)1262 SBThread 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 
GetExtendedBacktraceOriginatingIndexID()1296 uint32_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 
GetCurrentException()1305 SBValue 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 
GetCurrentExceptionBacktrace()1315 SBThread 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 
SafeToCallFunctions()1325 bool 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 
operator ->()1334 lldb_private::Thread *SBThread::operator->() {
1335   return get();
1336 }
1337 
get()1338 lldb_private::Thread *SBThread::get() {
1339   return m_opaque_sp->GetThreadSP().get();
1340 }
1341 
GetSiginfo()1342 SBValue 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