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