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