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