130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124c5de699SEli Friedman #include "lldb/API/SBThread.h"
1330fdc8d8SChris Lattner 
1430fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
174e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
186611103cSGreg Clayton #include "lldb/Core/Debugger.h"
19a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2130fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
235dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Process.h"
26b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
2730fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2830fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
29f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
3030fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner 
384c5de699SEli Friedman #include "lldb/API/SBAddress.h"
394c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
404f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4173ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
424c5de699SEli Friedman #include "lldb/API/SBProcess.h"
4373ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner using namespace lldb;
4630fdc8d8SChris Lattner using namespace lldb_private;
4730fdc8d8SChris Lattner 
484f465cffSJim Ingham const char *
494f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
504f465cffSJim Ingham {
514f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
524f465cffSJim Ingham }
534f465cffSJim Ingham 
54cfd1acedSGreg Clayton //----------------------------------------------------------------------
55cfd1acedSGreg Clayton // Constructors
56cfd1acedSGreg Clayton //----------------------------------------------------------------------
5730fdc8d8SChris Lattner SBThread::SBThread () :
587fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
5930fdc8d8SChris Lattner {
6030fdc8d8SChris Lattner }
6130fdc8d8SChris Lattner 
6230fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
637fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6430fdc8d8SChris Lattner {
6530fdc8d8SChris Lattner }
6630fdc8d8SChris Lattner 
6792ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
687fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
6930fdc8d8SChris Lattner {
707fdf9ef1SGreg Clayton 
7130fdc8d8SChris Lattner }
7230fdc8d8SChris Lattner 
7330fdc8d8SChris Lattner //----------------------------------------------------------------------
74cfd1acedSGreg Clayton // Assignment operator
75cfd1acedSGreg Clayton //----------------------------------------------------------------------
76cfd1acedSGreg Clayton 
77cfd1acedSGreg Clayton const lldb::SBThread &
78cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
79cfd1acedSGreg Clayton {
80cfd1acedSGreg Clayton     if (this != &rhs)
817fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
82cfd1acedSGreg Clayton     return *this;
83cfd1acedSGreg Clayton }
84cfd1acedSGreg Clayton 
85cfd1acedSGreg Clayton //----------------------------------------------------------------------
8630fdc8d8SChris Lattner // Destructor
8730fdc8d8SChris Lattner //----------------------------------------------------------------------
8830fdc8d8SChris Lattner SBThread::~SBThread()
8930fdc8d8SChris Lattner {
9030fdc8d8SChris Lattner }
9130fdc8d8SChris Lattner 
92b9ffa98cSJason Molenda lldb::SBQueue
93b9ffa98cSJason Molenda SBThread::GetQueue () const
94b9ffa98cSJason Molenda {
95b9ffa98cSJason Molenda     SBQueue sb_queue;
96b9ffa98cSJason Molenda     QueueSP queue_sp;
97b9ffa98cSJason Molenda     Mutex::Locker api_locker;
98b9ffa98cSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
99b9ffa98cSJason Molenda 
100b9ffa98cSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
101b9ffa98cSJason Molenda     if (exe_ctx.HasThreadScope())
102b9ffa98cSJason Molenda     {
103b9ffa98cSJason Molenda         Process::StopLocker stop_locker;
104b9ffa98cSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
105b9ffa98cSJason Molenda         {
106b9ffa98cSJason Molenda             queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
107b9ffa98cSJason Molenda             if (queue_sp)
108b9ffa98cSJason Molenda             {
109b9ffa98cSJason Molenda                 sb_queue.SetQueue (queue_sp);
110b9ffa98cSJason Molenda             }
111b9ffa98cSJason Molenda         }
112b9ffa98cSJason Molenda         else
113b9ffa98cSJason Molenda         {
114b9ffa98cSJason Molenda             if (log)
115b9ffa98cSJason Molenda                 log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running",
116b9ffa98cSJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
117b9ffa98cSJason Molenda         }
118b9ffa98cSJason Molenda     }
119b9ffa98cSJason Molenda 
120b9ffa98cSJason Molenda     if (log)
121b9ffa98cSJason Molenda         log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)",
122b9ffa98cSJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
123b9ffa98cSJason Molenda 
124b9ffa98cSJason Molenda     return sb_queue;
125b9ffa98cSJason Molenda }
126b9ffa98cSJason Molenda 
127b9ffa98cSJason Molenda 
12830fdc8d8SChris Lattner bool
12930fdc8d8SChris Lattner SBThread::IsValid() const
13030fdc8d8SChris Lattner {
1317fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
13230fdc8d8SChris Lattner }
13330fdc8d8SChris Lattner 
13448e42549SGreg Clayton void
13548e42549SGreg Clayton SBThread::Clear ()
13648e42549SGreg Clayton {
1377fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
13848e42549SGreg Clayton }
13948e42549SGreg Clayton 
14048e42549SGreg Clayton 
14130fdc8d8SChris Lattner StopReason
14230fdc8d8SChris Lattner SBThread::GetStopReason()
14330fdc8d8SChris Lattner {
1445160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
145ceb6b139SCaroline Tice 
146ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1474fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1484fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1494fc6cb9cSJim Ingham 
1501ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
15130fdc8d8SChris Lattner     {
1527fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1537fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1547fdf9ef1SGreg Clayton         {
15597d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
15630fdc8d8SChris Lattner         }
157c9858e4dSGreg Clayton         else
158c9858e4dSGreg Clayton         {
159c9858e4dSGreg Clayton             if (log)
160324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
161324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
162c9858e4dSGreg Clayton         }
1637fdf9ef1SGreg Clayton     }
164ceb6b139SCaroline Tice 
165ceb6b139SCaroline Tice     if (log)
166324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
167324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
168750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
169ceb6b139SCaroline Tice 
170ceb6b139SCaroline Tice     return reason;
17130fdc8d8SChris Lattner }
17230fdc8d8SChris Lattner 
17330fdc8d8SChris Lattner size_t
1744e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1754e78f606SGreg Clayton {
1764fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1774fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1784fc6cb9cSJim Ingham 
1791ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1804e78f606SGreg Clayton     {
1817fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1827fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1837fdf9ef1SGreg Clayton         {
1841ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1854e78f606SGreg Clayton             if (stop_info_sp)
1864e78f606SGreg Clayton             {
1874e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1884e78f606SGreg Clayton                 switch (reason)
1894e78f606SGreg Clayton                 {
1904e78f606SGreg Clayton                 case eStopReasonInvalid:
1914e78f606SGreg Clayton                 case eStopReasonNone:
1924e78f606SGreg Clayton                 case eStopReasonTrace:
19390ba8115SGreg Clayton                 case eStopReasonExec:
1944e78f606SGreg Clayton                 case eStopReasonPlanComplete:
195f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
1964e78f606SGreg Clayton                     // There is no data for these stop reasons.
1974e78f606SGreg Clayton                     return 0;
1984e78f606SGreg Clayton 
1994e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2004e78f606SGreg Clayton                     {
2014e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2021ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2034e78f606SGreg Clayton                         if (bp_site_sp)
2044e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
2054e78f606SGreg Clayton                         else
2064e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
2074e78f606SGreg Clayton                     }
2084e78f606SGreg Clayton                     break;
2094e78f606SGreg Clayton 
2104e78f606SGreg Clayton                 case eStopReasonWatchpoint:
211290fa41bSJohnny Chen                     return 1;
2124e78f606SGreg Clayton 
2134e78f606SGreg Clayton                 case eStopReasonSignal:
2144e78f606SGreg Clayton                     return 1;
2154e78f606SGreg Clayton 
2164e78f606SGreg Clayton                 case eStopReasonException:
2174e78f606SGreg Clayton                     return 1;
2184e78f606SGreg Clayton                 }
2194e78f606SGreg Clayton             }
2204e78f606SGreg Clayton         }
221c9858e4dSGreg Clayton         else
222c9858e4dSGreg Clayton         {
2235160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
224c9858e4dSGreg Clayton             if (log)
225324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
226324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
227c9858e4dSGreg Clayton         }
2287fdf9ef1SGreg Clayton     }
2294e78f606SGreg Clayton     return 0;
2304e78f606SGreg Clayton }
2314e78f606SGreg Clayton 
2324e78f606SGreg Clayton uint64_t
2334e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
2344e78f606SGreg Clayton {
2354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2374fc6cb9cSJim Ingham 
2381ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2394e78f606SGreg Clayton     {
2407fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2417fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2427fdf9ef1SGreg Clayton         {
2431ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2441ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2454e78f606SGreg Clayton             if (stop_info_sp)
2464e78f606SGreg Clayton             {
2474e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2484e78f606SGreg Clayton                 switch (reason)
2494e78f606SGreg Clayton                 {
2504e78f606SGreg Clayton                 case eStopReasonInvalid:
2514e78f606SGreg Clayton                 case eStopReasonNone:
2524e78f606SGreg Clayton                 case eStopReasonTrace:
25390ba8115SGreg Clayton                 case eStopReasonExec:
2544e78f606SGreg Clayton                 case eStopReasonPlanComplete:
255f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
2564e78f606SGreg Clayton                     // There is no data for these stop reasons.
2574e78f606SGreg Clayton                     return 0;
2584e78f606SGreg Clayton 
2594e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2604e78f606SGreg Clayton                     {
2614e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2621ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2634e78f606SGreg Clayton                         if (bp_site_sp)
2644e78f606SGreg Clayton                         {
2654e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2664e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2674e78f606SGreg Clayton                             if (bp_loc_sp)
2684e78f606SGreg Clayton                             {
2698334e14eSGreg Clayton                                 if (idx & 1)
2704e78f606SGreg Clayton                                 {
2714e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2724e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2734e78f606SGreg Clayton                                 }
2744e78f606SGreg Clayton                                 else
2754e78f606SGreg Clayton                                 {
2764e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2774e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2784e78f606SGreg Clayton                                 }
2794e78f606SGreg Clayton                             }
2804e78f606SGreg Clayton                         }
2814e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2824e78f606SGreg Clayton                     }
2834e78f606SGreg Clayton                     break;
2844e78f606SGreg Clayton 
2854e78f606SGreg Clayton                 case eStopReasonWatchpoint:
286290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2874e78f606SGreg Clayton 
2884e78f606SGreg Clayton                 case eStopReasonSignal:
2894e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2904e78f606SGreg Clayton 
2914e78f606SGreg Clayton                 case eStopReasonException:
2924e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2934e78f606SGreg Clayton                 }
2944e78f606SGreg Clayton             }
2954e78f606SGreg Clayton         }
296c9858e4dSGreg Clayton         else
297c9858e4dSGreg Clayton         {
2985160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
299c9858e4dSGreg Clayton             if (log)
300324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
301324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
302c9858e4dSGreg Clayton         }
3037fdf9ef1SGreg Clayton     }
3044e78f606SGreg Clayton     return 0;
3054e78f606SGreg Clayton }
3064e78f606SGreg Clayton 
3074e78f606SGreg Clayton size_t
30830fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
30930fdc8d8SChris Lattner {
3105160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
311ceb6b139SCaroline Tice 
3124fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3134fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3144fc6cb9cSJim Ingham 
3151ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
31630fdc8d8SChris Lattner     {
3177fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3187fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3197fdf9ef1SGreg Clayton         {
3207fdf9ef1SGreg Clayton 
3211ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
322b15bfc75SJim Ingham             if (stop_info_sp)
32330fdc8d8SChris Lattner             {
324b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
32530fdc8d8SChris Lattner                 if (stop_desc)
32630fdc8d8SChris Lattner                 {
327ceb6b139SCaroline Tice                     if (log)
3284838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
329324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
330324a1036SSaleem Abdulrasool                                      stop_desc);
33130fdc8d8SChris Lattner                     if (dst)
33230fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
33330fdc8d8SChris Lattner                     else
33430fdc8d8SChris Lattner                     {
33530fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
33630fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
33730fdc8d8SChris Lattner                     }
33830fdc8d8SChris Lattner                 }
33930fdc8d8SChris Lattner                 else
34030fdc8d8SChris Lattner                 {
34130fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
342b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
34330fdc8d8SChris Lattner                     {
34430fdc8d8SChris Lattner                     case eStopReasonTrace:
34530fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
34630fdc8d8SChris Lattner                         {
34730fdc8d8SChris Lattner                             static char trace_desc[] = "step";
34830fdc8d8SChris Lattner                             stop_desc = trace_desc;
34930fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
35030fdc8d8SChris Lattner                         }
35130fdc8d8SChris Lattner                         break;
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
35430fdc8d8SChris Lattner                         {
35530fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
35630fdc8d8SChris Lattner                             stop_desc = bp_desc;
35730fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
35830fdc8d8SChris Lattner                         }
35930fdc8d8SChris Lattner                         break;
36030fdc8d8SChris Lattner 
36130fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
36230fdc8d8SChris Lattner                         {
36330fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
36430fdc8d8SChris Lattner                             stop_desc = wp_desc;
36530fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
36630fdc8d8SChris Lattner                         }
36730fdc8d8SChris Lattner                         break;
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner                     case eStopReasonSignal:
37030fdc8d8SChris Lattner                         {
3711ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
37230fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
37330fdc8d8SChris Lattner                             {
37430fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
37530fdc8d8SChris Lattner                                 stop_desc = signal_desc;
37630fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
37730fdc8d8SChris Lattner                             }
37830fdc8d8SChris Lattner                         }
37930fdc8d8SChris Lattner                         break;
38030fdc8d8SChris Lattner 
38130fdc8d8SChris Lattner                     case eStopReasonException:
38230fdc8d8SChris Lattner                         {
38330fdc8d8SChris Lattner                             char exc_desc[] = "exception";
38430fdc8d8SChris Lattner                             stop_desc = exc_desc;
38530fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
38630fdc8d8SChris Lattner                         }
38730fdc8d8SChris Lattner                         break;
388c982c768SGreg Clayton 
38990ba8115SGreg Clayton                     case eStopReasonExec:
39090ba8115SGreg Clayton                         {
39190ba8115SGreg Clayton                             char exc_desc[] = "exec";
39290ba8115SGreg Clayton                             stop_desc = exc_desc;
39390ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
39490ba8115SGreg Clayton                         }
39590ba8115SGreg Clayton                         break;
39690ba8115SGreg Clayton 
397f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
398f85defaeSAndrew Kaylor                         {
399f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
400f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
401f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
402f85defaeSAndrew Kaylor                         }
403f85defaeSAndrew Kaylor                         break;
404c982c768SGreg Clayton                     default:
405c982c768SGreg Clayton                         break;
40630fdc8d8SChris Lattner                     }
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
40930fdc8d8SChris Lattner                     {
410ceb6b139SCaroline Tice                         if (log)
41193aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
412324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
413324a1036SSaleem Abdulrasool                                          stop_desc);
414ceb6b139SCaroline Tice 
41530fdc8d8SChris Lattner                         if (dst)
41630fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
41730fdc8d8SChris Lattner 
41830fdc8d8SChris Lattner                         if (stop_desc_len == 0)
41930fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
42030fdc8d8SChris Lattner 
42130fdc8d8SChris Lattner                         return stop_desc_len;
42230fdc8d8SChris Lattner                     }
42330fdc8d8SChris Lattner                 }
42430fdc8d8SChris Lattner             }
42530fdc8d8SChris Lattner         }
426c9858e4dSGreg Clayton         else
427c9858e4dSGreg Clayton         {
4285160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
429c9858e4dSGreg Clayton             if (log)
430324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
431324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
432c9858e4dSGreg Clayton         }
4337fdf9ef1SGreg Clayton     }
43430fdc8d8SChris Lattner     if (dst)
43530fdc8d8SChris Lattner         *dst = 0;
43630fdc8d8SChris Lattner     return 0;
43730fdc8d8SChris Lattner }
43830fdc8d8SChris Lattner 
43973ca05a2SJim Ingham SBValue
44073ca05a2SJim Ingham SBThread::GetStopReturnValue ()
44173ca05a2SJim Ingham {
4425160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
44373ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
4444fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4454fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4464fc6cb9cSJim Ingham 
4471ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
44873ca05a2SJim Ingham     {
4497fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4507fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4517fdf9ef1SGreg Clayton         {
4521ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
45373ca05a2SJim Ingham             if (stop_info_sp)
45473ca05a2SJim Ingham             {
45573ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
45673ca05a2SJim Ingham             }
45773ca05a2SJim Ingham         }
458c9858e4dSGreg Clayton         else
459c9858e4dSGreg Clayton         {
460c9858e4dSGreg Clayton             if (log)
461324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
462324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
463c9858e4dSGreg Clayton         }
4647fdf9ef1SGreg Clayton     }
46573ca05a2SJim Ingham 
46673ca05a2SJim Ingham     if (log)
467324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
468324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
46973ca05a2SJim Ingham                      return_valobj_sp.get()
47073ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
47173ca05a2SJim Ingham                         : "<no return value>");
47273ca05a2SJim Ingham 
47373ca05a2SJim Ingham     return SBValue (return_valobj_sp);
47473ca05a2SJim Ingham }
47573ca05a2SJim Ingham 
47630fdc8d8SChris Lattner void
47730fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
47830fdc8d8SChris Lattner {
4797fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
48030fdc8d8SChris Lattner }
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner lldb::tid_t
48330fdc8d8SChris Lattner SBThread::GetThreadID () const
48430fdc8d8SChris Lattner {
4857fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
48617a6ad05SGreg Clayton     if (thread_sp)
4871ac04c30SGreg Clayton         return thread_sp->GetID();
4881ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
48930fdc8d8SChris Lattner }
49030fdc8d8SChris Lattner 
49130fdc8d8SChris Lattner uint32_t
49230fdc8d8SChris Lattner SBThread::GetIndexID () const
49330fdc8d8SChris Lattner {
4947fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
49517a6ad05SGreg Clayton     if (thread_sp)
49617a6ad05SGreg Clayton         return thread_sp->GetIndexID();
49730fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
49830fdc8d8SChris Lattner }
4991ac04c30SGreg Clayton 
50030fdc8d8SChris Lattner const char *
50130fdc8d8SChris Lattner SBThread::GetName () const
50230fdc8d8SChris Lattner {
5035160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5044838131bSGreg Clayton     const char *name = NULL;
5054fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5064fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5074fc6cb9cSJim Ingham 
5081ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
509af67cecdSGreg Clayton     {
5107fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5117fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5127fdf9ef1SGreg Clayton         {
5131ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
514af67cecdSGreg Clayton         }
515c9858e4dSGreg Clayton         else
516c9858e4dSGreg Clayton         {
517c9858e4dSGreg Clayton             if (log)
518324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
519324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
520c9858e4dSGreg Clayton         }
5217fdf9ef1SGreg Clayton     }
522ceb6b139SCaroline Tice 
523ceb6b139SCaroline Tice     if (log)
524324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
525324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
526324a1036SSaleem Abdulrasool                      name ? name : "NULL");
527ceb6b139SCaroline Tice 
5284838131bSGreg Clayton     return name;
52930fdc8d8SChris Lattner }
53030fdc8d8SChris Lattner 
53130fdc8d8SChris Lattner const char *
53230fdc8d8SChris Lattner SBThread::GetQueueName () const
53330fdc8d8SChris Lattner {
5344838131bSGreg Clayton     const char *name = NULL;
5354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5374fc6cb9cSJim Ingham 
5385160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
540af67cecdSGreg Clayton     {
5417fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5427fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5437fdf9ef1SGreg Clayton         {
5441ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
545af67cecdSGreg Clayton         }
546c9858e4dSGreg Clayton         else
547c9858e4dSGreg Clayton         {
548c9858e4dSGreg Clayton             if (log)
549324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
550324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
551c9858e4dSGreg Clayton         }
5527fdf9ef1SGreg Clayton     }
553ceb6b139SCaroline Tice 
554ceb6b139SCaroline Tice     if (log)
555324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
556324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
557324a1036SSaleem Abdulrasool                      name ? name : "NULL");
558ceb6b139SCaroline Tice 
5594838131bSGreg Clayton     return name;
56030fdc8d8SChris Lattner }
56130fdc8d8SChris Lattner 
5624fdb5863SJason Molenda lldb::queue_id_t
5634fdb5863SJason Molenda SBThread::GetQueueID () const
5644fdb5863SJason Molenda {
5654fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
5664fdb5863SJason Molenda     Mutex::Locker api_locker;
5674fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5684fdb5863SJason Molenda 
5694fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5704fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
5714fdb5863SJason Molenda     {
5724fdb5863SJason Molenda         Process::StopLocker stop_locker;
5734fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5744fdb5863SJason Molenda         {
5754fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
5764fdb5863SJason Molenda         }
5774fdb5863SJason Molenda         else
5784fdb5863SJason Molenda         {
5794fdb5863SJason Molenda             if (log)
580324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
581324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
5824fdb5863SJason Molenda         }
5834fdb5863SJason Molenda     }
5844fdb5863SJason Molenda 
5854fdb5863SJason Molenda     if (log)
586324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
587324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
5884fdb5863SJason Molenda 
5894fdb5863SJason Molenda     return id;
5904fdb5863SJason Molenda }
5914fdb5863SJason Molenda 
59264e7ead1SJim Ingham SBError
59364e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
59464e7ead1SJim Ingham {
59564e7ead1SJim Ingham     SBError sb_error;
59664e7ead1SJim Ingham 
59764e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
59864e7ead1SJim Ingham     if (!process)
59964e7ead1SJim Ingham     {
60064e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
60164e7ead1SJim Ingham         return sb_error;
60264e7ead1SJim Ingham     }
60364e7ead1SJim Ingham 
60464e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
60564e7ead1SJim Ingham     if (!thread)
60664e7ead1SJim Ingham     {
60764e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
60864e7ead1SJim Ingham         return sb_error;
60964e7ead1SJim Ingham     }
61064e7ead1SJim Ingham 
61164e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
61264e7ead1SJim Ingham     // then a "continue" will resume the plan.
61364e7ead1SJim Ingham     if (new_plan != NULL)
61464e7ead1SJim Ingham     {
61564e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
61664e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
61764e7ead1SJim Ingham     }
61864e7ead1SJim Ingham 
61964e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
62064e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
62164e7ead1SJim Ingham     sb_error.ref() = process->Resume();
62264e7ead1SJim Ingham 
62364e7ead1SJim Ingham     if (sb_error.Success())
62464e7ead1SJim Ingham     {
62564e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
62664e7ead1SJim Ingham         // process to stop yet again!
62764e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
62864e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
62964e7ead1SJim Ingham     }
63064e7ead1SJim Ingham 
63164e7ead1SJim Ingham     return sb_error;
63264e7ead1SJim Ingham }
63330fdc8d8SChris Lattner 
63430fdc8d8SChris Lattner void
63530fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
63630fdc8d8SChris Lattner {
6375160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
638ceb6b139SCaroline Tice 
6394fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6404fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6414fc6cb9cSJim Ingham 
64217a6ad05SGreg Clayton 
643ceb6b139SCaroline Tice     if (log)
644324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
645324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
646ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
647ceb6b139SCaroline Tice 
6481ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
64930fdc8d8SChris Lattner     {
6501ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6517ba6e991SJim Ingham         bool abort_other_plans = false;
652b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
65330fdc8d8SChris Lattner 
6544d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
65530fdc8d8SChris Lattner         if (frame_sp)
65630fdc8d8SChris Lattner         {
65730fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
65830fdc8d8SChris Lattner             {
6594b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
66030fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
6614d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
66230fdc8d8SChris Lattner                                                                     sc.line_entry.range,
66330fdc8d8SChris Lattner                                                                     sc,
6644b4b2478SJim Ingham                                                                     stop_other_threads,
6654b4b2478SJim Ingham                                                                     avoid_no_debug);
66630fdc8d8SChris Lattner             }
66730fdc8d8SChris Lattner             else
66830fdc8d8SChris Lattner             {
6694d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
67030fdc8d8SChris Lattner                                                                                abort_other_plans,
67130fdc8d8SChris Lattner                                                                                stop_other_threads);
67230fdc8d8SChris Lattner             }
67330fdc8d8SChris Lattner         }
67430fdc8d8SChris Lattner 
67564e7ead1SJim Ingham         // This returns an error, we should use it!
6764d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
67730fdc8d8SChris Lattner     }
67830fdc8d8SChris Lattner }
67930fdc8d8SChris Lattner 
68030fdc8d8SChris Lattner void
68130fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
68230fdc8d8SChris Lattner {
683c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
684c627682eSJim Ingham }
685c627682eSJim Ingham 
686c627682eSJim Ingham void
687c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
688c627682eSJim Ingham {
6895160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
690ceb6b139SCaroline Tice 
6914fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6924fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
69317a6ad05SGreg Clayton 
69417a6ad05SGreg Clayton     if (log)
695c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
696324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
697c627682eSJim Ingham                      target_name? target_name: "<NULL>",
69817a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
699c627682eSJim Ingham 
7001ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
70130fdc8d8SChris Lattner     {
7027ba6e991SJim Ingham         bool abort_other_plans = false;
70330fdc8d8SChris Lattner 
7041ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
705b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
7064d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
70730fdc8d8SChris Lattner 
70830fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
70930fdc8d8SChris Lattner         {
7104b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
7114b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
71230fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
7134d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
71430fdc8d8SChris Lattner                                                               sc.line_entry.range,
71530fdc8d8SChris Lattner                                                               sc,
716c627682eSJim Ingham                                                               target_name,
717474966a4SGreg Clayton                                                               stop_other_threads,
7184b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
7194b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
72030fdc8d8SChris Lattner         }
72130fdc8d8SChris Lattner         else
72230fdc8d8SChris Lattner         {
7234d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
72430fdc8d8SChris Lattner                                                                            abort_other_plans,
72530fdc8d8SChris Lattner                                                                            stop_other_threads);
72630fdc8d8SChris Lattner         }
72730fdc8d8SChris Lattner 
72864e7ead1SJim Ingham         // This returns an error, we should use it!
7294d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
73030fdc8d8SChris Lattner     }
73130fdc8d8SChris Lattner }
73230fdc8d8SChris Lattner 
73330fdc8d8SChris Lattner void
73430fdc8d8SChris Lattner SBThread::StepOut ()
73530fdc8d8SChris Lattner {
7365160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
737ceb6b139SCaroline Tice 
7384fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7394fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7404fc6cb9cSJim Ingham 
741ceb6b139SCaroline Tice 
74217a6ad05SGreg Clayton     if (log)
743324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
744324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
74517a6ad05SGreg Clayton 
7461ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
74730fdc8d8SChris Lattner     {
7487ba6e991SJim Ingham         bool abort_other_plans = false;
74994b09246SJim Ingham         bool stop_other_threads = false;
75030fdc8d8SChris Lattner 
7511ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7521ac04c30SGreg Clayton 
7534b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
7544d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
755481cef25SGreg Clayton                                                                     NULL,
756481cef25SGreg Clayton                                                                     false,
757481cef25SGreg Clayton                                                                     stop_other_threads,
758481cef25SGreg Clayton                                                                     eVoteYes,
759481cef25SGreg Clayton                                                                     eVoteNoOpinion,
7604b4b2478SJim Ingham                                                                     0,
7614b4b2478SJim Ingham                                                                     avoid_no_debug));
762481cef25SGreg Clayton 
76364e7ead1SJim Ingham         // This returns an error, we should use it!
7644d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
765481cef25SGreg Clayton     }
766481cef25SGreg Clayton }
767481cef25SGreg Clayton 
768481cef25SGreg Clayton void
769481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
770481cef25SGreg Clayton {
7715160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
772481cef25SGreg Clayton 
7734fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7744fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7754fc6cb9cSJim Ingham 
776b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
777481cef25SGreg Clayton     if (log)
778481cef25SGreg Clayton     {
779481cef25SGreg Clayton         SBStream frame_desc_strm;
780481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
781324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
782324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
783324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
784324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
785481cef25SGreg Clayton     }
786481cef25SGreg Clayton 
7871ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
788481cef25SGreg Clayton     {
7897ba6e991SJim Ingham         bool abort_other_plans = false;
79094b09246SJim Ingham         bool stop_other_threads = false;
7911ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
792481cef25SGreg Clayton 
7934d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
794481cef25SGreg Clayton                                                                     NULL,
795481cef25SGreg Clayton                                                                     false,
796481cef25SGreg Clayton                                                                     stop_other_threads,
797481cef25SGreg Clayton                                                                     eVoteYes,
798481cef25SGreg Clayton                                                                     eVoteNoOpinion,
7994d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
80030fdc8d8SChris Lattner 
80164e7ead1SJim Ingham         // This returns an error, we should use it!
8024d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
80330fdc8d8SChris Lattner     }
80430fdc8d8SChris Lattner }
80530fdc8d8SChris Lattner 
80630fdc8d8SChris Lattner void
80730fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
80830fdc8d8SChris Lattner {
8095160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
810ceb6b139SCaroline Tice 
8114fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8124fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8134fc6cb9cSJim Ingham 
8141ac04c30SGreg Clayton 
815ceb6b139SCaroline Tice 
81617a6ad05SGreg Clayton     if (log)
817324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
818324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
81917a6ad05SGreg Clayton 
8201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
82130fdc8d8SChris Lattner     {
8221ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8234d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
82464e7ead1SJim Ingham 
82564e7ead1SJim Ingham         // This returns an error, we should use it!
8264d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
82730fdc8d8SChris Lattner     }
82830fdc8d8SChris Lattner }
82930fdc8d8SChris Lattner 
83030fdc8d8SChris Lattner void
83130fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
83230fdc8d8SChris Lattner {
8335160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
834ceb6b139SCaroline Tice 
8354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8374fc6cb9cSJim Ingham 
838ceb6b139SCaroline Tice 
83917a6ad05SGreg Clayton     if (log)
840324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
841324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
84217a6ad05SGreg Clayton 
8431ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
84430fdc8d8SChris Lattner     {
8457ba6e991SJim Ingham         bool abort_other_plans = false;
84630fdc8d8SChris Lattner         bool stop_other_threads = true;
84730fdc8d8SChris Lattner 
848e72dfb32SGreg Clayton         Address target_addr (addr);
84930fdc8d8SChris Lattner 
8501ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8511ac04c30SGreg Clayton 
8524d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
85364e7ead1SJim Ingham 
85464e7ead1SJim Ingham         // This returns an error, we should use it!
8554d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
85630fdc8d8SChris Lattner     }
85730fdc8d8SChris Lattner }
85830fdc8d8SChris Lattner 
859481cef25SGreg Clayton SBError
860481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
861481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
862481cef25SGreg Clayton                          uint32_t line)
863481cef25SGreg Clayton {
864481cef25SGreg Clayton     SBError sb_error;
8655160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
866481cef25SGreg Clayton     char path[PATH_MAX];
867481cef25SGreg Clayton 
8684fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8694fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8704fc6cb9cSJim Ingham 
871b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
87217a6ad05SGreg Clayton 
873481cef25SGreg Clayton     if (log)
874481cef25SGreg Clayton     {
875481cef25SGreg Clayton         SBStream frame_desc_strm;
876481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
877481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
878481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
879324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
880324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
881324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
882481cef25SGreg Clayton     }
883481cef25SGreg Clayton 
8841ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
885481cef25SGreg Clayton     {
8861ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
8871ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
888481cef25SGreg Clayton 
889481cef25SGreg Clayton         if (line == 0)
890481cef25SGreg Clayton         {
891481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
892481cef25SGreg Clayton             return sb_error;
893481cef25SGreg Clayton         }
894481cef25SGreg Clayton 
895b9556accSGreg Clayton         if (!frame_sp)
896481cef25SGreg Clayton         {
8971ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
898481cef25SGreg Clayton             if (!frame_sp)
8991ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
900481cef25SGreg Clayton         }
901481cef25SGreg Clayton 
902481cef25SGreg Clayton         SymbolContext frame_sc;
903481cef25SGreg Clayton         if (!frame_sp)
904481cef25SGreg Clayton         {
905481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
906481cef25SGreg Clayton             return sb_error;
907481cef25SGreg Clayton         }
908481cef25SGreg Clayton 
909481cef25SGreg Clayton         // If we have a frame, get its line
910481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
911481cef25SGreg Clayton                                                eSymbolContextFunction  |
912481cef25SGreg Clayton                                                eSymbolContextLineEntry |
913481cef25SGreg Clayton                                                eSymbolContextSymbol    );
914481cef25SGreg Clayton 
915481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
916481cef25SGreg Clayton         {
917481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
918481cef25SGreg Clayton             return sb_error;
919481cef25SGreg Clayton         }
920481cef25SGreg Clayton 
921481cef25SGreg Clayton         FileSpec step_file_spec;
922481cef25SGreg Clayton         if (sb_file_spec.IsValid())
923481cef25SGreg Clayton         {
924481cef25SGreg Clayton             // The file spec passed in was valid, so use it
925481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
926481cef25SGreg Clayton         }
927481cef25SGreg Clayton         else
928481cef25SGreg Clayton         {
929481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
930481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
931481cef25SGreg Clayton             else
932481cef25SGreg Clayton             {
933481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
934481cef25SGreg Clayton                 return sb_error;
935481cef25SGreg Clayton             }
936481cef25SGreg Clayton         }
937481cef25SGreg Clayton 
9389b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
9399b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
9409b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
9419b70ddb3SJim Ingham         // error message.
9429b70ddb3SJim Ingham 
9439b70ddb3SJim Ingham         bool all_in_function = true;
9449b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
9459b70ddb3SJim Ingham 
946481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
9477ba6e991SJim Ingham         const bool abort_other_plans = false;
948c02e3344SJim Ingham         const bool stop_other_threads = false;
949481cef25SGreg Clayton         const bool check_inlines = true;
950481cef25SGreg Clayton         const bool exact = false;
951481cef25SGreg Clayton 
952481cef25SGreg Clayton         SymbolContextList sc_list;
9539b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
9549b70ddb3SJim Ingham                                                                                line,
9559b70ddb3SJim Ingham                                                                                check_inlines,
9569b70ddb3SJim Ingham                                                                                exact,
9579b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
9589b70ddb3SJim Ingham                                                                                sc_list);
959481cef25SGreg Clayton         if (num_matches > 0)
960481cef25SGreg Clayton         {
961481cef25SGreg Clayton             SymbolContext sc;
962481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
963481cef25SGreg Clayton             {
964481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
965481cef25SGreg Clayton                 {
9669b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
967481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
968481cef25SGreg Clayton                     {
9699b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
970481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
9719b70ddb3SJim Ingham                         else
9729b70ddb3SJim Ingham                             all_in_function = false;
973481cef25SGreg Clayton                     }
974481cef25SGreg Clayton                 }
975481cef25SGreg Clayton             }
976481cef25SGreg Clayton         }
977481cef25SGreg Clayton 
978481cef25SGreg Clayton         if (step_over_until_addrs.empty())
979481cef25SGreg Clayton         {
9809b70ddb3SJim Ingham             if (all_in_function)
9819b70ddb3SJim Ingham             {
982481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
983fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
984481cef25SGreg Clayton             }
985481cef25SGreg Clayton             else
98686edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
9879b70ddb3SJim Ingham         }
9889b70ddb3SJim Ingham         else
989481cef25SGreg Clayton         {
9904d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
991481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
992481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
993481cef25SGreg Clayton                                                                         stop_other_threads,
9944d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
995481cef25SGreg Clayton 
9964d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
997481cef25SGreg Clayton         }
998481cef25SGreg Clayton     }
999481cef25SGreg Clayton     else
1000481cef25SGreg Clayton     {
1001481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
1002481cef25SGreg Clayton     }
1003481cef25SGreg Clayton     return sb_error;
1004481cef25SGreg Clayton }
1005481cef25SGreg Clayton 
10064413758cSJim Ingham SBError
1007f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1008f86248d9SRichard Mitton {
1009f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1010f86248d9SRichard Mitton     SBError sb_error;
1011f86248d9SRichard Mitton 
1012f86248d9SRichard Mitton     Mutex::Locker api_locker;
1013f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1014f86248d9SRichard Mitton 
1015f86248d9SRichard Mitton     if (log)
1016324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1017324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1018324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
1019f86248d9SRichard Mitton 
1020f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
1021f86248d9SRichard Mitton     {
1022f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
1023f86248d9SRichard Mitton         return sb_error;
1024f86248d9SRichard Mitton     }
1025f86248d9SRichard Mitton 
1026f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
1027f86248d9SRichard Mitton 
1028f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
1029f86248d9SRichard Mitton     sb_error.SetError (err);
1030f86248d9SRichard Mitton     return sb_error;
1031f86248d9SRichard Mitton }
1032f86248d9SRichard Mitton 
1033f86248d9SRichard Mitton SBError
1034cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
10354413758cSJim Ingham {
10364413758cSJim Ingham     SBError sb_error;
10374413758cSJim Ingham 
10385160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10394413758cSJim Ingham 
10404413758cSJim Ingham     Mutex::Locker api_locker;
10414413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10424413758cSJim Ingham 
10434413758cSJim Ingham 
10444413758cSJim Ingham     if (log)
1045324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1046324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1047324a1036SSaleem Abdulrasool                      frame.GetFrameID());
10484413758cSJim Ingham 
10494413758cSJim Ingham     if (exe_ctx.HasThreadScope())
10504413758cSJim Ingham     {
10514413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1052cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10534413758cSJim Ingham     }
10544413758cSJim Ingham 
10554413758cSJim Ingham     return sb_error;
10564413758cSJim Ingham }
10574413758cSJim Ingham 
1058481cef25SGreg Clayton 
1059722a0cdcSGreg Clayton bool
1060722a0cdcSGreg Clayton SBThread::Suspend()
1061722a0cdcSGreg Clayton {
10625160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10637fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1064c9858e4dSGreg Clayton     bool result = false;
10651ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1066722a0cdcSGreg Clayton     {
1067c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1068c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1069c9858e4dSGreg Clayton         {
10701ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1071c9858e4dSGreg Clayton             result = true;
1072722a0cdcSGreg Clayton         }
1073c9858e4dSGreg Clayton         else
1074c9858e4dSGreg Clayton         {
1075c9858e4dSGreg Clayton             if (log)
1076324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1077324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1078c9858e4dSGreg Clayton         }
1079c9858e4dSGreg Clayton     }
1080c9858e4dSGreg Clayton     if (log)
1081324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1082324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1083c9858e4dSGreg Clayton     return result;
1084722a0cdcSGreg Clayton }
1085722a0cdcSGreg Clayton 
1086722a0cdcSGreg Clayton bool
1087722a0cdcSGreg Clayton SBThread::Resume ()
1088722a0cdcSGreg Clayton {
10895160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10907fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1091c9858e4dSGreg Clayton     bool result = false;
10921ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1093722a0cdcSGreg Clayton     {
1094c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1095c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1096c9858e4dSGreg Clayton         {
10976c9ed91cSJim Ingham             const bool override_suspend = true;
10986c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1099c9858e4dSGreg Clayton             result = true;
1100722a0cdcSGreg Clayton         }
1101c9858e4dSGreg Clayton         else
1102c9858e4dSGreg Clayton         {
1103c9858e4dSGreg Clayton             if (log)
1104324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1105324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1106c9858e4dSGreg Clayton         }
1107c9858e4dSGreg Clayton     }
1108c9858e4dSGreg Clayton     if (log)
1109324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1110324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1111c9858e4dSGreg Clayton     return result;
1112722a0cdcSGreg Clayton }
1113722a0cdcSGreg Clayton 
1114722a0cdcSGreg Clayton bool
1115722a0cdcSGreg Clayton SBThread::IsSuspended()
1116722a0cdcSGreg Clayton {
11177fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
11181ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
11191ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1120722a0cdcSGreg Clayton     return false;
1121722a0cdcSGreg Clayton }
1122722a0cdcSGreg Clayton 
1123a75418dbSAndrew Kaylor bool
1124a75418dbSAndrew Kaylor SBThread::IsStopped()
1125a75418dbSAndrew Kaylor {
1126a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1127a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1128a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1129a75418dbSAndrew Kaylor     return false;
1130a75418dbSAndrew Kaylor }
1131a75418dbSAndrew Kaylor 
113230fdc8d8SChris Lattner SBProcess
113330fdc8d8SChris Lattner SBThread::GetProcess ()
113430fdc8d8SChris Lattner {
1135b9556accSGreg Clayton     SBProcess sb_process;
11367fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
11371ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
113830fdc8d8SChris Lattner     {
113930fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
11401ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
114130fdc8d8SChris Lattner     }
1142ceb6b139SCaroline Tice 
11435160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1144ceb6b139SCaroline Tice     if (log)
1145ceb6b139SCaroline Tice     {
1146481cef25SGreg Clayton         SBStream frame_desc_strm;
1147b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1148324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1149324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1150324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1151324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1152ceb6b139SCaroline Tice     }
1153ceb6b139SCaroline Tice 
1154b9556accSGreg Clayton     return sb_process;
115530fdc8d8SChris Lattner }
115630fdc8d8SChris Lattner 
115730fdc8d8SChris Lattner uint32_t
115830fdc8d8SChris Lattner SBThread::GetNumFrames ()
115930fdc8d8SChris Lattner {
11605160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1161ceb6b139SCaroline Tice 
1162ceb6b139SCaroline Tice     uint32_t num_frames = 0;
11634fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11644fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11654fc6cb9cSJim Ingham 
11661ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1167af67cecdSGreg Clayton     {
11687fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11697fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11707fdf9ef1SGreg Clayton         {
11711ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1172af67cecdSGreg Clayton         }
1173c9858e4dSGreg Clayton         else
1174c9858e4dSGreg Clayton         {
1175c9858e4dSGreg Clayton             if (log)
1176324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1177324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1178c9858e4dSGreg Clayton         }
11797fdf9ef1SGreg Clayton     }
1180ceb6b139SCaroline Tice 
1181ceb6b139SCaroline Tice     if (log)
1182324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1183324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1184ceb6b139SCaroline Tice 
1185ceb6b139SCaroline Tice     return num_frames;
118630fdc8d8SChris Lattner }
118730fdc8d8SChris Lattner 
118830fdc8d8SChris Lattner SBFrame
118930fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
119030fdc8d8SChris Lattner {
11915160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1192ceb6b139SCaroline Tice 
119330fdc8d8SChris Lattner     SBFrame sb_frame;
1194b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11954fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11964fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11974fc6cb9cSJim Ingham 
11981ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1199af67cecdSGreg Clayton     {
12007fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12017fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12027fdf9ef1SGreg Clayton         {
12031ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1204b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1205af67cecdSGreg Clayton         }
1206c9858e4dSGreg Clayton         else
1207c9858e4dSGreg Clayton         {
1208c9858e4dSGreg Clayton             if (log)
1209324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1210324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1211c9858e4dSGreg Clayton         }
12127fdf9ef1SGreg Clayton     }
1213ceb6b139SCaroline Tice 
1214ceb6b139SCaroline Tice     if (log)
1215ceb6b139SCaroline Tice     {
1216481cef25SGreg Clayton         SBStream frame_desc_strm;
1217481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
12184838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1219324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1220324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1221324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1222ceb6b139SCaroline Tice     }
1223ceb6b139SCaroline Tice 
122430fdc8d8SChris Lattner     return sb_frame;
122530fdc8d8SChris Lattner }
122630fdc8d8SChris Lattner 
1227f028a1fbSGreg Clayton lldb::SBFrame
1228f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1229f028a1fbSGreg Clayton {
12305160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1231f028a1fbSGreg Clayton 
1232f028a1fbSGreg Clayton     SBFrame sb_frame;
1233b57e4a1bSJason Molenda     StackFrameSP frame_sp;
12344fc6cb9cSJim Ingham     Mutex::Locker api_locker;
12354fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12364fc6cb9cSJim Ingham 
12371ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1238af67cecdSGreg Clayton     {
12397fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12407fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12417fdf9ef1SGreg Clayton         {
12421ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1243b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1244af67cecdSGreg Clayton         }
1245c9858e4dSGreg Clayton         else
1246c9858e4dSGreg Clayton         {
1247c9858e4dSGreg Clayton             if (log)
1248324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1249324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1250c9858e4dSGreg Clayton         }
12517fdf9ef1SGreg Clayton     }
1252f028a1fbSGreg Clayton 
1253f028a1fbSGreg Clayton     if (log)
1254f028a1fbSGreg Clayton     {
1255481cef25SGreg Clayton         SBStream frame_desc_strm;
1256481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1257f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1258324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1259324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1260324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1261f028a1fbSGreg Clayton     }
1262f028a1fbSGreg Clayton 
1263f028a1fbSGreg Clayton     return sb_frame;
1264f028a1fbSGreg Clayton }
1265f028a1fbSGreg Clayton 
1266f028a1fbSGreg Clayton lldb::SBFrame
1267f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1268f028a1fbSGreg Clayton {
12695160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1270f028a1fbSGreg Clayton 
1271f028a1fbSGreg Clayton     SBFrame sb_frame;
1272b57e4a1bSJason Molenda     StackFrameSP frame_sp;
12734fc6cb9cSJim Ingham     Mutex::Locker api_locker;
12744fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12754fc6cb9cSJim Ingham 
12761ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1277f028a1fbSGreg Clayton     {
12787fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12797fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12807fdf9ef1SGreg Clayton         {
12811ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
12821ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1283f028a1fbSGreg Clayton             if (frame_sp)
1284f028a1fbSGreg Clayton             {
12851ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1286b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1287f028a1fbSGreg Clayton             }
1288f028a1fbSGreg Clayton         }
1289c9858e4dSGreg Clayton         else
1290c9858e4dSGreg Clayton         {
1291c9858e4dSGreg Clayton             if (log)
1292324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1293324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1294c9858e4dSGreg Clayton         }
12957fdf9ef1SGreg Clayton     }
1296f028a1fbSGreg Clayton 
1297f028a1fbSGreg Clayton     if (log)
1298f028a1fbSGreg Clayton     {
1299481cef25SGreg Clayton         SBStream frame_desc_strm;
1300481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1301f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1302324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1303324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1304324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1305f028a1fbSGreg Clayton     }
1306f028a1fbSGreg Clayton     return sb_frame;
1307f028a1fbSGreg Clayton }
1308f028a1fbSGreg Clayton 
13094f465cffSJim Ingham bool
13104f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
13114f465cffSJim Ingham {
13124f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
13134f465cffSJim Ingham }
13144f465cffSJim Ingham 
13154f465cffSJim Ingham SBFrame
13164f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
13174f465cffSJim Ingham {
13184f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
13194f465cffSJim Ingham 
13204f465cffSJim Ingham }
13214f465cffSJim Ingham 
13224f465cffSJim Ingham SBThread
13234f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
13244f465cffSJim Ingham {
13254f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
13264f465cffSJim Ingham }
1327f028a1fbSGreg Clayton 
132830fdc8d8SChris Lattner bool
132930fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
133030fdc8d8SChris Lattner {
13317fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
133230fdc8d8SChris Lattner }
133330fdc8d8SChris Lattner 
133430fdc8d8SChris Lattner bool
133530fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
133630fdc8d8SChris Lattner {
13377fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
133830fdc8d8SChris Lattner }
1339dde9cff3SCaroline Tice 
1340dde9cff3SCaroline Tice bool
13414f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
13424f465cffSJim Ingham {
13434f465cffSJim Ingham     Stream &strm = status.ref();
13444f465cffSJim Ingham 
13454f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
13464f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
13474f465cffSJim Ingham     {
13484f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
13494f465cffSJim Ingham     }
13504f465cffSJim Ingham     else
13514f465cffSJim Ingham         strm.PutCString ("No status");
13524f465cffSJim Ingham 
13534f465cffSJim Ingham     return true;
13544f465cffSJim Ingham }
13554f465cffSJim Ingham 
13564f465cffSJim Ingham bool
1357ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1358ceb6b139SCaroline Tice {
1359da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1360da7bc7d0SGreg Clayton 
13617fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1363ceb6b139SCaroline Tice     {
1364d01b2953SDaniel Malea         strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1365ceb6b139SCaroline Tice     }
1366ceb6b139SCaroline Tice     else
1367da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1368ceb6b139SCaroline Tice 
1369ceb6b139SCaroline Tice     return true;
1370ceb6b139SCaroline Tice }
13715dd4916fSJason Molenda 
13725dd4916fSJason Molenda SBThread
1373008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
13745dd4916fSJason Molenda {
13755dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
13765dd4916fSJason Molenda     Mutex::Locker api_locker;
13775dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13785dd4916fSJason Molenda     SBThread sb_origin_thread;
13795dd4916fSJason Molenda 
13805dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
13815dd4916fSJason Molenda     {
13825dd4916fSJason Molenda         Process::StopLocker stop_locker;
13835dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13845dd4916fSJason Molenda         {
13857a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
13865dd4916fSJason Molenda             if (real_thread)
13875dd4916fSJason Molenda             {
13885dd4916fSJason Molenda                 ConstString type_const (type);
13897a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
13907a2f7904SJason Molenda                 if (process)
13917a2f7904SJason Molenda                 {
13927a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
13935dd4916fSJason Molenda                     if (runtime)
13945dd4916fSJason Molenda                     {
1395008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1396a6e9130dSJason Molenda                         if (new_thread_sp)
1397a6e9130dSJason Molenda                         {
13987a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
13997a2f7904SJason Molenda                             // object.
14007a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
14017a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1402a6e9130dSJason Molenda                             if (log)
1403a6e9130dSJason Molenda                             {
1404a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1405a6e9130dSJason Molenda                                 if (queue_name == NULL)
1406a6e9130dSJason Molenda                                     queue_name = "";
1407324a1036SSaleem Abdulrasool                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1408324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1409324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1410324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1411324a1036SSaleem Abdulrasool                                              queue_name);
1412a6e9130dSJason Molenda                             }
1413a6e9130dSJason Molenda                         }
14147a2f7904SJason Molenda                     }
14155dd4916fSJason Molenda                 }
14165dd4916fSJason Molenda             }
14175dd4916fSJason Molenda         }
14185dd4916fSJason Molenda         else
14195dd4916fSJason Molenda         {
14205dd4916fSJason Molenda             if (log)
1421324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1422324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
14235dd4916fSJason Molenda         }
14245dd4916fSJason Molenda     }
14255dd4916fSJason Molenda 
1426ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1427324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1428324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
14295dd4916fSJason Molenda     return sb_origin_thread;
14305dd4916fSJason Molenda }
14318ee9cb58SJason Molenda 
14328ee9cb58SJason Molenda uint32_t
14338ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
14348ee9cb58SJason Molenda {
14358ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
14368ee9cb58SJason Molenda     if (thread_sp)
14378ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
14388ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
14398ee9cb58SJason Molenda }
1440*b4892cd2SJason Molenda 
1441*b4892cd2SJason Molenda bool
1442*b4892cd2SJason Molenda SBThread::SafeToCallFunctions ()
1443*b4892cd2SJason Molenda {
1444*b4892cd2SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1445*b4892cd2SJason Molenda     if (thread_sp)
1446*b4892cd2SJason Molenda         return thread_sp->SafeToCallFunctions();
1447*b4892cd2SJason Molenda     return true;
1448*b4892cd2SJason Molenda }
1449