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