]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/API/SBThread.cpp
Vendor import of stripped lldb trunk r256633:
[FreeBSD/FreeBSD.git] / source / API / SBThread.cpp
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     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
778
779     Mutex::Locker api_locker;
780     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
781
782     if (log)
783         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
784                      static_cast<void*>(exe_ctx.GetThreadPtr()),
785                      target_name? target_name: "<NULL>",
786                      Thread::RunModeAsCString (stop_other_threads));
787
788     if (exe_ctx.HasThreadScope())
789     {
790         bool abort_other_plans = false;
791
792         Thread *thread = exe_ctx.GetThreadPtr();
793         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
794         ThreadPlanSP new_plan_sp;
795
796         if (frame_sp && frame_sp->HasDebugInformation ())
797         {
798             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
799             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
800             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
801             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
802                                                               sc.line_entry,
803                                                               sc,
804                                                               target_name,
805                                                               stop_other_threads,
806                                                               step_in_avoids_code_without_debug_info,
807                                                               step_out_avoids_code_without_debug_info);
808         }
809         else
810         {
811             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
812                                                                            abort_other_plans,
813                                                                            stop_other_threads);
814         }
815
816         // This returns an error, we should use it!
817         ResumeNewPlan (exe_ctx, new_plan_sp.get());
818     }
819 }
820
821 void
822 SBThread::StepOut ()
823 {
824     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
825
826     Mutex::Locker api_locker;
827     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
828
829     if (log)
830         log->Printf ("SBThread(%p)::StepOut ()",
831                      static_cast<void*>(exe_ctx.GetThreadPtr()));
832
833     if (exe_ctx.HasThreadScope())
834     {
835         bool abort_other_plans = false;
836         bool stop_other_threads = false;
837
838         Thread *thread = exe_ctx.GetThreadPtr();
839
840         const LazyBool avoid_no_debug = eLazyBoolCalculate;
841         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
842                                                                     NULL,
843                                                                     false,
844                                                                     stop_other_threads,
845                                                                     eVoteYes,
846                                                                     eVoteNoOpinion,
847                                                                     0,
848                                                                     avoid_no_debug));
849
850         // This returns an error, we should use it!
851         ResumeNewPlan (exe_ctx, new_plan_sp.get());
852     }
853 }
854
855 void
856 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
857 {
858     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
859
860     Mutex::Locker api_locker;
861     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
862
863     if (!sb_frame.IsValid())
864     {
865         if (log)
866             log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
867                         static_cast<void*>(exe_ctx.GetThreadPtr()));
868         return;
869     }
870     
871     StackFrameSP frame_sp (sb_frame.GetFrameSP());
872     if (log)
873     {
874         SBStream frame_desc_strm;
875         sb_frame.GetDescription (frame_desc_strm);
876         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
877                      static_cast<void*>(exe_ctx.GetThreadPtr()),
878                      static_cast<void*>(frame_sp.get()),
879                      frame_desc_strm.GetData());
880     }
881
882     if (exe_ctx.HasThreadScope())
883     {
884         bool abort_other_plans = false;
885         bool stop_other_threads = false;
886         Thread *thread = exe_ctx.GetThreadPtr();
887         if (sb_frame.GetThread().GetThreadID() != thread->GetID())
888         {
889             log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
890                         static_cast<void*>(exe_ctx.GetThreadPtr()),
891                         sb_frame.GetThread().GetThreadID(),
892                         thread->GetID());
893         }
894
895         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
896                                                                     NULL,
897                                                                     false,
898                                                                     stop_other_threads,
899                                                                     eVoteYes,
900                                                                     eVoteNoOpinion,
901                                                                     frame_sp->GetFrameIndex()));
902
903         // This returns an error, we should use it!
904         ResumeNewPlan (exe_ctx, new_plan_sp.get());
905     }
906 }
907
908 void
909 SBThread::StepInstruction (bool step_over)
910 {
911     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
912
913     Mutex::Locker api_locker;
914     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
915
916
917
918     if (log)
919         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
920                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
921
922     if (exe_ctx.HasThreadScope())
923     {
924         Thread *thread = exe_ctx.GetThreadPtr();
925         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
926
927         // This returns an error, we should use it!
928         ResumeNewPlan (exe_ctx, new_plan_sp.get());
929     }
930 }
931
932 void
933 SBThread::RunToAddress (lldb::addr_t addr)
934 {
935     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
936
937     Mutex::Locker api_locker;
938     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
939
940
941     if (log)
942         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
943                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
944
945     if (exe_ctx.HasThreadScope())
946     {
947         bool abort_other_plans = false;
948         bool stop_other_threads = true;
949
950         Address target_addr (addr);
951
952         Thread *thread = exe_ctx.GetThreadPtr();
953
954         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
955                                                                          target_addr,
956                                                                          stop_other_threads));
957
958         // This returns an error, we should use it!
959         ResumeNewPlan (exe_ctx, new_plan_sp.get());
960     }
961 }
962
963 SBError
964 SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 
965                          lldb::SBFileSpec &sb_file_spec, 
966                          uint32_t line)
967 {
968     SBError sb_error;
969     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
970     char path[PATH_MAX];
971
972     Mutex::Locker api_locker;
973     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
974
975     StackFrameSP frame_sp (sb_frame.GetFrameSP());
976
977     if (log)
978     {
979         SBStream frame_desc_strm;
980         sb_frame.GetDescription (frame_desc_strm);
981         sb_file_spec->GetPath (path, sizeof(path));
982         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
983                      static_cast<void*>(exe_ctx.GetThreadPtr()),
984                      static_cast<void*>(frame_sp.get()),
985                      frame_desc_strm.GetData(), path, line);
986     }
987
988     if (exe_ctx.HasThreadScope())
989     {
990         Target *target = exe_ctx.GetTargetPtr();
991         Thread *thread = exe_ctx.GetThreadPtr();
992
993         if (line == 0)
994         {
995             sb_error.SetErrorString("invalid line argument");
996             return sb_error;
997         }
998
999         if (!frame_sp)
1000         {
1001             frame_sp = thread->GetSelectedFrame ();
1002             if (!frame_sp)
1003                 frame_sp = thread->GetStackFrameAtIndex (0);
1004         }
1005
1006         SymbolContext frame_sc;
1007         if (!frame_sp)        
1008         {
1009             sb_error.SetErrorString("no valid frames in thread to step");
1010             return sb_error;
1011         }
1012
1013         // If we have a frame, get its line
1014         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1015                                                eSymbolContextFunction  | 
1016                                                eSymbolContextLineEntry | 
1017                                                eSymbolContextSymbol    );
1018
1019         if (frame_sc.comp_unit == NULL)
1020         {
1021             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1022             return sb_error;
1023         }
1024
1025         FileSpec step_file_spec;
1026         if (sb_file_spec.IsValid())
1027         {
1028             // The file spec passed in was valid, so use it
1029             step_file_spec = sb_file_spec.ref();
1030         }
1031         else
1032         {
1033             if (frame_sc.line_entry.IsValid())
1034                 step_file_spec = frame_sc.line_entry.file;
1035             else
1036             {
1037                 sb_error.SetErrorString("invalid file argument or no file for frame");
1038                 return sb_error;
1039             }
1040         }
1041
1042         // Grab the current function, then we will make sure the "until" address is
1043         // within the function.  We discard addresses that are out of the current
1044         // function, and then if there are no addresses remaining, give an appropriate
1045         // error message.
1046
1047         bool all_in_function = true;
1048         AddressRange fun_range = frame_sc.function->GetAddressRange();
1049
1050         std::vector<addr_t> step_over_until_addrs;
1051         const bool abort_other_plans = false;
1052         const bool stop_other_threads = false;
1053         const bool check_inlines = true;
1054         const bool exact = false;
1055
1056         SymbolContextList sc_list;
1057         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 
1058                                                                                line, 
1059                                                                                check_inlines, 
1060                                                                                exact, 
1061                                                                                eSymbolContextLineEntry, 
1062                                                                                sc_list);
1063         if (num_matches > 0)
1064         {
1065             SymbolContext sc;
1066             for (uint32_t i=0; i<num_matches; ++i)
1067             {
1068                 if (sc_list.GetContextAtIndex(i, sc))
1069                 {
1070                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1071                     if (step_addr != LLDB_INVALID_ADDRESS)
1072                     {
1073                         if (fun_range.ContainsLoadAddress(step_addr, target))
1074                             step_over_until_addrs.push_back(step_addr);
1075                         else
1076                             all_in_function = false;
1077                     }
1078                 }
1079             }
1080         }
1081
1082         if (step_over_until_addrs.empty())
1083         {
1084             if (all_in_function)
1085             {
1086                 step_file_spec.GetPath (path, sizeof(path));
1087                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1088             }
1089             else
1090                 sb_error.SetErrorString ("step until target not in current function");
1091         }
1092         else
1093         {
1094             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1095                                                                         &step_over_until_addrs[0],
1096                                                                         step_over_until_addrs.size(),
1097                                                                         stop_other_threads,
1098                                                                         frame_sp->GetFrameIndex()));
1099
1100             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1101         }
1102     }
1103     else
1104     {
1105         sb_error.SetErrorString("this SBThread object is invalid");
1106     }
1107     return sb_error;
1108 }
1109
1110 SBError
1111 SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
1112 {
1113     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1114     SBError sb_error;
1115
1116     Mutex::Locker api_locker;
1117     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1118
1119     if (log)
1120     {
1121         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1122                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1123                      script_class_name);
1124     }
1125
1126
1127     if (!exe_ctx.HasThreadScope())
1128     {
1129         sb_error.SetErrorString("this SBThread object is invalid");
1130         return sb_error;
1131     }
1132
1133     Thread *thread = exe_ctx.GetThreadPtr();
1134     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
1135
1136     if (thread_plan_sp)
1137         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1138     else
1139     {
1140         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
1141         if (log)
1142         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
1143                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1144                      script_class_name);
1145     }
1146
1147     return sb_error;
1148 }
1149
1150 SBError
1151 SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1152 {
1153     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1154     SBError sb_error;
1155
1156     Mutex::Locker api_locker;
1157     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1158
1159     if (log)
1160         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1161                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1162                      file_spec->GetPath().c_str(), line);
1163
1164     if (!exe_ctx.HasThreadScope())
1165     {
1166         sb_error.SetErrorString("this SBThread object is invalid");
1167         return sb_error;
1168     }
1169
1170     Thread *thread = exe_ctx.GetThreadPtr();
1171
1172     Error err = thread->JumpToLine (file_spec.get(), line, true);
1173     sb_error.SetError (err);
1174     return sb_error;
1175 }
1176
1177 SBError
1178 SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
1179 {
1180     SBError sb_error;
1181
1182     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1183
1184     Mutex::Locker api_locker;
1185     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1186
1187
1188     if (log)
1189         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1190                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1191                      frame.GetFrameID());
1192
1193     if (exe_ctx.HasThreadScope())
1194     {
1195         Thread *thread = exe_ctx.GetThreadPtr();
1196         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1197     }
1198
1199     return sb_error;
1200 }
1201
1202
1203 bool
1204 SBThread::Suspend()
1205 {
1206     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1207     ExecutionContext exe_ctx (m_opaque_sp.get());
1208     bool result = false;
1209     if (exe_ctx.HasThreadScope())
1210     {
1211         Process::StopLocker stop_locker;
1212         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1213         {
1214             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1215             result = true;
1216         }
1217         else
1218         {
1219             if (log)
1220                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1221                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1222         }
1223     }
1224     if (log)
1225         log->Printf ("SBThread(%p)::Suspend() => %i",
1226                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1227     return result;
1228 }
1229
1230 bool
1231 SBThread::Resume ()
1232 {
1233     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1234     ExecutionContext exe_ctx (m_opaque_sp.get());
1235     bool result = false;
1236     if (exe_ctx.HasThreadScope())
1237     {
1238         Process::StopLocker stop_locker;
1239         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1240         {
1241             const bool override_suspend = true;
1242             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1243             result = true;
1244         }
1245         else
1246         {
1247             if (log)
1248                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1249                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1250         }
1251     }
1252     if (log)
1253         log->Printf ("SBThread(%p)::Resume() => %i",
1254                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1255     return result;
1256 }
1257
1258 bool
1259 SBThread::IsSuspended()
1260 {
1261     ExecutionContext exe_ctx (m_opaque_sp.get());
1262     if (exe_ctx.HasThreadScope())
1263         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1264     return false;
1265 }
1266
1267 bool
1268 SBThread::IsStopped()
1269 {
1270     ExecutionContext exe_ctx (m_opaque_sp.get());
1271     if (exe_ctx.HasThreadScope())
1272         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1273     return false;
1274 }
1275
1276 SBProcess
1277 SBThread::GetProcess ()
1278 {
1279     SBProcess sb_process;
1280     ExecutionContext exe_ctx (m_opaque_sp.get());
1281     if (exe_ctx.HasThreadScope())
1282     {
1283         // Have to go up to the target so we can get a shared pointer to our process...
1284         sb_process.SetSP (exe_ctx.GetProcessSP());
1285     }
1286
1287     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1288     if (log)
1289     {
1290         SBStream frame_desc_strm;
1291         sb_process.GetDescription (frame_desc_strm);
1292         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1293                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1294                      static_cast<void*>(sb_process.GetSP().get()),
1295                      frame_desc_strm.GetData());
1296     }
1297
1298     return sb_process;
1299 }
1300
1301 uint32_t
1302 SBThread::GetNumFrames ()
1303 {
1304     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1305
1306     uint32_t num_frames = 0;
1307     Mutex::Locker api_locker;
1308     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1309
1310     if (exe_ctx.HasThreadScope())
1311     {
1312         Process::StopLocker stop_locker;
1313         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1314         {
1315             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1316         }
1317         else
1318         {
1319             if (log)
1320                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1321                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1322         }
1323     }
1324
1325     if (log)
1326         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1327                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1328
1329     return num_frames;
1330 }
1331
1332 SBFrame
1333 SBThread::GetFrameAtIndex (uint32_t idx)
1334 {
1335     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1336
1337     SBFrame sb_frame;
1338     StackFrameSP frame_sp;
1339     Mutex::Locker api_locker;
1340     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1341
1342     if (exe_ctx.HasThreadScope())
1343     {
1344         Process::StopLocker stop_locker;
1345         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1346         {
1347             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1348             sb_frame.SetFrameSP (frame_sp);
1349         }
1350         else
1351         {
1352             if (log)
1353                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1354                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1355         }
1356     }
1357
1358     if (log)
1359     {
1360         SBStream frame_desc_strm;
1361         sb_frame.GetDescription (frame_desc_strm);
1362         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1363                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1364                      static_cast<void*>(frame_sp.get()),
1365                      frame_desc_strm.GetData());
1366     }
1367
1368     return sb_frame;
1369 }
1370
1371 lldb::SBFrame
1372 SBThread::GetSelectedFrame ()
1373 {
1374     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1375
1376     SBFrame sb_frame;
1377     StackFrameSP frame_sp;
1378     Mutex::Locker api_locker;
1379     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1380
1381     if (exe_ctx.HasThreadScope())
1382     {
1383         Process::StopLocker stop_locker;
1384         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1385         {
1386             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1387             sb_frame.SetFrameSP (frame_sp);
1388         }
1389         else
1390         {
1391             if (log)
1392                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1393                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1394         }
1395     }
1396
1397     if (log)
1398     {
1399         SBStream frame_desc_strm;
1400         sb_frame.GetDescription (frame_desc_strm);
1401         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1402                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1403                      static_cast<void*>(frame_sp.get()),
1404                      frame_desc_strm.GetData());
1405     }
1406
1407     return sb_frame;
1408 }
1409
1410 lldb::SBFrame
1411 SBThread::SetSelectedFrame (uint32_t idx)
1412 {
1413     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1414
1415     SBFrame sb_frame;
1416     StackFrameSP frame_sp;
1417     Mutex::Locker api_locker;
1418     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1419
1420     if (exe_ctx.HasThreadScope())
1421     {
1422         Process::StopLocker stop_locker;
1423         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1424         {
1425             Thread *thread = exe_ctx.GetThreadPtr();
1426             frame_sp = thread->GetStackFrameAtIndex (idx);
1427             if (frame_sp)
1428             {
1429                 thread->SetSelectedFrame (frame_sp.get());
1430                 sb_frame.SetFrameSP (frame_sp);
1431             }
1432         }
1433         else
1434         {
1435             if (log)
1436                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1437                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1438         }
1439     }
1440
1441     if (log)
1442     {
1443         SBStream frame_desc_strm;
1444         sb_frame.GetDescription (frame_desc_strm);
1445         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1446                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1447                      static_cast<void*>(frame_sp.get()),
1448                      frame_desc_strm.GetData());
1449     }
1450     return sb_frame;
1451 }
1452
1453 bool
1454 SBThread::EventIsThreadEvent (const SBEvent &event)
1455 {
1456     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1457 }
1458
1459 SBFrame
1460 SBThread::GetStackFrameFromEvent (const SBEvent &event)
1461 {
1462     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1463
1464 }
1465
1466 SBThread
1467 SBThread::GetThreadFromEvent (const SBEvent &event)
1468 {
1469     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1470 }
1471
1472 bool
1473 SBThread::operator == (const SBThread &rhs) const
1474 {
1475     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1476 }
1477
1478 bool
1479 SBThread::operator != (const SBThread &rhs) const
1480 {
1481     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1482 }
1483
1484 bool
1485 SBThread::GetStatus (SBStream &status) const
1486 {
1487     Stream &strm = status.ref();
1488
1489     ExecutionContext exe_ctx (m_opaque_sp.get());
1490     if (exe_ctx.HasThreadScope())
1491     {
1492         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1493     }
1494     else
1495         strm.PutCString ("No status");
1496     
1497     return true;
1498 }
1499
1500 bool
1501 SBThread::GetDescription (SBStream &description) const
1502 {
1503     Stream &strm = description.ref();
1504
1505     ExecutionContext exe_ctx (m_opaque_sp.get());
1506     if (exe_ctx.HasThreadScope())
1507     {
1508         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1509         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1510     }
1511     else
1512         strm.PutCString ("No value");
1513     
1514     return true;
1515 }
1516
1517 SBThread
1518 SBThread::GetExtendedBacktraceThread (const char *type)
1519 {
1520     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1521     Mutex::Locker api_locker;
1522     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1523     SBThread sb_origin_thread;
1524
1525     if (exe_ctx.HasThreadScope())
1526     {
1527         Process::StopLocker stop_locker;
1528         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1529         {
1530             ThreadSP real_thread(exe_ctx.GetThreadSP());
1531             if (real_thread)
1532             {
1533                 ConstString type_const (type);
1534                 Process *process = exe_ctx.GetProcessPtr();
1535                 if (process)
1536                 {
1537                     SystemRuntime *runtime = process->GetSystemRuntime();
1538                     if (runtime)
1539                     {
1540                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1541                         if (new_thread_sp)
1542                         {
1543                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
1544                             // object.
1545                             process->GetExtendedThreadList().AddThread (new_thread_sp);
1546                             sb_origin_thread.SetThread (new_thread_sp);
1547                             if (log)
1548                             {
1549                                 const char *queue_name = new_thread_sp->GetQueueName();
1550                                 if (queue_name == NULL)
1551                                     queue_name = "";
1552                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
1553                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1554                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1555                                              static_cast<void*>(new_thread_sp.get()),
1556                                              new_thread_sp->GetQueueID(),
1557                                              queue_name);
1558                             }
1559                         }
1560                     }
1561                 }
1562             }
1563         }
1564         else
1565         {
1566             if (log)
1567                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1568                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1569         }
1570     }
1571
1572     if (log && sb_origin_thread.IsValid() == false)
1573         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1574                     static_cast<void*>(exe_ctx.GetThreadPtr()));
1575     return sb_origin_thread;
1576 }
1577
1578 uint32_t
1579 SBThread::GetExtendedBacktraceOriginatingIndexID ()
1580 {
1581     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1582     if (thread_sp)
1583         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1584     return LLDB_INVALID_INDEX32;
1585 }
1586
1587 bool
1588 SBThread::SafeToCallFunctions ()
1589 {
1590     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1591     if (thread_sp)
1592         return thread_sp->SafeToCallFunctions();
1593     return true;
1594 }
1595
1596 lldb_private::Thread *
1597 SBThread::operator->()
1598 {
1599     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1600     if (thread_sp)
1601         return thread_sp.get();
1602     else
1603         return NULL;
1604 }
1605
1606 lldb_private::Thread *
1607 SBThread::get()
1608 {
1609     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1610     if (thread_sp)
1611         return thread_sp.get();
1612     else
1613         return NULL;
1614 }
1615