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