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 "SBReproducerPrivate.h"
11 #include "Utils.h"
12 #include "lldb/API/SBAddress.h"
13 #include "lldb/API/SBDebugger.h"
14 #include "lldb/API/SBEvent.h"
15 #include "lldb/API/SBFileSpec.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/StreamFile.h"
27 #include "lldb/Core/StructuredDataImpl.h"
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Interpreter/CommandInterpreter.h"
30 #include "lldb/Symbol/CompileUnit.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/Queue.h"
34 #include "lldb/Target/StopInfo.h"
35 #include "lldb/Target/SystemRuntime.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Target/ThreadPlan.h"
39 #include "lldb/Target/ThreadPlanStepInRange.h"
40 #include "lldb/Target/ThreadPlanStepInstruction.h"
41 #include "lldb/Target/ThreadPlanStepOut.h"
42 #include "lldb/Target/ThreadPlanStepRange.h"
43 #include "lldb/Target/UnixSignals.h"
44 #include "lldb/Utility/State.h"
45 #include "lldb/Utility/Stream.h"
46 #include "lldb/Utility/StructuredData.h"
47 #include "lldb/lldb-enumerations.h"
48 
49 #include <memory>
50 
51 using namespace lldb;
52 using namespace lldb_private;
53 
54 const char *SBThread::GetBroadcasterClassName() {
55   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread,
56                                     GetBroadcasterClassName);
57 
58   return Thread::GetStaticBroadcasterClass().AsCString();
59 }
60 
61 // Constructors
62 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {
63   LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread);
64 }
65 
66 SBThread::SBThread(const ThreadSP &lldb_object_sp)
67     : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
68   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp);
69 }
70 
71 SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() {
72   LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs);
73 
74   m_opaque_sp = clone(rhs.m_opaque_sp);
75 }
76 
77 // Assignment operator
78 
79 const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
80   LLDB_RECORD_METHOD(const lldb::SBThread &,
81                      SBThread, operator=,(const lldb::SBThread &), rhs);
82 
83   if (this != &rhs)
84     m_opaque_sp = clone(rhs.m_opaque_sp);
85   return LLDB_RECORD_RESULT(*this);
86 }
87 
88 // Destructor
89 SBThread::~SBThread() {}
90 
91 lldb::SBQueue SBThread::GetQueue() const {
92   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue);
93 
94   SBQueue sb_queue;
95   QueueSP queue_sp;
96   std::unique_lock<std::recursive_mutex> lock;
97   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
98 
99   if (exe_ctx.HasThreadScope()) {
100     Process::StopLocker stop_locker;
101     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
102       queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
103       if (queue_sp) {
104         sb_queue.SetQueue(queue_sp);
105       }
106     }
107   }
108 
109   return LLDB_RECORD_RESULT(sb_queue);
110 }
111 
112 bool SBThread::IsValid() const {
113   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid);
114   return this->operator bool();
115 }
116 SBThread::operator bool() const {
117   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool);
118 
119   std::unique_lock<std::recursive_mutex> lock;
120   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
121 
122   Target *target = exe_ctx.GetTargetPtr();
123   Process *process = exe_ctx.GetProcessPtr();
124   if (target && process) {
125     Process::StopLocker stop_locker;
126     if (stop_locker.TryLock(&process->GetRunLock()))
127       return m_opaque_sp->GetThreadSP().get() != nullptr;
128   }
129   // Without a valid target & process, this thread can't be valid.
130   return false;
131 }
132 
133 void SBThread::Clear() {
134   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear);
135 
136   m_opaque_sp->Clear();
137 }
138 
139 StopReason SBThread::GetStopReason() {
140   LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason);
141 
142   StopReason reason = eStopReasonInvalid;
143   std::unique_lock<std::recursive_mutex> lock;
144   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
145 
146   if (exe_ctx.HasThreadScope()) {
147     Process::StopLocker stop_locker;
148     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
149       return exe_ctx.GetThreadPtr()->GetStopReason();
150     }
151   }
152 
153   return reason;
154 }
155 
156 size_t SBThread::GetStopReasonDataCount() {
157   LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount);
158 
159   std::unique_lock<std::recursive_mutex> lock;
160   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
161 
162   if (exe_ctx.HasThreadScope()) {
163     Process::StopLocker stop_locker;
164     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
165       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
166       if (stop_info_sp) {
167         StopReason reason = stop_info_sp->GetStopReason();
168         switch (reason) {
169         case eStopReasonInvalid:
170         case eStopReasonNone:
171         case eStopReasonTrace:
172         case eStopReasonExec:
173         case eStopReasonPlanComplete:
174         case eStopReasonThreadExiting:
175         case eStopReasonInstrumentation:
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->GetNumberOfOwners() * 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 eStopReasonException:
197           return 1;
198         }
199       }
200     }
201   }
202   return 0;
203 }
204 
205 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
206   LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t),
207                      idx);
208 
209   std::unique_lock<std::recursive_mutex> lock;
210   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
211 
212   if (exe_ctx.HasThreadScope()) {
213     Process::StopLocker stop_locker;
214     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
215       Thread *thread = exe_ctx.GetThreadPtr();
216       StopInfoSP stop_info_sp = thread->GetStopInfo();
217       if (stop_info_sp) {
218         StopReason reason = stop_info_sp->GetStopReason();
219         switch (reason) {
220         case eStopReasonInvalid:
221         case eStopReasonNone:
222         case eStopReasonTrace:
223         case eStopReasonExec:
224         case eStopReasonPlanComplete:
225         case eStopReasonThreadExiting:
226         case eStopReasonInstrumentation:
227           // There is no data for these stop reasons.
228           return 0;
229 
230         case eStopReasonBreakpoint: {
231           break_id_t site_id = stop_info_sp->GetValue();
232           lldb::BreakpointSiteSP bp_site_sp(
233               exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
234                   site_id));
235           if (bp_site_sp) {
236             uint32_t bp_index = idx / 2;
237             BreakpointLocationSP bp_loc_sp(
238                 bp_site_sp->GetOwnerAtIndex(bp_index));
239             if (bp_loc_sp) {
240               if (idx & 1) {
241                 // Odd idx, return the breakpoint location ID
242                 return bp_loc_sp->GetID();
243               } else {
244                 // Even idx, return the breakpoint ID
245                 return bp_loc_sp->GetBreakpoint().GetID();
246               }
247             }
248           }
249           return LLDB_INVALID_BREAK_ID;
250         } break;
251 
252         case eStopReasonWatchpoint:
253           return stop_info_sp->GetValue();
254 
255         case eStopReasonSignal:
256           return stop_info_sp->GetValue();
257 
258         case eStopReasonException:
259           return stop_info_sp->GetValue();
260         }
261       }
262     }
263   }
264   return 0;
265 }
266 
267 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
268   LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
269                      (lldb::SBStream &), stream);
270 
271   Stream &strm = stream.ref();
272 
273   std::unique_lock<std::recursive_mutex> lock;
274   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
275 
276   if (!exe_ctx.HasThreadScope())
277     return false;
278 
279   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
280   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
281   if (!info)
282     return false;
283 
284   info->Dump(strm);
285 
286   return true;
287 }
288 
289 SBThreadCollection
290 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
291   LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread,
292                      GetStopReasonExtendedBacktraces,
293                      (lldb::InstrumentationRuntimeType), type);
294 
295   ThreadCollectionSP threads;
296   threads = std::make_shared<ThreadCollection>();
297 
298   std::unique_lock<std::recursive_mutex> lock;
299   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
300 
301   if (!exe_ctx.HasThreadScope())
302     return LLDB_RECORD_RESULT(threads);
303 
304   ProcessSP process_sp = exe_ctx.GetProcessSP();
305 
306   StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
307   StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
308   if (!info)
309     return LLDB_RECORD_RESULT(threads);
310 
311   return LLDB_RECORD_RESULT(process_sp->GetInstrumentationRuntime(type)
312                                 ->GetBacktracesFromExtendedStopInfo(info));
313 }
314 
315 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
316   LLDB_RECORD_METHOD(size_t, SBThread, GetStopDescription, (char *, size_t), "",
317                      dst_len);
318 
319   std::unique_lock<std::recursive_mutex> lock;
320   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
321 
322   if (exe_ctx.HasThreadScope()) {
323     Process::StopLocker stop_locker;
324     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
325 
326       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
327       if (stop_info_sp) {
328         std::string thread_stop_desc =
329             exe_ctx.GetThreadPtr()->GetStopDescription();
330         const char *stop_desc = thread_stop_desc.c_str();
331 
332         if (stop_desc[0] != '\0') {
333           if (dst)
334             return ::snprintf(dst, dst_len, "%s", stop_desc);
335           else {
336             // NULL dst passed in, return the length needed to contain the
337             // description
338             return ::strlen(stop_desc) + 1; // Include the NULL byte for size
339           }
340         } else {
341           size_t stop_desc_len = 0;
342           switch (stop_info_sp->GetStopReason()) {
343           case eStopReasonTrace:
344           case eStopReasonPlanComplete: {
345             static char trace_desc[] = "step";
346             stop_desc = trace_desc;
347             stop_desc_len =
348                 sizeof(trace_desc); // Include the NULL byte for size
349           } break;
350 
351           case eStopReasonBreakpoint: {
352             static char bp_desc[] = "breakpoint hit";
353             stop_desc = bp_desc;
354             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
355           } break;
356 
357           case eStopReasonWatchpoint: {
358             static char wp_desc[] = "watchpoint hit";
359             stop_desc = wp_desc;
360             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
361           } break;
362 
363           case eStopReasonSignal: {
364             stop_desc =
365                 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
366                     stop_info_sp->GetValue());
367             if (stop_desc == nullptr || stop_desc[0] == '\0') {
368               static char signal_desc[] = "signal";
369               stop_desc = signal_desc;
370               stop_desc_len =
371                   sizeof(signal_desc); // Include the NULL byte for size
372             }
373           } break;
374 
375           case eStopReasonException: {
376             char exc_desc[] = "exception";
377             stop_desc = exc_desc;
378             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
379           } break;
380 
381           case eStopReasonExec: {
382             char exc_desc[] = "exec";
383             stop_desc = exc_desc;
384             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
385           } break;
386 
387           case eStopReasonThreadExiting: {
388             char limbo_desc[] = "thread exiting";
389             stop_desc = limbo_desc;
390             stop_desc_len = sizeof(limbo_desc);
391           } break;
392           default:
393             break;
394           }
395 
396           if (stop_desc && stop_desc[0]) {
397             if (dst)
398               return ::snprintf(dst, dst_len, "%s", stop_desc) +
399                      1; // Include the NULL byte
400 
401             if (stop_desc_len == 0)
402               stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
403 
404             return stop_desc_len;
405           }
406         }
407       }
408     }
409   }
410   if (dst)
411     *dst = 0;
412   return 0;
413 }
414 
415 SBValue SBThread::GetStopReturnValue() {
416   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue);
417 
418   ValueObjectSP return_valobj_sp;
419   std::unique_lock<std::recursive_mutex> lock;
420   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
421 
422   if (exe_ctx.HasThreadScope()) {
423     Process::StopLocker stop_locker;
424     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
425       StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
426       if (stop_info_sp) {
427         return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
428       }
429     }
430   }
431 
432   return LLDB_RECORD_RESULT(SBValue(return_valobj_sp));
433 }
434 
435 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
436   m_opaque_sp->SetThreadSP(lldb_object_sp);
437 }
438 
439 lldb::tid_t SBThread::GetThreadID() const {
440   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID);
441 
442   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
443   if (thread_sp)
444     return thread_sp->GetID();
445   return LLDB_INVALID_THREAD_ID;
446 }
447 
448 uint32_t SBThread::GetIndexID() const {
449   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID);
450 
451   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
452   if (thread_sp)
453     return thread_sp->GetIndexID();
454   return LLDB_INVALID_INDEX32;
455 }
456 
457 const char *SBThread::GetName() const {
458   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName);
459 
460   const char *name = nullptr;
461   std::unique_lock<std::recursive_mutex> lock;
462   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
463 
464   if (exe_ctx.HasThreadScope()) {
465     Process::StopLocker stop_locker;
466     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
467       name = exe_ctx.GetThreadPtr()->GetName();
468     }
469   }
470 
471   return name;
472 }
473 
474 const char *SBThread::GetQueueName() const {
475   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName);
476 
477   const char *name = nullptr;
478   std::unique_lock<std::recursive_mutex> lock;
479   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
480 
481   if (exe_ctx.HasThreadScope()) {
482     Process::StopLocker stop_locker;
483     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
484       name = exe_ctx.GetThreadPtr()->GetQueueName();
485     }
486   }
487 
488   return name;
489 }
490 
491 lldb::queue_id_t SBThread::GetQueueID() const {
492   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID);
493 
494   queue_id_t id = LLDB_INVALID_QUEUE_ID;
495   std::unique_lock<std::recursive_mutex> lock;
496   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
497 
498   if (exe_ctx.HasThreadScope()) {
499     Process::StopLocker stop_locker;
500     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
501       id = exe_ctx.GetThreadPtr()->GetQueueID();
502     }
503   }
504 
505   return id;
506 }
507 
508 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
509   LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString,
510                      (const char *, lldb::SBStream &), path, strm);
511 
512   bool success = false;
513   std::unique_lock<std::recursive_mutex> lock;
514   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
515 
516   if (exe_ctx.HasThreadScope()) {
517     Process::StopLocker stop_locker;
518     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
519       Thread *thread = exe_ctx.GetThreadPtr();
520       StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
521       if (info_root_sp) {
522         StructuredData::ObjectSP node =
523             info_root_sp->GetObjectForDotSeparatedPath(path);
524         if (node) {
525           if (node->GetType() == eStructuredDataTypeString) {
526             strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
527             success = true;
528           }
529           if (node->GetType() == eStructuredDataTypeInteger) {
530             strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
531             success = true;
532           }
533           if (node->GetType() == eStructuredDataTypeFloat) {
534             strm.Printf("0x%f", node->GetAsFloat()->GetValue());
535             success = true;
536           }
537           if (node->GetType() == eStructuredDataTypeBoolean) {
538             if (node->GetAsBoolean()->GetValue())
539               strm.Printf("true");
540             else
541               strm.Printf("false");
542             success = true;
543           }
544           if (node->GetType() == eStructuredDataTypeNull) {
545             strm.Printf("null");
546             success = true;
547           }
548         }
549       }
550     }
551   }
552 
553   return success;
554 }
555 
556 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
557                                 ThreadPlan *new_plan) {
558   SBError sb_error;
559 
560   Process *process = exe_ctx.GetProcessPtr();
561   if (!process) {
562     sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
563     return sb_error;
564   }
565 
566   Thread *thread = exe_ctx.GetThreadPtr();
567   if (!thread) {
568     sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
569     return sb_error;
570   }
571 
572   // User level plans should be Master Plans so they can be interrupted, other
573   // plans executed, and then a "continue" will resume the plan.
574   if (new_plan != nullptr) {
575     new_plan->SetIsMasterPlan(true);
576     new_plan->SetOkayToDiscard(false);
577   }
578 
579   // Why do we need to set the current thread by ID here???
580   process->GetThreadList().SetSelectedThreadByID(thread->GetID());
581 
582   if (process->GetTarget().GetDebugger().GetAsyncExecution())
583     sb_error.ref() = process->Resume();
584   else
585     sb_error.ref() = process->ResumeSynchronous(nullptr);
586 
587   return sb_error;
588 }
589 
590 void SBThread::StepOver(lldb::RunMode stop_other_threads) {
591   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode),
592                      stop_other_threads);
593 
594   SBError error; // Ignored
595   StepOver(stop_other_threads, error);
596 }
597 
598 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
599   LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &),
600                      stop_other_threads, error);
601 
602   std::unique_lock<std::recursive_mutex> lock;
603   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
604 
605   if (!exe_ctx.HasThreadScope()) {
606     error.SetErrorString("this SBThread object is invalid");
607     return;
608   }
609 
610   Thread *thread = exe_ctx.GetThreadPtr();
611   bool abort_other_plans = false;
612   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
613 
614   Status new_plan_status;
615   ThreadPlanSP new_plan_sp;
616   if (frame_sp) {
617     if (frame_sp->HasDebugInformation()) {
618       const LazyBool avoid_no_debug = eLazyBoolCalculate;
619       SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
620       new_plan_sp = thread->QueueThreadPlanForStepOverRange(
621           abort_other_plans, sc.line_entry, sc, stop_other_threads,
622           new_plan_status, avoid_no_debug);
623     } else {
624       new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
625           true, abort_other_plans, stop_other_threads, new_plan_status);
626     }
627   }
628   error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
629 }
630 
631 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
632   LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode),
633                      stop_other_threads);
634 
635   StepInto(nullptr, stop_other_threads);
636 }
637 
638 void SBThread::StepInto(const char *target_name,
639                         lldb::RunMode stop_other_threads) {
640   LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode),
641                      target_name, stop_other_threads);
642 
643   SBError error; // Ignored
644   StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
645 }
646 
647 void SBThread::StepInto(const char *target_name, uint32_t end_line,
648                         SBError &error, lldb::RunMode stop_other_threads) {
649   LLDB_RECORD_METHOD(void, SBThread, StepInto,
650                      (const char *, uint32_t, lldb::SBError &, lldb::RunMode),
651                      target_name, end_line, error, stop_other_threads);
652 
653 
654   std::unique_lock<std::recursive_mutex> lock;
655   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
656 
657   if (!exe_ctx.HasThreadScope()) {
658     error.SetErrorString("this SBThread object is invalid");
659     return;
660   }
661 
662   bool abort_other_plans = false;
663 
664   Thread *thread = exe_ctx.GetThreadPtr();
665   StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
666   ThreadPlanSP new_plan_sp;
667   Status new_plan_status;
668 
669   if (frame_sp && frame_sp->HasDebugInformation()) {
670     SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
671     AddressRange range;
672     if (end_line == LLDB_INVALID_LINE_NUMBER)
673       range = sc.line_entry.range;
674     else {
675       if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
676         return;
677     }
678 
679     const LazyBool step_out_avoids_code_without_debug_info =
680         eLazyBoolCalculate;
681     const LazyBool step_in_avoids_code_without_debug_info =
682         eLazyBoolCalculate;
683     new_plan_sp = thread->QueueThreadPlanForStepInRange(
684         abort_other_plans, range, sc, target_name, stop_other_threads,
685         new_plan_status, step_in_avoids_code_without_debug_info,
686         step_out_avoids_code_without_debug_info);
687   } else {
688     new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
689         false, abort_other_plans, stop_other_threads, new_plan_status);
690   }
691 
692   if (new_plan_status.Success())
693     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
694   else
695     error.SetErrorString(new_plan_status.AsCString());
696 }
697 
698 void SBThread::StepOut() {
699   LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut);
700 
701   SBError error; // Ignored
702   StepOut(error);
703 }
704 
705 void SBThread::StepOut(SBError &error) {
706   LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error);
707 
708   std::unique_lock<std::recursive_mutex> lock;
709   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
710 
711   if (!exe_ctx.HasThreadScope()) {
712     error.SetErrorString("this SBThread object is invalid");
713     return;
714   }
715 
716   bool abort_other_plans = false;
717   bool stop_other_threads = false;
718 
719   Thread *thread = exe_ctx.GetThreadPtr();
720 
721   const LazyBool avoid_no_debug = eLazyBoolCalculate;
722   Status new_plan_status;
723   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
724       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
725       eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
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 
733 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
734   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &),
735                      sb_frame);
736 
737   SBError error; // Ignored
738   StepOutOfFrame(sb_frame, error);
739 }
740 
741 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
742   LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame,
743                      (lldb::SBFrame &, lldb::SBError &), sb_frame, error);
744 
745 
746   std::unique_lock<std::recursive_mutex> lock;
747   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
748 
749   if (!sb_frame.IsValid()) {
750     error.SetErrorString("passed invalid SBFrame object");
751     return;
752   }
753 
754   StackFrameSP frame_sp(sb_frame.GetFrameSP());
755 
756   if (!exe_ctx.HasThreadScope()) {
757     error.SetErrorString("this SBThread object is invalid");
758     return;
759   }
760 
761   bool abort_other_plans = false;
762   bool stop_other_threads = false;
763   Thread *thread = exe_ctx.GetThreadPtr();
764   if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
765     error.SetErrorString("passed a frame from another thread");
766     return;
767   }
768 
769   Status new_plan_status;
770   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
771       abort_other_plans, nullptr, false, stop_other_threads, eVoteYes,
772       eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
773 
774   if (new_plan_status.Success())
775     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
776   else
777     error.SetErrorString(new_plan_status.AsCString());
778 }
779 
780 void SBThread::StepInstruction(bool step_over) {
781   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over);
782 
783   SBError error; // Ignored
784   StepInstruction(step_over, error);
785 }
786 
787 void SBThread::StepInstruction(bool step_over, SBError &error) {
788   LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &),
789                      step_over, error);
790 
791   std::unique_lock<std::recursive_mutex> lock;
792   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
793 
794   if (!exe_ctx.HasThreadScope()) {
795     error.SetErrorString("this SBThread object is invalid");
796     return;
797   }
798 
799   Thread *thread = exe_ctx.GetThreadPtr();
800   Status new_plan_status;
801   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
802       step_over, true, true, new_plan_status));
803 
804   if (new_plan_status.Success())
805     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
806   else
807     error.SetErrorString(new_plan_status.AsCString());
808 }
809 
810 void SBThread::RunToAddress(lldb::addr_t addr) {
811   LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr);
812 
813   SBError error; // Ignored
814   RunToAddress(addr, error);
815 }
816 
817 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
818   LLDB_RECORD_METHOD(void, SBThread, RunToAddress,
819                      (lldb::addr_t, lldb::SBError &), addr, error);
820 
821   std::unique_lock<std::recursive_mutex> lock;
822   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
823 
824   if (!exe_ctx.HasThreadScope()) {
825     error.SetErrorString("this SBThread object is invalid");
826     return;
827   }
828 
829   bool abort_other_plans = false;
830   bool stop_other_threads = true;
831 
832   Address target_addr(addr);
833 
834   Thread *thread = exe_ctx.GetThreadPtr();
835 
836   Status new_plan_status;
837   ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
838       abort_other_plans, target_addr, stop_other_threads, new_plan_status));
839 
840   if (new_plan_status.Success())
841     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
842   else
843     error.SetErrorString(new_plan_status.AsCString());
844 }
845 
846 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
847                                 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
848   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil,
849                      (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame,
850                      sb_file_spec, line);
851 
852   SBError sb_error;
853   char path[PATH_MAX];
854 
855   std::unique_lock<std::recursive_mutex> lock;
856   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
857 
858   StackFrameSP frame_sp(sb_frame.GetFrameSP());
859 
860   if (exe_ctx.HasThreadScope()) {
861     Target *target = exe_ctx.GetTargetPtr();
862     Thread *thread = exe_ctx.GetThreadPtr();
863 
864     if (line == 0) {
865       sb_error.SetErrorString("invalid line argument");
866       return LLDB_RECORD_RESULT(sb_error);
867     }
868 
869     if (!frame_sp) {
870       frame_sp = thread->GetSelectedFrame();
871       if (!frame_sp)
872         frame_sp = thread->GetStackFrameAtIndex(0);
873     }
874 
875     SymbolContext frame_sc;
876     if (!frame_sp) {
877       sb_error.SetErrorString("no valid frames in thread to step");
878       return LLDB_RECORD_RESULT(sb_error);
879     }
880 
881     // If we have a frame, get its line
882     frame_sc = frame_sp->GetSymbolContext(
883         eSymbolContextCompUnit | eSymbolContextFunction |
884         eSymbolContextLineEntry | eSymbolContextSymbol);
885 
886     if (frame_sc.comp_unit == nullptr) {
887       sb_error.SetErrorStringWithFormat(
888           "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
889       return LLDB_RECORD_RESULT(sb_error);
890     }
891 
892     FileSpec step_file_spec;
893     if (sb_file_spec.IsValid()) {
894       // The file spec passed in was valid, so use it
895       step_file_spec = sb_file_spec.ref();
896     } else {
897       if (frame_sc.line_entry.IsValid())
898         step_file_spec = frame_sc.line_entry.file;
899       else {
900         sb_error.SetErrorString("invalid file argument or no file for frame");
901         return LLDB_RECORD_RESULT(sb_error);
902       }
903     }
904 
905     // Grab the current function, then we will make sure the "until" address is
906     // within the function.  We discard addresses that are out of the current
907     // function, and then if there are no addresses remaining, give an
908     // appropriate error message.
909 
910     bool all_in_function = true;
911     AddressRange fun_range = frame_sc.function->GetAddressRange();
912 
913     std::vector<addr_t> step_over_until_addrs;
914     const bool abort_other_plans = false;
915     const bool stop_other_threads = false;
916     const bool check_inlines = true;
917     const bool exact = false;
918 
919     SymbolContextList sc_list;
920     frame_sc.comp_unit->ResolveSymbolContext(step_file_spec, line,
921                                              check_inlines, exact,
922                                              eSymbolContextLineEntry, sc_list);
923     const uint32_t num_matches = sc_list.GetSize();
924     if (num_matches > 0) {
925       SymbolContext sc;
926       for (uint32_t i = 0; i < num_matches; ++i) {
927         if (sc_list.GetContextAtIndex(i, sc)) {
928           addr_t step_addr =
929               sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
930           if (step_addr != LLDB_INVALID_ADDRESS) {
931             if (fun_range.ContainsLoadAddress(step_addr, target))
932               step_over_until_addrs.push_back(step_addr);
933             else
934               all_in_function = false;
935           }
936         }
937       }
938     }
939 
940     if (step_over_until_addrs.empty()) {
941       if (all_in_function) {
942         step_file_spec.GetPath(path, sizeof(path));
943         sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
944                                           line);
945       } else
946         sb_error.SetErrorString("step until target not in current function");
947     } else {
948       Status new_plan_status;
949       ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
950           abort_other_plans, &step_over_until_addrs[0],
951           step_over_until_addrs.size(), stop_other_threads,
952           frame_sp->GetFrameIndex(), new_plan_status));
953 
954       if (new_plan_status.Success())
955         sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
956       else
957         sb_error.SetErrorString(new_plan_status.AsCString());
958     }
959   } else {
960     sb_error.SetErrorString("this SBThread object is invalid");
961   }
962   return LLDB_RECORD_RESULT(sb_error);
963 }
964 
965 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
966   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
967                      (const char *), script_class_name);
968 
969   return LLDB_RECORD_RESULT(
970       StepUsingScriptedThreadPlan(script_class_name, true));
971 }
972 
973 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
974                                             bool resume_immediately) {
975   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
976                      (const char *, bool), script_class_name,
977                      resume_immediately);
978 
979   lldb::SBStructuredData no_data;
980   return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan(
981       script_class_name, no_data, resume_immediately));
982 }
983 
984 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
985                                               SBStructuredData &args_data,
986                                               bool resume_immediately) {
987   LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
988                      (const char *, lldb::SBStructuredData &, bool),
989                      script_class_name, args_data, resume_immediately);
990 
991   SBError 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     error.SetErrorString("this SBThread object is invalid");
998     return LLDB_RECORD_RESULT(error);
999   }
1000 
1001   Thread *thread = exe_ctx.GetThreadPtr();
1002   Status new_plan_status;
1003   StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP();
1004 
1005   ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1006       false, script_class_name, obj_sp, false, new_plan_status);
1007 
1008   if (new_plan_status.Fail()) {
1009     error.SetErrorString(new_plan_status.AsCString());
1010     return LLDB_RECORD_RESULT(error);
1011   }
1012 
1013   if (!resume_immediately)
1014     return LLDB_RECORD_RESULT(error);
1015 
1016   if (new_plan_status.Success())
1017     error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1018   else
1019     error.SetErrorString(new_plan_status.AsCString());
1020 
1021   return LLDB_RECORD_RESULT(error);
1022 }
1023 
1024 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1025   LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine,
1026                      (lldb::SBFileSpec &, uint32_t), file_spec, line);
1027 
1028   SBError sb_error;
1029 
1030   std::unique_lock<std::recursive_mutex> lock;
1031   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1032 
1033   if (!exe_ctx.HasThreadScope()) {
1034     sb_error.SetErrorString("this SBThread object is invalid");
1035     return LLDB_RECORD_RESULT(sb_error);
1036   }
1037 
1038   Thread *thread = exe_ctx.GetThreadPtr();
1039 
1040   Status err = thread->JumpToLine(file_spec.ref(), line, true);
1041   sb_error.SetError(err);
1042   return LLDB_RECORD_RESULT(sb_error);
1043 }
1044 
1045 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1046   LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1047                      (lldb::SBFrame &, lldb::SBValue &), frame, return_value);
1048 
1049   SBError sb_error;
1050 
1051   std::unique_lock<std::recursive_mutex> lock;
1052   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1053 
1054   if (exe_ctx.HasThreadScope()) {
1055     Thread *thread = exe_ctx.GetThreadPtr();
1056     sb_error.SetError(
1057         thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1058   }
1059 
1060   return LLDB_RECORD_RESULT(sb_error);
1061 }
1062 
1063 SBError SBThread::UnwindInnermostExpression() {
1064   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread,
1065                              UnwindInnermostExpression);
1066 
1067   SBError sb_error;
1068 
1069   std::unique_lock<std::recursive_mutex> lock;
1070   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1071 
1072   if (exe_ctx.HasThreadScope()) {
1073     Thread *thread = exe_ctx.GetThreadPtr();
1074     sb_error.SetError(thread->UnwindInnermostExpression());
1075     if (sb_error.Success())
1076       thread->SetSelectedFrameByIndex(0, false);
1077   }
1078 
1079   return LLDB_RECORD_RESULT(sb_error);
1080 }
1081 
1082 bool SBThread::Suspend() {
1083   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend);
1084 
1085   SBError error; // Ignored
1086   return Suspend(error);
1087 }
1088 
1089 bool SBThread::Suspend(SBError &error) {
1090   LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error);
1091 
1092   std::unique_lock<std::recursive_mutex> lock;
1093   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1094 
1095   bool result = false;
1096   if (exe_ctx.HasThreadScope()) {
1097     Process::StopLocker stop_locker;
1098     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1099       exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1100       result = true;
1101     } else {
1102       error.SetErrorString("process is running");
1103     }
1104   } else
1105     error.SetErrorString("this SBThread object is invalid");
1106   return result;
1107 }
1108 
1109 bool SBThread::Resume() {
1110   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume);
1111 
1112   SBError error; // Ignored
1113   return Resume(error);
1114 }
1115 
1116 bool SBThread::Resume(SBError &error) {
1117   LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error);
1118 
1119   std::unique_lock<std::recursive_mutex> lock;
1120   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1121 
1122   bool result = false;
1123   if (exe_ctx.HasThreadScope()) {
1124     Process::StopLocker stop_locker;
1125     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1126       const bool override_suspend = true;
1127       exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1128       result = true;
1129     } else {
1130       error.SetErrorString("process is running");
1131     }
1132   } else
1133     error.SetErrorString("this SBThread object is invalid");
1134   return result;
1135 }
1136 
1137 bool SBThread::IsSuspended() {
1138   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended);
1139 
1140   std::unique_lock<std::recursive_mutex> lock;
1141   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1142 
1143   if (exe_ctx.HasThreadScope())
1144     return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1145   return false;
1146 }
1147 
1148 bool SBThread::IsStopped() {
1149   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped);
1150 
1151   std::unique_lock<std::recursive_mutex> lock;
1152   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1153 
1154   if (exe_ctx.HasThreadScope())
1155     return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1156   return false;
1157 }
1158 
1159 SBProcess SBThread::GetProcess() {
1160   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess);
1161 
1162   SBProcess sb_process;
1163   std::unique_lock<std::recursive_mutex> lock;
1164   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1165 
1166   if (exe_ctx.HasThreadScope()) {
1167     // Have to go up to the target so we can get a shared pointer to our
1168     // process...
1169     sb_process.SetSP(exe_ctx.GetProcessSP());
1170   }
1171 
1172   return LLDB_RECORD_RESULT(sb_process);
1173 }
1174 
1175 uint32_t SBThread::GetNumFrames() {
1176   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames);
1177 
1178   uint32_t num_frames = 0;
1179   std::unique_lock<std::recursive_mutex> lock;
1180   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1181 
1182   if (exe_ctx.HasThreadScope()) {
1183     Process::StopLocker stop_locker;
1184     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1185       num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1186     }
1187   }
1188 
1189   return num_frames;
1190 }
1191 
1192 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1193   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx);
1194 
1195   SBFrame sb_frame;
1196   StackFrameSP frame_sp;
1197   std::unique_lock<std::recursive_mutex> lock;
1198   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1199 
1200   if (exe_ctx.HasThreadScope()) {
1201     Process::StopLocker stop_locker;
1202     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1203       frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1204       sb_frame.SetFrameSP(frame_sp);
1205     }
1206   }
1207 
1208   return LLDB_RECORD_RESULT(sb_frame);
1209 }
1210 
1211 lldb::SBFrame SBThread::GetSelectedFrame() {
1212   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame);
1213 
1214   SBFrame sb_frame;
1215   StackFrameSP frame_sp;
1216   std::unique_lock<std::recursive_mutex> lock;
1217   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1218 
1219   if (exe_ctx.HasThreadScope()) {
1220     Process::StopLocker stop_locker;
1221     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1222       frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1223       sb_frame.SetFrameSP(frame_sp);
1224     }
1225   }
1226 
1227   return LLDB_RECORD_RESULT(sb_frame);
1228 }
1229 
1230 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1231   LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t),
1232                      idx);
1233 
1234   SBFrame sb_frame;
1235   StackFrameSP frame_sp;
1236   std::unique_lock<std::recursive_mutex> lock;
1237   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1238 
1239   if (exe_ctx.HasThreadScope()) {
1240     Process::StopLocker stop_locker;
1241     if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1242       Thread *thread = exe_ctx.GetThreadPtr();
1243       frame_sp = thread->GetStackFrameAtIndex(idx);
1244       if (frame_sp) {
1245         thread->SetSelectedFrame(frame_sp.get());
1246         sb_frame.SetFrameSP(frame_sp);
1247       }
1248     }
1249   }
1250 
1251   return LLDB_RECORD_RESULT(sb_frame);
1252 }
1253 
1254 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1255   LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1256                             (const lldb::SBEvent &), event);
1257 
1258   return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr;
1259 }
1260 
1261 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1262   LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1263                             (const lldb::SBEvent &), event);
1264 
1265   return LLDB_RECORD_RESULT(
1266       Thread::ThreadEventData::GetStackFrameFromEvent(event.get()));
1267 }
1268 
1269 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1270   LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1271                             (const lldb::SBEvent &), event);
1272 
1273   return LLDB_RECORD_RESULT(
1274       Thread::ThreadEventData::GetThreadFromEvent(event.get()));
1275 }
1276 
1277 bool SBThread::operator==(const SBThread &rhs) const {
1278   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &),
1279                            rhs);
1280 
1281   return m_opaque_sp->GetThreadSP().get() ==
1282          rhs.m_opaque_sp->GetThreadSP().get();
1283 }
1284 
1285 bool SBThread::operator!=(const SBThread &rhs) const {
1286   LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &),
1287                            rhs);
1288 
1289   return m_opaque_sp->GetThreadSP().get() !=
1290          rhs.m_opaque_sp->GetThreadSP().get();
1291 }
1292 
1293 bool SBThread::GetStatus(SBStream &status) const {
1294   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &),
1295                            status);
1296 
1297   Stream &strm = status.ref();
1298 
1299   std::unique_lock<std::recursive_mutex> lock;
1300   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1301 
1302   if (exe_ctx.HasThreadScope()) {
1303     exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1304   } else
1305     strm.PutCString("No status");
1306 
1307   return true;
1308 }
1309 
1310 bool SBThread::GetDescription(SBStream &description) const {
1311   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &),
1312                            description);
1313 
1314   return GetDescription(description, false);
1315 }
1316 
1317 bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1318   LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription,
1319                            (lldb::SBStream &, bool), description, stop_format);
1320 
1321   Stream &strm = description.ref();
1322 
1323   std::unique_lock<std::recursive_mutex> lock;
1324   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1325 
1326   if (exe_ctx.HasThreadScope()) {
1327     exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
1328                                                     LLDB_INVALID_THREAD_ID,
1329                                                     stop_format);
1330     // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1331     // exe_ctx.GetThreadPtr()->GetID());
1332   } else
1333     strm.PutCString("No value");
1334 
1335   return true;
1336 }
1337 
1338 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1339   LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1340                      (const char *), type);
1341 
1342   std::unique_lock<std::recursive_mutex> lock;
1343   ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1344   SBThread sb_origin_thread;
1345 
1346   Process::StopLocker stop_locker;
1347   if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1348     if (exe_ctx.HasThreadScope()) {
1349       ThreadSP real_thread(exe_ctx.GetThreadSP());
1350       if (real_thread) {
1351         ConstString type_const(type);
1352         Process *process = exe_ctx.GetProcessPtr();
1353         if (process) {
1354           SystemRuntime *runtime = process->GetSystemRuntime();
1355           if (runtime) {
1356             ThreadSP new_thread_sp(
1357                 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1358             if (new_thread_sp) {
1359               // Save this in the Process' ExtendedThreadList so a strong
1360               // pointer retains the object.
1361               process->GetExtendedThreadList().AddThread(new_thread_sp);
1362               sb_origin_thread.SetThread(new_thread_sp);
1363             }
1364           }
1365         }
1366       }
1367     }
1368   }
1369 
1370   return LLDB_RECORD_RESULT(sb_origin_thread);
1371 }
1372 
1373 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1374   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread,
1375                              GetExtendedBacktraceOriginatingIndexID);
1376 
1377   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1378   if (thread_sp)
1379     return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1380   return LLDB_INVALID_INDEX32;
1381 }
1382 
1383 SBValue SBThread::GetCurrentException() {
1384   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException);
1385 
1386   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1387   if (!thread_sp)
1388     return LLDB_RECORD_RESULT(SBValue());
1389 
1390   return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException()));
1391 }
1392 
1393 SBThread SBThread::GetCurrentExceptionBacktrace() {
1394   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread,
1395                              GetCurrentExceptionBacktrace);
1396 
1397   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1398   if (!thread_sp)
1399     return LLDB_RECORD_RESULT(SBThread());
1400 
1401   return LLDB_RECORD_RESULT(
1402       SBThread(thread_sp->GetCurrentExceptionBacktrace()));
1403 }
1404 
1405 bool SBThread::SafeToCallFunctions() {
1406   LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions);
1407 
1408   ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1409   if (thread_sp)
1410     return thread_sp->SafeToCallFunctions();
1411   return true;
1412 }
1413 
1414 lldb_private::Thread *SBThread::operator->() {
1415   return get();
1416 }
1417 
1418 lldb_private::Thread *SBThread::get() {
1419   return m_opaque_sp->GetThreadSP().get();
1420 }
1421 
1422 namespace lldb_private {
1423 namespace repro {
1424 
1425 template <>
1426 void RegisterMethods<SBThread>(Registry &R) {
1427   LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName,
1428                               ());
1429   LLDB_REGISTER_CONSTRUCTOR(SBThread, ());
1430   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &));
1431   LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &));
1432   LLDB_REGISTER_METHOD(const lldb::SBThread &,
1433                        SBThread, operator=,(const lldb::SBThread &));
1434   LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ());
1435   LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ());
1436   LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ());
1437   LLDB_REGISTER_METHOD(void, SBThread, Clear, ());
1438   LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ());
1439   LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ());
1440   LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex,
1441                        (uint32_t));
1442   LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON,
1443                        (lldb::SBStream &));
1444   LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread,
1445                        GetStopReasonExtendedBacktraces,
1446                        (lldb::InstrumentationRuntimeType));
1447   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ());
1448   LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ());
1449   LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ());
1450   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ());
1451   LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ());
1452   LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ());
1453   LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString,
1454                        (const char *, lldb::SBStream &));
1455   LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode));
1456   LLDB_REGISTER_METHOD(void, SBThread, StepOver,
1457                        (lldb::RunMode, lldb::SBError &));
1458   LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode));
1459   LLDB_REGISTER_METHOD(void, SBThread, StepInto,
1460                        (const char *, lldb::RunMode));
1461   LLDB_REGISTER_METHOD(
1462       void, SBThread, StepInto,
1463       (const char *, uint32_t, lldb::SBError &, lldb::RunMode));
1464   LLDB_REGISTER_METHOD(void, SBThread, StepOut, ());
1465   LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &));
1466   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &));
1467   LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame,
1468                        (lldb::SBFrame &, lldb::SBError &));
1469   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool));
1470   LLDB_REGISTER_METHOD(void, SBThread, StepInstruction,
1471                        (bool, lldb::SBError &));
1472   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t));
1473   LLDB_REGISTER_METHOD(void, SBThread, RunToAddress,
1474                        (lldb::addr_t, lldb::SBError &));
1475   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil,
1476                        (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t));
1477   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1478                        (const char *));
1479   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1480                        (const char *, bool));
1481   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan,
1482                        (const char *, SBStructuredData &, bool));
1483   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine,
1484                        (lldb::SBFileSpec &, uint32_t));
1485   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame,
1486                        (lldb::SBFrame &, lldb::SBValue &));
1487   LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression,
1488                        ());
1489   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ());
1490   LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &));
1491   LLDB_REGISTER_METHOD(bool, SBThread, Resume, ());
1492   LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &));
1493   LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ());
1494   LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ());
1495   LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ());
1496   LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ());
1497   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t));
1498   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ());
1499   LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t));
1500   LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent,
1501                               (const lldb::SBEvent &));
1502   LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent,
1503                               (const lldb::SBEvent &));
1504   LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent,
1505                               (const lldb::SBEvent &));
1506   LLDB_REGISTER_METHOD_CONST(bool,
1507                              SBThread, operator==,(const lldb::SBThread &));
1508   LLDB_REGISTER_METHOD_CONST(bool,
1509                              SBThread, operator!=,(const lldb::SBThread &));
1510   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &));
1511   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1512                              (lldb::SBStream &));
1513   LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription,
1514                              (lldb::SBStream &, bool));
1515   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread,
1516                        (const char *));
1517   LLDB_REGISTER_METHOD(uint32_t, SBThread,
1518                        GetExtendedBacktraceOriginatingIndexID, ());
1519   LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ());
1520   LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace,
1521                        ());
1522   LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ());
1523   LLDB_REGISTER_CHAR_PTR_REDIRECT(size_t, SBThread, GetStopDescription);
1524 }
1525 
1526 }
1527 }
1528