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