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