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