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