1 //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "lldb/API/SBThread.h"
13 
14 #include "lldb/API/SBSymbolContext.h"
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/API/SBStream.h"
17 #include "lldb/Breakpoint/BreakpointLocation.h"
18 #include "lldb/Core/Debugger.h"
19 #include "lldb/Core/State.h"
20 #include "lldb/Core/Stream.h"
21 #include "lldb/Core/StreamFile.h"
22 #include "lldb/Core/StructuredData.h"
23 #include "lldb/Interpreter/CommandInterpreter.h"
24 #include "lldb/Symbol/SymbolContext.h"
25 #include "lldb/Symbol/CompileUnit.h"
26 #include "lldb/Target/SystemRuntime.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/Process.h"
29 #include "lldb/Target/Queue.h"
30 #include "lldb/Target/UnixSignals.h"
31 #include "lldb/Target/StopInfo.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/ThreadPlan.h"
34 #include "lldb/Target/ThreadPlanStepInstruction.h"
35 #include "lldb/Target/ThreadPlanStepOut.h"
36 #include "lldb/Target/ThreadPlanStepRange.h"
37 #include "lldb/Target/ThreadPlanStepInRange.h"
38 
39 
40 #include "lldb/API/SBAddress.h"
41 #include "lldb/API/SBDebugger.h"
42 #include "lldb/API/SBEvent.h"
43 #include "lldb/API/SBFrame.h"
44 #include "lldb/API/SBProcess.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)::GetQueueKind() => error: process is running",
119                              static_cast<void*>(exe_ctx.GetThreadPtr()));
120         }
121     }
122 
123     if (log)
124         log->Printf ("SBThread(%p)::GetQueueKind () => 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 size_t
333 SBThread::GetStopDescription (char *dst, size_t dst_len)
334 {
335     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
336 
337     Mutex::Locker api_locker;
338     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
339 
340     if (exe_ctx.HasThreadScope())
341     {
342         Process::StopLocker stop_locker;
343         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
344         {
345 
346             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
347             if (stop_info_sp)
348             {
349                 const char *stop_desc = stop_info_sp->GetDescription();
350                 if (stop_desc)
351                 {
352                     if (log)
353                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
354                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
355                                      stop_desc);
356                     if (dst)
357                         return ::snprintf (dst, dst_len, "%s", stop_desc);
358                     else
359                     {
360                         // NULL dst passed in, return the length needed to contain the description
361                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
362                     }
363                 }
364                 else
365                 {
366                     size_t stop_desc_len = 0;
367                     switch (stop_info_sp->GetStopReason())
368                     {
369                     case eStopReasonTrace:
370                     case eStopReasonPlanComplete:
371                         {
372                             static char trace_desc[] = "step";
373                             stop_desc = trace_desc;
374                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
375                         }
376                         break;
377 
378                     case eStopReasonBreakpoint:
379                         {
380                             static char bp_desc[] = "breakpoint hit";
381                             stop_desc = bp_desc;
382                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
383                         }
384                         break;
385 
386                     case eStopReasonWatchpoint:
387                         {
388                             static char wp_desc[] = "watchpoint hit";
389                             stop_desc = wp_desc;
390                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
391                         }
392                         break;
393 
394                     case eStopReasonSignal:
395                         {
396                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
397                             if (stop_desc == NULL || stop_desc[0] == '\0')
398                             {
399                                 static char signal_desc[] = "signal";
400                                 stop_desc = signal_desc;
401                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
402                             }
403                         }
404                         break;
405 
406                     case eStopReasonException:
407                         {
408                             char exc_desc[] = "exception";
409                             stop_desc = exc_desc;
410                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
411                         }
412                         break;
413 
414                     case eStopReasonExec:
415                         {
416                             char exc_desc[] = "exec";
417                             stop_desc = exc_desc;
418                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
419                         }
420                         break;
421 
422                     case eStopReasonThreadExiting:
423                         {
424                             char limbo_desc[] = "thread exiting";
425                             stop_desc = limbo_desc;
426                             stop_desc_len = sizeof(limbo_desc);
427                         }
428                         break;
429                     default:
430                         break;
431                     }
432 
433                     if (stop_desc && stop_desc[0])
434                     {
435                         if (log)
436                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
437                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
438                                          stop_desc);
439 
440                         if (dst)
441                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
442 
443                         if (stop_desc_len == 0)
444                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
445 
446                         return stop_desc_len;
447                     }
448                 }
449             }
450         }
451         else
452         {
453             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
454             if (log)
455                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
456                              static_cast<void*>(exe_ctx.GetThreadPtr()));
457         }
458     }
459     if (dst)
460         *dst = 0;
461     return 0;
462 }
463 
464 SBValue
465 SBThread::GetStopReturnValue ()
466 {
467     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
468     ValueObjectSP return_valobj_sp;
469     Mutex::Locker api_locker;
470     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
471 
472     if (exe_ctx.HasThreadScope())
473     {
474         Process::StopLocker stop_locker;
475         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
476         {
477             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
478             if (stop_info_sp)
479             {
480                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
481             }
482         }
483         else
484         {
485             if (log)
486                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
487                              static_cast<void*>(exe_ctx.GetThreadPtr()));
488         }
489     }
490 
491     if (log)
492         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
493                      static_cast<void*>(exe_ctx.GetThreadPtr()),
494                      return_valobj_sp.get()
495                         ? return_valobj_sp->GetValueAsCString()
496                         : "<no return value>");
497 
498     return SBValue (return_valobj_sp);
499 }
500 
501 void
502 SBThread::SetThread (const ThreadSP& lldb_object_sp)
503 {
504     m_opaque_sp->SetThreadSP (lldb_object_sp);
505 }
506 
507 lldb::tid_t
508 SBThread::GetThreadID () const
509 {
510     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
511     if (thread_sp)
512         return thread_sp->GetID();
513     return LLDB_INVALID_THREAD_ID;
514 }
515 
516 uint32_t
517 SBThread::GetIndexID () const
518 {
519     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
520     if (thread_sp)
521         return thread_sp->GetIndexID();
522     return LLDB_INVALID_INDEX32;
523 }
524 
525 const char *
526 SBThread::GetName () const
527 {
528     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
529     const char *name = NULL;
530     Mutex::Locker api_locker;
531     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
532 
533     if (exe_ctx.HasThreadScope())
534     {
535         Process::StopLocker stop_locker;
536         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
537         {
538             name = exe_ctx.GetThreadPtr()->GetName();
539         }
540         else
541         {
542             if (log)
543                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
544                              static_cast<void*>(exe_ctx.GetThreadPtr()));
545         }
546     }
547 
548     if (log)
549         log->Printf ("SBThread(%p)::GetName () => %s",
550                      static_cast<void*>(exe_ctx.GetThreadPtr()),
551                      name ? name : "NULL");
552 
553     return name;
554 }
555 
556 const char *
557 SBThread::GetQueueName () const
558 {
559     const char *name = NULL;
560     Mutex::Locker api_locker;
561     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
562 
563     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
564     if (exe_ctx.HasThreadScope())
565     {
566         Process::StopLocker stop_locker;
567         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
568         {
569             name = exe_ctx.GetThreadPtr()->GetQueueName();
570         }
571         else
572         {
573             if (log)
574                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
575                              static_cast<void*>(exe_ctx.GetThreadPtr()));
576         }
577     }
578 
579     if (log)
580         log->Printf ("SBThread(%p)::GetQueueName () => %s",
581                      static_cast<void*>(exe_ctx.GetThreadPtr()),
582                      name ? name : "NULL");
583 
584     return name;
585 }
586 
587 lldb::queue_id_t
588 SBThread::GetQueueID () const
589 {
590     queue_id_t id = LLDB_INVALID_QUEUE_ID;
591     Mutex::Locker api_locker;
592     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
593 
594     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
595     if (exe_ctx.HasThreadScope())
596     {
597         Process::StopLocker stop_locker;
598         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
599         {
600             id = exe_ctx.GetThreadPtr()->GetQueueID();
601         }
602         else
603         {
604             if (log)
605                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
606                              static_cast<void*>(exe_ctx.GetThreadPtr()));
607         }
608     }
609 
610     if (log)
611         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
612                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
613 
614     return id;
615 }
616 
617 bool
618 SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
619 {
620     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
621     bool success = false;
622     Mutex::Locker api_locker;
623     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
624 
625     if (exe_ctx.HasThreadScope())
626     {
627         Process::StopLocker stop_locker;
628         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
629         {
630             Thread *thread = exe_ctx.GetThreadPtr();
631             StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
632             if (info_root_sp)
633             {
634                 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path);
635                 if (node)
636                 {
637                     if (node->GetType() == StructuredData::Type::eTypeString)
638                     {
639                         strm.Printf ("%s", node->GetAsString()->GetValue().c_str());
640                         success = true;
641                     }
642                     if (node->GetType() == StructuredData::Type::eTypeInteger)
643                     {
644                         strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue());
645                         success = true;
646                     }
647                     if (node->GetType() == StructuredData::Type::eTypeFloat)
648                     {
649                         strm.Printf ("0x%f", node->GetAsFloat()->GetValue());
650                         success = true;
651                     }
652                     if (node->GetType() == StructuredData::Type::eTypeBoolean)
653                     {
654                         if (node->GetAsBoolean()->GetValue() == true)
655                             strm.Printf ("true");
656                         else
657                             strm.Printf ("false");
658                         success = true;
659                     }
660                     if (node->GetType() == StructuredData::Type::eTypeNull)
661                     {
662                         strm.Printf ("null");
663                         success = true;
664                     }
665                 }
666             }
667         }
668         else
669         {
670             if (log)
671                 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running",
672                              static_cast<void*>(exe_ctx.GetThreadPtr()));
673         }
674     }
675 
676     if (log)
677         log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s",
678                      static_cast<void*>(exe_ctx.GetThreadPtr()),
679                      strm.GetData());
680 
681     return success;
682 }
683 
684 
685 SBError
686 SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
687 {
688     SBError sb_error;
689 
690     Process *process = exe_ctx.GetProcessPtr();
691     if (!process)
692     {
693         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
694         return sb_error;
695     }
696 
697     Thread *thread = exe_ctx.GetThreadPtr();
698     if (!thread)
699     {
700         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
701         return sb_error;
702     }
703 
704     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
705     // then a "continue" will resume the plan.
706     if (new_plan != NULL)
707     {
708         new_plan->SetIsMasterPlan(true);
709         new_plan->SetOkayToDiscard(false);
710     }
711 
712     // Why do we need to set the current thread by ID here???
713     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
714 
715     if (process->GetTarget().GetDebugger().GetAsyncExecution ())
716         sb_error.ref() = process->Resume ();
717     else
718         sb_error.ref() = process->ResumeSynchronous (NULL);
719 
720     return sb_error;
721 }
722 
723 void
724 SBThread::StepOver (lldb::RunMode stop_other_threads)
725 {
726     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
727 
728     Mutex::Locker api_locker;
729     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
730 
731 
732     if (log)
733         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
734                      static_cast<void*>(exe_ctx.GetThreadPtr()),
735                      Thread::RunModeAsCString (stop_other_threads));
736 
737     if (exe_ctx.HasThreadScope())
738     {
739         Thread *thread = exe_ctx.GetThreadPtr();
740         bool abort_other_plans = false;
741         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
742 
743         ThreadPlanSP new_plan_sp;
744         if (frame_sp)
745         {
746             if (frame_sp->HasDebugInformation ())
747             {
748                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
749                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
750                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
751                                                                     sc.line_entry.range,
752                                                                     sc,
753                                                                     stop_other_threads,
754                                                                     avoid_no_debug);
755             }
756             else
757             {
758                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
759                                                                                abort_other_plans,
760                                                                                stop_other_threads);
761             }
762         }
763 
764         // This returns an error, we should use it!
765         ResumeNewPlan (exe_ctx, new_plan_sp.get());
766     }
767 }
768 
769 void
770 SBThread::StepInto (lldb::RunMode stop_other_threads)
771 {
772     StepInto (NULL, stop_other_threads);
773 }
774 
775 void
776 SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
777 {
778     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
779 
780     Mutex::Locker api_locker;
781     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
782 
783     if (log)
784         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
785                      static_cast<void*>(exe_ctx.GetThreadPtr()),
786                      target_name? target_name: "<NULL>",
787                      Thread::RunModeAsCString (stop_other_threads));
788 
789     if (exe_ctx.HasThreadScope())
790     {
791         bool abort_other_plans = false;
792 
793         Thread *thread = exe_ctx.GetThreadPtr();
794         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
795         ThreadPlanSP new_plan_sp;
796 
797         if (frame_sp && frame_sp->HasDebugInformation ())
798         {
799             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
800             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
801             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
802             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
803                                                               sc.line_entry.range,
804                                                               sc,
805                                                               target_name,
806                                                               stop_other_threads,
807                                                               step_in_avoids_code_without_debug_info,
808                                                               step_out_avoids_code_without_debug_info);
809         }
810         else
811         {
812             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
813                                                                            abort_other_plans,
814                                                                            stop_other_threads);
815         }
816 
817         // This returns an error, we should use it!
818         ResumeNewPlan (exe_ctx, new_plan_sp.get());
819     }
820 }
821 
822 void
823 SBThread::StepOut ()
824 {
825     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
826 
827     Mutex::Locker api_locker;
828     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
829 
830 
831     if (log)
832         log->Printf ("SBThread(%p)::StepOut ()",
833                      static_cast<void*>(exe_ctx.GetThreadPtr()));
834 
835     if (exe_ctx.HasThreadScope())
836     {
837         bool abort_other_plans = false;
838         bool stop_other_threads = false;
839 
840         Thread *thread = exe_ctx.GetThreadPtr();
841 
842         const LazyBool avoid_no_debug = eLazyBoolCalculate;
843         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
844                                                                     NULL,
845                                                                     false,
846                                                                     stop_other_threads,
847                                                                     eVoteYes,
848                                                                     eVoteNoOpinion,
849                                                                     0,
850                                                                     avoid_no_debug));
851 
852         // This returns an error, we should use it!
853         ResumeNewPlan (exe_ctx, new_plan_sp.get());
854     }
855 }
856 
857 void
858 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
859 {
860     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
861 
862     Mutex::Locker api_locker;
863     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
864 
865     StackFrameSP frame_sp (sb_frame.GetFrameSP());
866     if (log)
867     {
868         SBStream frame_desc_strm;
869         sb_frame.GetDescription (frame_desc_strm);
870         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
871                      static_cast<void*>(exe_ctx.GetThreadPtr()),
872                      static_cast<void*>(frame_sp.get()),
873                      frame_desc_strm.GetData());
874     }
875 
876     if (exe_ctx.HasThreadScope())
877     {
878         bool abort_other_plans = false;
879         bool stop_other_threads = false;
880         Thread *thread = exe_ctx.GetThreadPtr();
881 
882         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
883                                                                     NULL,
884                                                                     false,
885                                                                     stop_other_threads,
886                                                                     eVoteYes,
887                                                                     eVoteNoOpinion,
888                                                                     frame_sp->GetFrameIndex()));
889 
890         // This returns an error, we should use it!
891         ResumeNewPlan (exe_ctx, new_plan_sp.get());
892     }
893 }
894 
895 void
896 SBThread::StepInstruction (bool step_over)
897 {
898     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
899 
900     Mutex::Locker api_locker;
901     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
902 
903 
904 
905     if (log)
906         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
907                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
908 
909     if (exe_ctx.HasThreadScope())
910     {
911         Thread *thread = exe_ctx.GetThreadPtr();
912         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
913 
914         // This returns an error, we should use it!
915         ResumeNewPlan (exe_ctx, new_plan_sp.get());
916     }
917 }
918 
919 void
920 SBThread::RunToAddress (lldb::addr_t addr)
921 {
922     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
923 
924     Mutex::Locker api_locker;
925     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
926 
927 
928     if (log)
929         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
930                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
931 
932     if (exe_ctx.HasThreadScope())
933     {
934         bool abort_other_plans = false;
935         bool stop_other_threads = true;
936 
937         Address target_addr (addr);
938 
939         Thread *thread = exe_ctx.GetThreadPtr();
940 
941         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
942                                                                          target_addr,
943                                                                          stop_other_threads));
944 
945         // This returns an error, we should use it!
946         ResumeNewPlan (exe_ctx, new_plan_sp.get());
947     }
948 }
949 
950 SBError
951 SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
952                          lldb::SBFileSpec &sb_file_spec,
953                          uint32_t line)
954 {
955     SBError sb_error;
956     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
957     char path[PATH_MAX];
958 
959     Mutex::Locker api_locker;
960     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
961 
962     StackFrameSP frame_sp (sb_frame.GetFrameSP());
963 
964     if (log)
965     {
966         SBStream frame_desc_strm;
967         sb_frame.GetDescription (frame_desc_strm);
968         sb_file_spec->GetPath (path, sizeof(path));
969         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
970                      static_cast<void*>(exe_ctx.GetThreadPtr()),
971                      static_cast<void*>(frame_sp.get()),
972                      frame_desc_strm.GetData(), path, line);
973     }
974 
975     if (exe_ctx.HasThreadScope())
976     {
977         Target *target = exe_ctx.GetTargetPtr();
978         Thread *thread = exe_ctx.GetThreadPtr();
979 
980         if (line == 0)
981         {
982             sb_error.SetErrorString("invalid line argument");
983             return sb_error;
984         }
985 
986         if (!frame_sp)
987         {
988             frame_sp = thread->GetSelectedFrame ();
989             if (!frame_sp)
990                 frame_sp = thread->GetStackFrameAtIndex (0);
991         }
992 
993         SymbolContext frame_sc;
994         if (!frame_sp)
995         {
996             sb_error.SetErrorString("no valid frames in thread to step");
997             return sb_error;
998         }
999 
1000         // If we have a frame, get its line
1001         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1002                                                eSymbolContextFunction  |
1003                                                eSymbolContextLineEntry |
1004                                                eSymbolContextSymbol    );
1005 
1006         if (frame_sc.comp_unit == NULL)
1007         {
1008             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1009             return sb_error;
1010         }
1011 
1012         FileSpec step_file_spec;
1013         if (sb_file_spec.IsValid())
1014         {
1015             // The file spec passed in was valid, so use it
1016             step_file_spec = sb_file_spec.ref();
1017         }
1018         else
1019         {
1020             if (frame_sc.line_entry.IsValid())
1021                 step_file_spec = frame_sc.line_entry.file;
1022             else
1023             {
1024                 sb_error.SetErrorString("invalid file argument or no file for frame");
1025                 return sb_error;
1026             }
1027         }
1028 
1029         // Grab the current function, then we will make sure the "until" address is
1030         // within the function.  We discard addresses that are out of the current
1031         // function, and then if there are no addresses remaining, give an appropriate
1032         // error message.
1033 
1034         bool all_in_function = true;
1035         AddressRange fun_range = frame_sc.function->GetAddressRange();
1036 
1037         std::vector<addr_t> step_over_until_addrs;
1038         const bool abort_other_plans = false;
1039         const bool stop_other_threads = false;
1040         const bool check_inlines = true;
1041         const bool exact = false;
1042 
1043         SymbolContextList sc_list;
1044         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
1045                                                                                line,
1046                                                                                check_inlines,
1047                                                                                exact,
1048                                                                                eSymbolContextLineEntry,
1049                                                                                sc_list);
1050         if (num_matches > 0)
1051         {
1052             SymbolContext sc;
1053             for (uint32_t i=0; i<num_matches; ++i)
1054             {
1055                 if (sc_list.GetContextAtIndex(i, sc))
1056                 {
1057                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1058                     if (step_addr != LLDB_INVALID_ADDRESS)
1059                     {
1060                         if (fun_range.ContainsLoadAddress(step_addr, target))
1061                             step_over_until_addrs.push_back(step_addr);
1062                         else
1063                             all_in_function = false;
1064                     }
1065                 }
1066             }
1067         }
1068 
1069         if (step_over_until_addrs.empty())
1070         {
1071             if (all_in_function)
1072             {
1073                 step_file_spec.GetPath (path, sizeof(path));
1074                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1075             }
1076             else
1077                 sb_error.SetErrorString ("step until target not in current function");
1078         }
1079         else
1080         {
1081             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1082                                                                         &step_over_until_addrs[0],
1083                                                                         step_over_until_addrs.size(),
1084                                                                         stop_other_threads,
1085                                                                         frame_sp->GetFrameIndex()));
1086 
1087             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1088         }
1089     }
1090     else
1091     {
1092         sb_error.SetErrorString("this SBThread object is invalid");
1093     }
1094     return sb_error;
1095 }
1096 
1097 SBError
1098 SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
1099 {
1100     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1101     SBError sb_error;
1102 
1103     Mutex::Locker api_locker;
1104     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1105 
1106     if (log)
1107     {
1108         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1109                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1110                      script_class_name);
1111     }
1112 
1113 
1114     if (!exe_ctx.HasThreadScope())
1115     {
1116         sb_error.SetErrorString("this SBThread object is invalid");
1117         return sb_error;
1118     }
1119 
1120     Thread *thread = exe_ctx.GetThreadPtr();
1121     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
1122 
1123     if (thread_plan_sp)
1124         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1125     else
1126     {
1127         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
1128         if (log)
1129         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
1130                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1131                      script_class_name);
1132     }
1133 
1134     return sb_error;
1135 }
1136 
1137 SBError
1138 SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1139 {
1140     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1141     SBError sb_error;
1142 
1143     Mutex::Locker api_locker;
1144     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1145 
1146     if (log)
1147         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1148                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1149                      file_spec->GetPath().c_str(), line);
1150 
1151     if (!exe_ctx.HasThreadScope())
1152     {
1153         sb_error.SetErrorString("this SBThread object is invalid");
1154         return sb_error;
1155     }
1156 
1157     Thread *thread = exe_ctx.GetThreadPtr();
1158 
1159     Error err = thread->JumpToLine (file_spec.get(), line, true);
1160     sb_error.SetError (err);
1161     return sb_error;
1162 }
1163 
1164 SBError
1165 SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
1166 {
1167     SBError sb_error;
1168 
1169     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1170 
1171     Mutex::Locker api_locker;
1172     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1173 
1174 
1175     if (log)
1176         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1177                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1178                      frame.GetFrameID());
1179 
1180     if (exe_ctx.HasThreadScope())
1181     {
1182         Thread *thread = exe_ctx.GetThreadPtr();
1183         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1184     }
1185 
1186     return sb_error;
1187 }
1188 
1189 
1190 bool
1191 SBThread::Suspend()
1192 {
1193     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1194     ExecutionContext exe_ctx (m_opaque_sp.get());
1195     bool result = false;
1196     if (exe_ctx.HasThreadScope())
1197     {
1198         Process::StopLocker stop_locker;
1199         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1200         {
1201             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1202             result = true;
1203         }
1204         else
1205         {
1206             if (log)
1207                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1208                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1209         }
1210     }
1211     if (log)
1212         log->Printf ("SBThread(%p)::Suspend() => %i",
1213                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1214     return result;
1215 }
1216 
1217 bool
1218 SBThread::Resume ()
1219 {
1220     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1221     ExecutionContext exe_ctx (m_opaque_sp.get());
1222     bool result = false;
1223     if (exe_ctx.HasThreadScope())
1224     {
1225         Process::StopLocker stop_locker;
1226         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1227         {
1228             const bool override_suspend = true;
1229             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1230             result = true;
1231         }
1232         else
1233         {
1234             if (log)
1235                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1236                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1237         }
1238     }
1239     if (log)
1240         log->Printf ("SBThread(%p)::Resume() => %i",
1241                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1242     return result;
1243 }
1244 
1245 bool
1246 SBThread::IsSuspended()
1247 {
1248     ExecutionContext exe_ctx (m_opaque_sp.get());
1249     if (exe_ctx.HasThreadScope())
1250         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1251     return false;
1252 }
1253 
1254 bool
1255 SBThread::IsStopped()
1256 {
1257     ExecutionContext exe_ctx (m_opaque_sp.get());
1258     if (exe_ctx.HasThreadScope())
1259         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1260     return false;
1261 }
1262 
1263 SBProcess
1264 SBThread::GetProcess ()
1265 {
1266     SBProcess sb_process;
1267     ExecutionContext exe_ctx (m_opaque_sp.get());
1268     if (exe_ctx.HasThreadScope())
1269     {
1270         // Have to go up to the target so we can get a shared pointer to our process...
1271         sb_process.SetSP (exe_ctx.GetProcessSP());
1272     }
1273 
1274     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1275     if (log)
1276     {
1277         SBStream frame_desc_strm;
1278         sb_process.GetDescription (frame_desc_strm);
1279         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1280                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1281                      static_cast<void*>(sb_process.GetSP().get()),
1282                      frame_desc_strm.GetData());
1283     }
1284 
1285     return sb_process;
1286 }
1287 
1288 uint32_t
1289 SBThread::GetNumFrames ()
1290 {
1291     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1292 
1293     uint32_t num_frames = 0;
1294     Mutex::Locker api_locker;
1295     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1296 
1297     if (exe_ctx.HasThreadScope())
1298     {
1299         Process::StopLocker stop_locker;
1300         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1301         {
1302             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1303         }
1304         else
1305         {
1306             if (log)
1307                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1308                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1309         }
1310     }
1311 
1312     if (log)
1313         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1314                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1315 
1316     return num_frames;
1317 }
1318 
1319 SBFrame
1320 SBThread::GetFrameAtIndex (uint32_t idx)
1321 {
1322     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1323 
1324     SBFrame sb_frame;
1325     StackFrameSP frame_sp;
1326     Mutex::Locker api_locker;
1327     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1328 
1329     if (exe_ctx.HasThreadScope())
1330     {
1331         Process::StopLocker stop_locker;
1332         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1333         {
1334             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1335             sb_frame.SetFrameSP (frame_sp);
1336         }
1337         else
1338         {
1339             if (log)
1340                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1341                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1342         }
1343     }
1344 
1345     if (log)
1346     {
1347         SBStream frame_desc_strm;
1348         sb_frame.GetDescription (frame_desc_strm);
1349         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1350                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1351                      static_cast<void*>(frame_sp.get()),
1352                      frame_desc_strm.GetData());
1353     }
1354 
1355     return sb_frame;
1356 }
1357 
1358 lldb::SBFrame
1359 SBThread::GetSelectedFrame ()
1360 {
1361     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1362 
1363     SBFrame sb_frame;
1364     StackFrameSP frame_sp;
1365     Mutex::Locker api_locker;
1366     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1367 
1368     if (exe_ctx.HasThreadScope())
1369     {
1370         Process::StopLocker stop_locker;
1371         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1372         {
1373             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1374             sb_frame.SetFrameSP (frame_sp);
1375         }
1376         else
1377         {
1378             if (log)
1379                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1380                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1381         }
1382     }
1383 
1384     if (log)
1385     {
1386         SBStream frame_desc_strm;
1387         sb_frame.GetDescription (frame_desc_strm);
1388         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1389                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1390                      static_cast<void*>(frame_sp.get()),
1391                      frame_desc_strm.GetData());
1392     }
1393 
1394     return sb_frame;
1395 }
1396 
1397 lldb::SBFrame
1398 SBThread::SetSelectedFrame (uint32_t idx)
1399 {
1400     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1401 
1402     SBFrame sb_frame;
1403     StackFrameSP frame_sp;
1404     Mutex::Locker api_locker;
1405     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1406 
1407     if (exe_ctx.HasThreadScope())
1408     {
1409         Process::StopLocker stop_locker;
1410         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1411         {
1412             Thread *thread = exe_ctx.GetThreadPtr();
1413             frame_sp = thread->GetStackFrameAtIndex (idx);
1414             if (frame_sp)
1415             {
1416                 thread->SetSelectedFrame (frame_sp.get());
1417                 sb_frame.SetFrameSP (frame_sp);
1418             }
1419         }
1420         else
1421         {
1422             if (log)
1423                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1424                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1425         }
1426     }
1427 
1428     if (log)
1429     {
1430         SBStream frame_desc_strm;
1431         sb_frame.GetDescription (frame_desc_strm);
1432         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1433                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1434                      static_cast<void*>(frame_sp.get()),
1435                      frame_desc_strm.GetData());
1436     }
1437     return sb_frame;
1438 }
1439 
1440 bool
1441 SBThread::EventIsThreadEvent (const SBEvent &event)
1442 {
1443     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1444 }
1445 
1446 SBFrame
1447 SBThread::GetStackFrameFromEvent (const SBEvent &event)
1448 {
1449     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1450 
1451 }
1452 
1453 SBThread
1454 SBThread::GetThreadFromEvent (const SBEvent &event)
1455 {
1456     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1457 }
1458 
1459 bool
1460 SBThread::operator == (const SBThread &rhs) const
1461 {
1462     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1463 }
1464 
1465 bool
1466 SBThread::operator != (const SBThread &rhs) const
1467 {
1468     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1469 }
1470 
1471 bool
1472 SBThread::GetStatus (SBStream &status) const
1473 {
1474     Stream &strm = status.ref();
1475 
1476     ExecutionContext exe_ctx (m_opaque_sp.get());
1477     if (exe_ctx.HasThreadScope())
1478     {
1479         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1480     }
1481     else
1482         strm.PutCString ("No status");
1483 
1484     return true;
1485 }
1486 
1487 bool
1488 SBThread::GetDescription (SBStream &description) const
1489 {
1490     Stream &strm = description.ref();
1491 
1492     ExecutionContext exe_ctx (m_opaque_sp.get());
1493     if (exe_ctx.HasThreadScope())
1494     {
1495         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1496         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1497     }
1498     else
1499         strm.PutCString ("No value");
1500 
1501     return true;
1502 }
1503 
1504 SBThread
1505 SBThread::GetExtendedBacktraceThread (const char *type)
1506 {
1507     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1508     Mutex::Locker api_locker;
1509     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1510     SBThread sb_origin_thread;
1511 
1512     if (exe_ctx.HasThreadScope())
1513     {
1514         Process::StopLocker stop_locker;
1515         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1516         {
1517             ThreadSP real_thread(exe_ctx.GetThreadSP());
1518             if (real_thread)
1519             {
1520                 ConstString type_const (type);
1521                 Process *process = exe_ctx.GetProcessPtr();
1522                 if (process)
1523                 {
1524                     SystemRuntime *runtime = process->GetSystemRuntime();
1525                     if (runtime)
1526                     {
1527                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1528                         if (new_thread_sp)
1529                         {
1530                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
1531                             // object.
1532                             process->GetExtendedThreadList().AddThread (new_thread_sp);
1533                             sb_origin_thread.SetThread (new_thread_sp);
1534                             if (log)
1535                             {
1536                                 const char *queue_name = new_thread_sp->GetQueueName();
1537                                 if (queue_name == NULL)
1538                                     queue_name = "";
1539                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
1540                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1541                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1542                                              static_cast<void*>(new_thread_sp.get()),
1543                                              new_thread_sp->GetQueueID(),
1544                                              queue_name);
1545                             }
1546                         }
1547                     }
1548                 }
1549             }
1550         }
1551         else
1552         {
1553             if (log)
1554                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1555                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1556         }
1557     }
1558 
1559     if (log && sb_origin_thread.IsValid() == false)
1560         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1561                     static_cast<void*>(exe_ctx.GetThreadPtr()));
1562     return sb_origin_thread;
1563 }
1564 
1565 uint32_t
1566 SBThread::GetExtendedBacktraceOriginatingIndexID ()
1567 {
1568     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1569     if (thread_sp)
1570         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1571     return LLDB_INVALID_INDEX32;
1572 }
1573 
1574 bool
1575 SBThread::SafeToCallFunctions ()
1576 {
1577     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1578     if (thread_sp)
1579         return thread_sp->SafeToCallFunctions();
1580     return true;
1581 }
1582 
1583 lldb_private::Thread *
1584 SBThread::operator->()
1585 {
1586     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1587     if (thread_sp)
1588         return thread_sp.get();
1589     else
1590         return NULL;
1591 }
1592 
1593 lldb_private::Thread *
1594 SBThread::get()
1595 {
1596     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1597     if (thread_sp)
1598         return thread_sp.get();
1599     else
1600         return NULL;
1601 }
1602 
1603