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 
104c5de699SEli Friedman #include "lldb/API/SBThread.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
166611103cSGreg Clayton #include "lldb/Core/Debugger.h"
17a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
1930fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
20705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
21a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2393749ab3SZachary Turner #include "lldb/Symbol/SymbolContext.h"
2493749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
255dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h"
2630fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Process.h"
28b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
2993749ab3SZachary Turner #include "lldb/Target/UnixSignals.h"
30f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
3130fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
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"
436a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h"
442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4573ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner using namespace lldb;
4830fdc8d8SChris Lattner using namespace lldb_private;
4930fdc8d8SChris Lattner 
504f465cffSJim Ingham const char *
514f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
524f465cffSJim Ingham {
534f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
544f465cffSJim Ingham }
554f465cffSJim Ingham 
56cfd1acedSGreg Clayton //----------------------------------------------------------------------
57cfd1acedSGreg Clayton // Constructors
58cfd1acedSGreg Clayton //----------------------------------------------------------------------
5930fdc8d8SChris Lattner SBThread::SBThread () :
607fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
6130fdc8d8SChris Lattner {
6230fdc8d8SChris Lattner }
6330fdc8d8SChris Lattner 
6430fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
657fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6630fdc8d8SChris Lattner {
6730fdc8d8SChris Lattner }
6830fdc8d8SChris Lattner 
6992ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
707fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
7130fdc8d8SChris Lattner {
727fdf9ef1SGreg Clayton 
7330fdc8d8SChris Lattner }
7430fdc8d8SChris Lattner 
7530fdc8d8SChris Lattner //----------------------------------------------------------------------
76cfd1acedSGreg Clayton // Assignment operator
77cfd1acedSGreg Clayton //----------------------------------------------------------------------
78cfd1acedSGreg Clayton 
79cfd1acedSGreg Clayton const lldb::SBThread &
80cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
81cfd1acedSGreg Clayton {
82cfd1acedSGreg Clayton     if (this != &rhs)
837fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
84cfd1acedSGreg Clayton     return *this;
85cfd1acedSGreg Clayton }
86cfd1acedSGreg Clayton 
87cfd1acedSGreg Clayton //----------------------------------------------------------------------
8830fdc8d8SChris Lattner // Destructor
8930fdc8d8SChris Lattner //----------------------------------------------------------------------
9030fdc8d8SChris Lattner SBThread::~SBThread()
9130fdc8d8SChris Lattner {
9230fdc8d8SChris Lattner }
9330fdc8d8SChris Lattner 
94b9ffa98cSJason Molenda lldb::SBQueue
95b9ffa98cSJason Molenda SBThread::GetQueue () const
96b9ffa98cSJason Molenda {
97b9ffa98cSJason Molenda     SBQueue sb_queue;
98b9ffa98cSJason Molenda     QueueSP queue_sp;
99b9ffa98cSJason Molenda     Mutex::Locker api_locker;
100b9ffa98cSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
101b9ffa98cSJason Molenda 
102b9ffa98cSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
103b9ffa98cSJason Molenda     if (exe_ctx.HasThreadScope())
104b9ffa98cSJason Molenda     {
105b9ffa98cSJason Molenda         Process::StopLocker stop_locker;
106b9ffa98cSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
107b9ffa98cSJason Molenda         {
108b9ffa98cSJason Molenda             queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
109b9ffa98cSJason Molenda             if (queue_sp)
110b9ffa98cSJason Molenda             {
111b9ffa98cSJason Molenda                 sb_queue.SetQueue (queue_sp);
112b9ffa98cSJason Molenda             }
113b9ffa98cSJason Molenda         }
114b9ffa98cSJason Molenda         else
115b9ffa98cSJason Molenda         {
116b9ffa98cSJason Molenda             if (log)
117358cf1eaSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueue() => error: process is running",
118b9ffa98cSJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
119b9ffa98cSJason Molenda         }
120b9ffa98cSJason Molenda     }
121b9ffa98cSJason Molenda 
122b9ffa98cSJason Molenda     if (log)
123358cf1eaSGreg Clayton         log->Printf ("SBThread(%p)::GetQueue () => SBQueue(%p)",
124b9ffa98cSJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
125b9ffa98cSJason Molenda 
126b9ffa98cSJason Molenda     return sb_queue;
127b9ffa98cSJason Molenda }
128b9ffa98cSJason Molenda 
129b9ffa98cSJason Molenda 
13030fdc8d8SChris Lattner bool
13130fdc8d8SChris Lattner SBThread::IsValid() const
13230fdc8d8SChris Lattner {
1337fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
13430fdc8d8SChris Lattner }
13530fdc8d8SChris Lattner 
13648e42549SGreg Clayton void
13748e42549SGreg Clayton SBThread::Clear ()
13848e42549SGreg Clayton {
1397fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
14048e42549SGreg Clayton }
14148e42549SGreg Clayton 
14248e42549SGreg Clayton 
14330fdc8d8SChris Lattner StopReason
14430fdc8d8SChris Lattner SBThread::GetStopReason()
14530fdc8d8SChris Lattner {
1465160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
147ceb6b139SCaroline Tice 
148ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1494fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1504fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1514fc6cb9cSJim Ingham 
1521ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
15330fdc8d8SChris Lattner     {
1547fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1557fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1567fdf9ef1SGreg Clayton         {
15797d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
15830fdc8d8SChris Lattner         }
159c9858e4dSGreg Clayton         else
160c9858e4dSGreg Clayton         {
161c9858e4dSGreg Clayton             if (log)
162324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
163324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
164c9858e4dSGreg Clayton         }
1657fdf9ef1SGreg Clayton     }
166ceb6b139SCaroline Tice 
167ceb6b139SCaroline Tice     if (log)
168324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
169324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
170750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
171ceb6b139SCaroline Tice 
172ceb6b139SCaroline Tice     return reason;
17330fdc8d8SChris Lattner }
17430fdc8d8SChris Lattner 
17530fdc8d8SChris Lattner size_t
1764e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1774e78f606SGreg Clayton {
1784fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1794fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1804fc6cb9cSJim Ingham 
1811ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1824e78f606SGreg Clayton     {
1837fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1847fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1857fdf9ef1SGreg Clayton         {
1861ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1874e78f606SGreg Clayton             if (stop_info_sp)
1884e78f606SGreg Clayton             {
1894e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1904e78f606SGreg Clayton                 switch (reason)
1914e78f606SGreg Clayton                 {
1924e78f606SGreg Clayton                 case eStopReasonInvalid:
1934e78f606SGreg Clayton                 case eStopReasonNone:
1944e78f606SGreg Clayton                 case eStopReasonTrace:
19590ba8115SGreg Clayton                 case eStopReasonExec:
1964e78f606SGreg Clayton                 case eStopReasonPlanComplete:
197f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
198afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
1994e78f606SGreg Clayton                     // There is no data for these stop reasons.
2004e78f606SGreg Clayton                     return 0;
2014e78f606SGreg Clayton 
2024e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2034e78f606SGreg Clayton                     {
2044e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2051ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2064e78f606SGreg Clayton                         if (bp_site_sp)
2074e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
2084e78f606SGreg Clayton                         else
2094e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
2104e78f606SGreg Clayton                     }
2114e78f606SGreg Clayton                     break;
2124e78f606SGreg Clayton 
2134e78f606SGreg Clayton                 case eStopReasonWatchpoint:
214290fa41bSJohnny Chen                     return 1;
2154e78f606SGreg Clayton 
2164e78f606SGreg Clayton                 case eStopReasonSignal:
2174e78f606SGreg Clayton                     return 1;
2184e78f606SGreg Clayton 
2194e78f606SGreg Clayton                 case eStopReasonException:
2204e78f606SGreg Clayton                     return 1;
2214e78f606SGreg Clayton                 }
2224e78f606SGreg Clayton             }
2234e78f606SGreg Clayton         }
224c9858e4dSGreg Clayton         else
225c9858e4dSGreg Clayton         {
2265160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
227c9858e4dSGreg Clayton             if (log)
228324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
229324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
230c9858e4dSGreg Clayton         }
2317fdf9ef1SGreg Clayton     }
2324e78f606SGreg Clayton     return 0;
2334e78f606SGreg Clayton }
2344e78f606SGreg Clayton 
2354e78f606SGreg Clayton uint64_t
2364e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
2374e78f606SGreg Clayton {
2384fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2394fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2404fc6cb9cSJim Ingham 
2411ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2424e78f606SGreg Clayton     {
2437fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2447fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2457fdf9ef1SGreg Clayton         {
2461ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2471ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2484e78f606SGreg Clayton             if (stop_info_sp)
2494e78f606SGreg Clayton             {
2504e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2514e78f606SGreg Clayton                 switch (reason)
2524e78f606SGreg Clayton                 {
2534e78f606SGreg Clayton                 case eStopReasonInvalid:
2544e78f606SGreg Clayton                 case eStopReasonNone:
2554e78f606SGreg Clayton                 case eStopReasonTrace:
25690ba8115SGreg Clayton                 case eStopReasonExec:
2574e78f606SGreg Clayton                 case eStopReasonPlanComplete:
258f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
259afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2604e78f606SGreg Clayton                     // There is no data for these stop reasons.
2614e78f606SGreg Clayton                     return 0;
2624e78f606SGreg Clayton 
2634e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2644e78f606SGreg Clayton                     {
2654e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2661ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2674e78f606SGreg Clayton                         if (bp_site_sp)
2684e78f606SGreg Clayton                         {
2694e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2704e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2714e78f606SGreg Clayton                             if (bp_loc_sp)
2724e78f606SGreg Clayton                             {
2738334e14eSGreg Clayton                                 if (idx & 1)
2744e78f606SGreg Clayton                                 {
2754e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2764e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2774e78f606SGreg Clayton                                 }
2784e78f606SGreg Clayton                                 else
2794e78f606SGreg Clayton                                 {
2804e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2814e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2824e78f606SGreg Clayton                                 }
2834e78f606SGreg Clayton                             }
2844e78f606SGreg Clayton                         }
2854e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2864e78f606SGreg Clayton                     }
2874e78f606SGreg Clayton                     break;
2884e78f606SGreg Clayton 
2894e78f606SGreg Clayton                 case eStopReasonWatchpoint:
290290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2914e78f606SGreg Clayton 
2924e78f606SGreg Clayton                 case eStopReasonSignal:
2934e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2944e78f606SGreg Clayton 
2954e78f606SGreg Clayton                 case eStopReasonException:
2964e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2974e78f606SGreg Clayton                 }
2984e78f606SGreg Clayton             }
2994e78f606SGreg Clayton         }
300c9858e4dSGreg Clayton         else
301c9858e4dSGreg Clayton         {
3025160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
303c9858e4dSGreg Clayton             if (log)
304324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
305324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
306c9858e4dSGreg Clayton         }
3077fdf9ef1SGreg Clayton     }
3084e78f606SGreg Clayton     return 0;
3094e78f606SGreg Clayton }
3104e78f606SGreg Clayton 
311afdf842bSKuba Brecka bool
312afdf842bSKuba Brecka SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
313afdf842bSKuba Brecka {
314afdf842bSKuba Brecka     Stream &strm = stream.ref();
315afdf842bSKuba Brecka 
316afdf842bSKuba Brecka     ExecutionContext exe_ctx (m_opaque_sp.get());
317afdf842bSKuba Brecka     if (! exe_ctx.HasThreadScope())
318afdf842bSKuba Brecka         return false;
319afdf842bSKuba Brecka 
320afdf842bSKuba Brecka 
321afdf842bSKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
322afdf842bSKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
323afdf842bSKuba Brecka     if (! info)
324afdf842bSKuba Brecka         return false;
325afdf842bSKuba Brecka 
326afdf842bSKuba Brecka     info->Dump(strm);
327afdf842bSKuba Brecka 
328afdf842bSKuba Brecka     return true;
329afdf842bSKuba Brecka }
330afdf842bSKuba Brecka 
3316a831436SKuba Brecka SBThreadCollection
3326a831436SKuba Brecka SBThread::GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type)
3336a831436SKuba Brecka {
3346a831436SKuba Brecka     ThreadCollectionSP threads;
3356a831436SKuba Brecka     threads.reset(new ThreadCollection());
3366a831436SKuba Brecka 
3376a831436SKuba Brecka     // We currently only support ThreadSanitizer.
3386a831436SKuba Brecka     if (type != eInstrumentationRuntimeTypeThreadSanitizer)
3396a831436SKuba Brecka         return threads;
3406a831436SKuba Brecka 
3416a831436SKuba Brecka     ExecutionContext exe_ctx (m_opaque_sp.get());
3426a831436SKuba Brecka     if (! exe_ctx.HasThreadScope())
343*1aad8fb7SKuba Brecka         return threads;
3446a831436SKuba Brecka 
3456a831436SKuba Brecka     ProcessSP process_sp = exe_ctx.GetProcessSP();
3466a831436SKuba Brecka 
3476a831436SKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
3486a831436SKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
3496a831436SKuba Brecka     if (! info)
3506a831436SKuba Brecka         return threads;
3516a831436SKuba Brecka 
352*1aad8fb7SKuba Brecka     return process_sp->GetInstrumentationRuntime(type)->GetBacktracesFromExtendedStopInfo(info);
3536a831436SKuba Brecka }
3546a831436SKuba Brecka 
3554e78f606SGreg Clayton size_t
35630fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
35730fdc8d8SChris Lattner {
3585160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
359ceb6b139SCaroline Tice 
3604fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3614fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3624fc6cb9cSJim Ingham 
3631ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
36430fdc8d8SChris Lattner     {
3657fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3667fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3677fdf9ef1SGreg Clayton         {
3687fdf9ef1SGreg Clayton 
3691ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
370b15bfc75SJim Ingham             if (stop_info_sp)
37130fdc8d8SChris Lattner             {
372b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
37330fdc8d8SChris Lattner                 if (stop_desc)
37430fdc8d8SChris Lattner                 {
375ceb6b139SCaroline Tice                     if (log)
3764838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
377324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
378324a1036SSaleem Abdulrasool                                      stop_desc);
37930fdc8d8SChris Lattner                     if (dst)
38030fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
38130fdc8d8SChris Lattner                     else
38230fdc8d8SChris Lattner                     {
38330fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
38430fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
38530fdc8d8SChris Lattner                     }
38630fdc8d8SChris Lattner                 }
38730fdc8d8SChris Lattner                 else
38830fdc8d8SChris Lattner                 {
38930fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
390b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
39130fdc8d8SChris Lattner                     {
39230fdc8d8SChris Lattner                     case eStopReasonTrace:
39330fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
39430fdc8d8SChris Lattner                         {
39530fdc8d8SChris Lattner                             static char trace_desc[] = "step";
39630fdc8d8SChris Lattner                             stop_desc = trace_desc;
39730fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
39830fdc8d8SChris Lattner                         }
39930fdc8d8SChris Lattner                         break;
40030fdc8d8SChris Lattner 
40130fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
40230fdc8d8SChris Lattner                         {
40330fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
40430fdc8d8SChris Lattner                             stop_desc = bp_desc;
40530fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
40630fdc8d8SChris Lattner                         }
40730fdc8d8SChris Lattner                         break;
40830fdc8d8SChris Lattner 
40930fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
41030fdc8d8SChris Lattner                         {
41130fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
41230fdc8d8SChris Lattner                             stop_desc = wp_desc;
41330fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
41430fdc8d8SChris Lattner                         }
41530fdc8d8SChris Lattner                         break;
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner                     case eStopReasonSignal:
41830fdc8d8SChris Lattner                         {
41998d0a4b3SChaoren Lin                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(stop_info_sp->GetValue());
42030fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
42130fdc8d8SChris Lattner                             {
42230fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
42330fdc8d8SChris Lattner                                 stop_desc = signal_desc;
42430fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
42530fdc8d8SChris Lattner                             }
42630fdc8d8SChris Lattner                         }
42730fdc8d8SChris Lattner                         break;
42830fdc8d8SChris Lattner 
42930fdc8d8SChris Lattner                     case eStopReasonException:
43030fdc8d8SChris Lattner                         {
43130fdc8d8SChris Lattner                             char exc_desc[] = "exception";
43230fdc8d8SChris Lattner                             stop_desc = exc_desc;
43330fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
43430fdc8d8SChris Lattner                         }
43530fdc8d8SChris Lattner                         break;
436c982c768SGreg Clayton 
43790ba8115SGreg Clayton                     case eStopReasonExec:
43890ba8115SGreg Clayton                         {
43990ba8115SGreg Clayton                             char exc_desc[] = "exec";
44090ba8115SGreg Clayton                             stop_desc = exc_desc;
44190ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
44290ba8115SGreg Clayton                         }
44390ba8115SGreg Clayton                         break;
44490ba8115SGreg Clayton 
445f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
446f85defaeSAndrew Kaylor                         {
447f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
448f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
449f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
450f85defaeSAndrew Kaylor                         }
451f85defaeSAndrew Kaylor                         break;
452c982c768SGreg Clayton                     default:
453c982c768SGreg Clayton                         break;
45430fdc8d8SChris Lattner                     }
45530fdc8d8SChris Lattner 
45630fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
45730fdc8d8SChris Lattner                     {
458ceb6b139SCaroline Tice                         if (log)
45993aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
460324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
461324a1036SSaleem Abdulrasool                                          stop_desc);
462ceb6b139SCaroline Tice 
46330fdc8d8SChris Lattner                         if (dst)
46430fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
46530fdc8d8SChris Lattner 
46630fdc8d8SChris Lattner                         if (stop_desc_len == 0)
46730fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
46830fdc8d8SChris Lattner 
46930fdc8d8SChris Lattner                         return stop_desc_len;
47030fdc8d8SChris Lattner                     }
47130fdc8d8SChris Lattner                 }
47230fdc8d8SChris Lattner             }
47330fdc8d8SChris Lattner         }
474c9858e4dSGreg Clayton         else
475c9858e4dSGreg Clayton         {
4765160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
477c9858e4dSGreg Clayton             if (log)
478324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
479324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
480c9858e4dSGreg Clayton         }
4817fdf9ef1SGreg Clayton     }
48230fdc8d8SChris Lattner     if (dst)
48330fdc8d8SChris Lattner         *dst = 0;
48430fdc8d8SChris Lattner     return 0;
48530fdc8d8SChris Lattner }
48630fdc8d8SChris Lattner 
48773ca05a2SJim Ingham SBValue
48873ca05a2SJim Ingham SBThread::GetStopReturnValue ()
48973ca05a2SJim Ingham {
4905160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
49173ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
4924fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4934fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4944fc6cb9cSJim Ingham 
4951ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
49673ca05a2SJim Ingham     {
4977fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4987fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4997fdf9ef1SGreg Clayton         {
5001ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
50173ca05a2SJim Ingham             if (stop_info_sp)
50273ca05a2SJim Ingham             {
50373ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
50473ca05a2SJim Ingham             }
50573ca05a2SJim Ingham         }
506c9858e4dSGreg Clayton         else
507c9858e4dSGreg Clayton         {
508c9858e4dSGreg Clayton             if (log)
509324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
510324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
511c9858e4dSGreg Clayton         }
5127fdf9ef1SGreg Clayton     }
51373ca05a2SJim Ingham 
51473ca05a2SJim Ingham     if (log)
515324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
516324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
51773ca05a2SJim Ingham                      return_valobj_sp.get()
51873ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
51973ca05a2SJim Ingham                         : "<no return value>");
52073ca05a2SJim Ingham 
52173ca05a2SJim Ingham     return SBValue (return_valobj_sp);
52273ca05a2SJim Ingham }
52373ca05a2SJim Ingham 
52430fdc8d8SChris Lattner void
52530fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
52630fdc8d8SChris Lattner {
5277fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
52830fdc8d8SChris Lattner }
52930fdc8d8SChris Lattner 
53030fdc8d8SChris Lattner lldb::tid_t
53130fdc8d8SChris Lattner SBThread::GetThreadID () const
53230fdc8d8SChris Lattner {
5337fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
53417a6ad05SGreg Clayton     if (thread_sp)
5351ac04c30SGreg Clayton         return thread_sp->GetID();
5361ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
53730fdc8d8SChris Lattner }
53830fdc8d8SChris Lattner 
53930fdc8d8SChris Lattner uint32_t
54030fdc8d8SChris Lattner SBThread::GetIndexID () const
54130fdc8d8SChris Lattner {
5427fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
54317a6ad05SGreg Clayton     if (thread_sp)
54417a6ad05SGreg Clayton         return thread_sp->GetIndexID();
54530fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
54630fdc8d8SChris Lattner }
5471ac04c30SGreg Clayton 
54830fdc8d8SChris Lattner const char *
54930fdc8d8SChris Lattner SBThread::GetName () const
55030fdc8d8SChris Lattner {
5515160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5524838131bSGreg Clayton     const char *name = NULL;
5534fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5544fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5554fc6cb9cSJim Ingham 
5561ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
557af67cecdSGreg Clayton     {
5587fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5597fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5607fdf9ef1SGreg Clayton         {
5611ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
562af67cecdSGreg Clayton         }
563c9858e4dSGreg Clayton         else
564c9858e4dSGreg Clayton         {
565c9858e4dSGreg Clayton             if (log)
566324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
567324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
568c9858e4dSGreg Clayton         }
5697fdf9ef1SGreg Clayton     }
570ceb6b139SCaroline Tice 
571ceb6b139SCaroline Tice     if (log)
572324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
573324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
574324a1036SSaleem Abdulrasool                      name ? name : "NULL");
575ceb6b139SCaroline Tice 
5764838131bSGreg Clayton     return name;
57730fdc8d8SChris Lattner }
57830fdc8d8SChris Lattner 
57930fdc8d8SChris Lattner const char *
58030fdc8d8SChris Lattner SBThread::GetQueueName () const
58130fdc8d8SChris Lattner {
5824838131bSGreg Clayton     const char *name = NULL;
5834fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5844fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5854fc6cb9cSJim Ingham 
5865160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5871ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
588af67cecdSGreg Clayton     {
5897fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5907fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5917fdf9ef1SGreg Clayton         {
5921ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
593af67cecdSGreg Clayton         }
594c9858e4dSGreg Clayton         else
595c9858e4dSGreg Clayton         {
596c9858e4dSGreg Clayton             if (log)
597324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
598324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
599c9858e4dSGreg Clayton         }
6007fdf9ef1SGreg Clayton     }
601ceb6b139SCaroline Tice 
602ceb6b139SCaroline Tice     if (log)
603324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
604324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
605324a1036SSaleem Abdulrasool                      name ? name : "NULL");
606ceb6b139SCaroline Tice 
6074838131bSGreg Clayton     return name;
60830fdc8d8SChris Lattner }
60930fdc8d8SChris Lattner 
6104fdb5863SJason Molenda lldb::queue_id_t
6114fdb5863SJason Molenda SBThread::GetQueueID () const
6124fdb5863SJason Molenda {
6134fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
6144fdb5863SJason Molenda     Mutex::Locker api_locker;
6154fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6164fdb5863SJason Molenda 
6174fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
6184fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
6194fdb5863SJason Molenda     {
6204fdb5863SJason Molenda         Process::StopLocker stop_locker;
6214fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
6224fdb5863SJason Molenda         {
6234fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
6244fdb5863SJason Molenda         }
6254fdb5863SJason Molenda         else
6264fdb5863SJason Molenda         {
6274fdb5863SJason Molenda             if (log)
628324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
629324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
6304fdb5863SJason Molenda         }
6314fdb5863SJason Molenda     }
6324fdb5863SJason Molenda 
6334fdb5863SJason Molenda     if (log)
634324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
635324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
6364fdb5863SJason Molenda 
6374fdb5863SJason Molenda     return id;
6384fdb5863SJason Molenda }
6394fdb5863SJason Molenda 
640705b1809SJason Molenda bool
641705b1809SJason Molenda SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
642705b1809SJason Molenda {
643705b1809SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
644705b1809SJason Molenda     bool success = false;
645705b1809SJason Molenda     Mutex::Locker api_locker;
646705b1809SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
647705b1809SJason Molenda 
648705b1809SJason Molenda     if (exe_ctx.HasThreadScope())
649705b1809SJason Molenda     {
650705b1809SJason Molenda         Process::StopLocker stop_locker;
651705b1809SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
652705b1809SJason Molenda         {
653705b1809SJason Molenda             Thread *thread = exe_ctx.GetThreadPtr();
654705b1809SJason Molenda             StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
655705b1809SJason Molenda             if (info_root_sp)
656705b1809SJason Molenda             {
657705b1809SJason Molenda                 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path);
658705b1809SJason Molenda                 if (node)
659705b1809SJason Molenda                 {
660705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeString)
661705b1809SJason Molenda                     {
662705b1809SJason Molenda                         strm.Printf ("%s", node->GetAsString()->GetValue().c_str());
663705b1809SJason Molenda                         success = true;
664705b1809SJason Molenda                     }
665705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeInteger)
666705b1809SJason Molenda                     {
667705b1809SJason Molenda                         strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue());
668705b1809SJason Molenda                         success = true;
669705b1809SJason Molenda                     }
670705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeFloat)
671705b1809SJason Molenda                     {
672705b1809SJason Molenda                         strm.Printf ("0x%f", node->GetAsFloat()->GetValue());
673705b1809SJason Molenda                         success = true;
674705b1809SJason Molenda                     }
675705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeBoolean)
676705b1809SJason Molenda                     {
677705b1809SJason Molenda                         if (node->GetAsBoolean()->GetValue() == true)
678705b1809SJason Molenda                             strm.Printf ("true");
679705b1809SJason Molenda                         else
680705b1809SJason Molenda                             strm.Printf ("false");
681705b1809SJason Molenda                         success = true;
682705b1809SJason Molenda                     }
683705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeNull)
684705b1809SJason Molenda                     {
685705b1809SJason Molenda                         strm.Printf ("null");
686705b1809SJason Molenda                         success = true;
687705b1809SJason Molenda                     }
688705b1809SJason Molenda                 }
689705b1809SJason Molenda             }
690705b1809SJason Molenda         }
691705b1809SJason Molenda         else
692705b1809SJason Molenda         {
693705b1809SJason Molenda             if (log)
694705b1809SJason Molenda                 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running",
695705b1809SJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
696705b1809SJason Molenda         }
697705b1809SJason Molenda     }
698705b1809SJason Molenda 
699705b1809SJason Molenda     if (log)
700705b1809SJason Molenda         log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s",
701705b1809SJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()),
702705b1809SJason Molenda                      strm.GetData());
703705b1809SJason Molenda 
704705b1809SJason Molenda     return success;
705705b1809SJason Molenda }
706705b1809SJason Molenda 
707705b1809SJason Molenda 
70864e7ead1SJim Ingham SBError
70964e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
71064e7ead1SJim Ingham {
71164e7ead1SJim Ingham     SBError sb_error;
71264e7ead1SJim Ingham 
71364e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
71464e7ead1SJim Ingham     if (!process)
71564e7ead1SJim Ingham     {
71664e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
71764e7ead1SJim Ingham         return sb_error;
71864e7ead1SJim Ingham     }
71964e7ead1SJim Ingham 
72064e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
72164e7ead1SJim Ingham     if (!thread)
72264e7ead1SJim Ingham     {
72364e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
72464e7ead1SJim Ingham         return sb_error;
72564e7ead1SJim Ingham     }
72664e7ead1SJim Ingham 
72764e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
72864e7ead1SJim Ingham     // then a "continue" will resume the plan.
72964e7ead1SJim Ingham     if (new_plan != NULL)
73064e7ead1SJim Ingham     {
73164e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
73264e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
73364e7ead1SJim Ingham     }
73464e7ead1SJim Ingham 
73564e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
73664e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
73764e7ead1SJim Ingham 
738dc6224e0SGreg Clayton     if (process->GetTarget().GetDebugger().GetAsyncExecution ())
739dc6224e0SGreg Clayton         sb_error.ref() = process->Resume ();
740dc6224e0SGreg Clayton     else
741dc6224e0SGreg Clayton         sb_error.ref() = process->ResumeSynchronous (NULL);
74264e7ead1SJim Ingham 
74364e7ead1SJim Ingham     return sb_error;
74464e7ead1SJim Ingham }
74530fdc8d8SChris Lattner 
74630fdc8d8SChris Lattner void
74730fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
74830fdc8d8SChris Lattner {
7495160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
750ceb6b139SCaroline Tice 
7514fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7524fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7534fc6cb9cSJim Ingham 
75417a6ad05SGreg Clayton 
755ceb6b139SCaroline Tice     if (log)
756324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
757324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
758ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
759ceb6b139SCaroline Tice 
7601ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
76130fdc8d8SChris Lattner     {
7621ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7637ba6e991SJim Ingham         bool abort_other_plans = false;
764b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
76530fdc8d8SChris Lattner 
7664d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
76730fdc8d8SChris Lattner         if (frame_sp)
76830fdc8d8SChris Lattner         {
76930fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
77030fdc8d8SChris Lattner             {
7714b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
77230fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
7734d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
77425d5b10bSJason Molenda                                                                     sc.line_entry,
77530fdc8d8SChris Lattner                                                                     sc,
7764b4b2478SJim Ingham                                                                     stop_other_threads,
7774b4b2478SJim Ingham                                                                     avoid_no_debug);
77830fdc8d8SChris Lattner             }
77930fdc8d8SChris Lattner             else
78030fdc8d8SChris Lattner             {
7814d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
78230fdc8d8SChris Lattner                                                                                abort_other_plans,
78330fdc8d8SChris Lattner                                                                                stop_other_threads);
78430fdc8d8SChris Lattner             }
78530fdc8d8SChris Lattner         }
78630fdc8d8SChris Lattner 
78764e7ead1SJim Ingham         // This returns an error, we should use it!
7884d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
78930fdc8d8SChris Lattner     }
79030fdc8d8SChris Lattner }
79130fdc8d8SChris Lattner 
79230fdc8d8SChris Lattner void
79330fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
79430fdc8d8SChris Lattner {
795c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
796c627682eSJim Ingham }
797c627682eSJim Ingham 
798c627682eSJim Ingham void
799c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
800c627682eSJim Ingham {
801cbf6f9b2SJim Ingham     SBError error;
802cbf6f9b2SJim Ingham     StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
803cbf6f9b2SJim Ingham }
804cbf6f9b2SJim Ingham 
805cbf6f9b2SJim Ingham void
806cbf6f9b2SJim Ingham SBThread::StepInto (const char *target_name, uint32_t end_line, SBError &error, lldb::RunMode stop_other_threads)
807cbf6f9b2SJim Ingham {
8085160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
809ceb6b139SCaroline Tice 
8104fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8114fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
81217a6ad05SGreg Clayton 
81317a6ad05SGreg Clayton     if (log)
814c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
815324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
816c627682eSJim Ingham                      target_name? target_name: "<NULL>",
81717a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
818c627682eSJim Ingham 
8191ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
82030fdc8d8SChris Lattner     {
8217ba6e991SJim Ingham         bool abort_other_plans = false;
82230fdc8d8SChris Lattner 
8231ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
824b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
8254d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
82630fdc8d8SChris Lattner 
82730fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
82830fdc8d8SChris Lattner         {
829cbf6f9b2SJim Ingham             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
830cbf6f9b2SJim Ingham             AddressRange range;
831cbf6f9b2SJim Ingham             if (end_line == LLDB_INVALID_LINE_NUMBER)
832cbf6f9b2SJim Ingham                 range = sc.line_entry.range;
833cbf6f9b2SJim Ingham             else
834cbf6f9b2SJim Ingham             {
835cbf6f9b2SJim Ingham                 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
836cbf6f9b2SJim Ingham                     return;
837cbf6f9b2SJim Ingham             }
838cbf6f9b2SJim Ingham 
8394b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
8404b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
8414d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
842cbf6f9b2SJim Ingham                                                               range,
84330fdc8d8SChris Lattner                                                               sc,
844c627682eSJim Ingham                                                               target_name,
845474966a4SGreg Clayton                                                               stop_other_threads,
8464b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
8474b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
84830fdc8d8SChris Lattner         }
84930fdc8d8SChris Lattner         else
85030fdc8d8SChris Lattner         {
8514d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
85230fdc8d8SChris Lattner                                                                            abort_other_plans,
85330fdc8d8SChris Lattner                                                                            stop_other_threads);
85430fdc8d8SChris Lattner         }
85530fdc8d8SChris Lattner 
856cbf6f9b2SJim Ingham         error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
85730fdc8d8SChris Lattner     }
85830fdc8d8SChris Lattner }
85930fdc8d8SChris Lattner 
86030fdc8d8SChris Lattner void
86130fdc8d8SChris Lattner SBThread::StepOut ()
86230fdc8d8SChris Lattner {
8635160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
864ceb6b139SCaroline Tice 
8654fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8664fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8674fc6cb9cSJim Ingham 
86817a6ad05SGreg Clayton     if (log)
869324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
870324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
87117a6ad05SGreg Clayton 
8721ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
87330fdc8d8SChris Lattner     {
8747ba6e991SJim Ingham         bool abort_other_plans = false;
87594b09246SJim Ingham         bool stop_other_threads = false;
87630fdc8d8SChris Lattner 
8771ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8781ac04c30SGreg Clayton 
8794b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
8804d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
881481cef25SGreg Clayton                                                                     NULL,
882481cef25SGreg Clayton                                                                     false,
883481cef25SGreg Clayton                                                                     stop_other_threads,
884481cef25SGreg Clayton                                                                     eVoteYes,
885481cef25SGreg Clayton                                                                     eVoteNoOpinion,
8864b4b2478SJim Ingham                                                                     0,
8874b4b2478SJim Ingham                                                                     avoid_no_debug));
888481cef25SGreg Clayton 
88964e7ead1SJim Ingham         // This returns an error, we should use it!
8904d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
891481cef25SGreg Clayton     }
892481cef25SGreg Clayton }
893481cef25SGreg Clayton 
894481cef25SGreg Clayton void
895481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
896481cef25SGreg Clayton {
8975160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
898481cef25SGreg Clayton 
8994fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9004fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9014fc6cb9cSJim Ingham 
902989a7558SJim Ingham     if (!sb_frame.IsValid())
903989a7558SJim Ingham     {
904989a7558SJim Ingham         if (log)
905989a7558SJim Ingham             log->Printf("SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
906989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()));
907989a7558SJim Ingham         return;
908989a7558SJim Ingham     }
909989a7558SJim Ingham 
910b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
911481cef25SGreg Clayton     if (log)
912481cef25SGreg Clayton     {
913481cef25SGreg Clayton         SBStream frame_desc_strm;
914481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
915324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
916324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
917324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
918324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
919481cef25SGreg Clayton     }
920481cef25SGreg Clayton 
9211ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
922481cef25SGreg Clayton     {
9237ba6e991SJim Ingham         bool abort_other_plans = false;
92494b09246SJim Ingham         bool stop_other_threads = false;
9251ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
926989a7558SJim Ingham         if (sb_frame.GetThread().GetThreadID() != thread->GetID())
927989a7558SJim Ingham         {
9281ef6e4c8SBruce Mitchener             log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
929989a7558SJim Ingham                         static_cast<void*>(exe_ctx.GetThreadPtr()),
930989a7558SJim Ingham                         sb_frame.GetThread().GetThreadID(),
931989a7558SJim Ingham                         thread->GetID());
932989a7558SJim Ingham         }
933481cef25SGreg Clayton 
9344d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
935481cef25SGreg Clayton                                                                     NULL,
936481cef25SGreg Clayton                                                                     false,
937481cef25SGreg Clayton                                                                     stop_other_threads,
938481cef25SGreg Clayton                                                                     eVoteYes,
939481cef25SGreg Clayton                                                                     eVoteNoOpinion,
9404d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
94130fdc8d8SChris Lattner 
94264e7ead1SJim Ingham         // This returns an error, we should use it!
9434d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
94430fdc8d8SChris Lattner     }
94530fdc8d8SChris Lattner }
94630fdc8d8SChris Lattner 
94730fdc8d8SChris Lattner void
94830fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
94930fdc8d8SChris Lattner {
9505160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
951ceb6b139SCaroline Tice 
9524fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9534fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9544fc6cb9cSJim Ingham 
9551ac04c30SGreg Clayton 
956ceb6b139SCaroline Tice 
95717a6ad05SGreg Clayton     if (log)
958324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
959324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
96017a6ad05SGreg Clayton 
9611ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
96230fdc8d8SChris Lattner     {
9631ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9644d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
96564e7ead1SJim Ingham 
96664e7ead1SJim Ingham         // This returns an error, we should use it!
9674d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
96830fdc8d8SChris Lattner     }
96930fdc8d8SChris Lattner }
97030fdc8d8SChris Lattner 
97130fdc8d8SChris Lattner void
97230fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
97330fdc8d8SChris Lattner {
9745160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
975ceb6b139SCaroline Tice 
9764fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9774fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9784fc6cb9cSJim Ingham 
979ceb6b139SCaroline Tice 
98017a6ad05SGreg Clayton     if (log)
981324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
982324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
98317a6ad05SGreg Clayton 
9841ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
98530fdc8d8SChris Lattner     {
9867ba6e991SJim Ingham         bool abort_other_plans = false;
98730fdc8d8SChris Lattner         bool stop_other_threads = true;
98830fdc8d8SChris Lattner 
989e72dfb32SGreg Clayton         Address target_addr (addr);
99030fdc8d8SChris Lattner 
9911ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9921ac04c30SGreg Clayton 
9932bdbfd50SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
9942bdbfd50SJim Ingham                                                                          target_addr,
9952bdbfd50SJim Ingham                                                                          stop_other_threads));
99664e7ead1SJim Ingham 
99764e7ead1SJim Ingham         // This returns an error, we should use it!
9984d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
99930fdc8d8SChris Lattner     }
100030fdc8d8SChris Lattner }
100130fdc8d8SChris Lattner 
1002481cef25SGreg Clayton SBError
1003481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
1004481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
1005481cef25SGreg Clayton                          uint32_t line)
1006481cef25SGreg Clayton {
1007481cef25SGreg Clayton     SBError sb_error;
10085160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1009481cef25SGreg Clayton     char path[PATH_MAX];
1010481cef25SGreg Clayton 
10114fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10124fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10134fc6cb9cSJim Ingham 
1014b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
101517a6ad05SGreg Clayton 
1016481cef25SGreg Clayton     if (log)
1017481cef25SGreg Clayton     {
1018481cef25SGreg Clayton         SBStream frame_desc_strm;
1019481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1020481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
1021481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
1022324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1023324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1024324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
1025481cef25SGreg Clayton     }
1026481cef25SGreg Clayton 
10271ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1028481cef25SGreg Clayton     {
10291ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
10301ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
1031481cef25SGreg Clayton 
1032481cef25SGreg Clayton         if (line == 0)
1033481cef25SGreg Clayton         {
1034481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
1035481cef25SGreg Clayton             return sb_error;
1036481cef25SGreg Clayton         }
1037481cef25SGreg Clayton 
1038b9556accSGreg Clayton         if (!frame_sp)
1039481cef25SGreg Clayton         {
10401ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
1041481cef25SGreg Clayton             if (!frame_sp)
10421ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
1043481cef25SGreg Clayton         }
1044481cef25SGreg Clayton 
1045481cef25SGreg Clayton         SymbolContext frame_sc;
1046481cef25SGreg Clayton         if (!frame_sp)
1047481cef25SGreg Clayton         {
1048481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
1049481cef25SGreg Clayton             return sb_error;
1050481cef25SGreg Clayton         }
1051481cef25SGreg Clayton 
1052481cef25SGreg Clayton         // If we have a frame, get its line
1053481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1054481cef25SGreg Clayton                                                eSymbolContextFunction  |
1055481cef25SGreg Clayton                                                eSymbolContextLineEntry |
1056481cef25SGreg Clayton                                                eSymbolContextSymbol    );
1057481cef25SGreg Clayton 
1058481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
1059481cef25SGreg Clayton         {
1060481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1061481cef25SGreg Clayton             return sb_error;
1062481cef25SGreg Clayton         }
1063481cef25SGreg Clayton 
1064481cef25SGreg Clayton         FileSpec step_file_spec;
1065481cef25SGreg Clayton         if (sb_file_spec.IsValid())
1066481cef25SGreg Clayton         {
1067481cef25SGreg Clayton             // The file spec passed in was valid, so use it
1068481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
1069481cef25SGreg Clayton         }
1070481cef25SGreg Clayton         else
1071481cef25SGreg Clayton         {
1072481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
1073481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
1074481cef25SGreg Clayton             else
1075481cef25SGreg Clayton             {
1076481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
1077481cef25SGreg Clayton                 return sb_error;
1078481cef25SGreg Clayton             }
1079481cef25SGreg Clayton         }
1080481cef25SGreg Clayton 
10819b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
10829b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
10839b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
10849b70ddb3SJim Ingham         // error message.
10859b70ddb3SJim Ingham 
10869b70ddb3SJim Ingham         bool all_in_function = true;
10879b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
10889b70ddb3SJim Ingham 
1089481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
10907ba6e991SJim Ingham         const bool abort_other_plans = false;
1091c02e3344SJim Ingham         const bool stop_other_threads = false;
1092481cef25SGreg Clayton         const bool check_inlines = true;
1093481cef25SGreg Clayton         const bool exact = false;
1094481cef25SGreg Clayton 
1095481cef25SGreg Clayton         SymbolContextList sc_list;
10969b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
10979b70ddb3SJim Ingham                                                                                line,
10989b70ddb3SJim Ingham                                                                                check_inlines,
10999b70ddb3SJim Ingham                                                                                exact,
11009b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
11019b70ddb3SJim Ingham                                                                                sc_list);
1102481cef25SGreg Clayton         if (num_matches > 0)
1103481cef25SGreg Clayton         {
1104481cef25SGreg Clayton             SymbolContext sc;
1105481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
1106481cef25SGreg Clayton             {
1107481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
1108481cef25SGreg Clayton                 {
11099b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1110481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
1111481cef25SGreg Clayton                     {
11129b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
1113481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
11149b70ddb3SJim Ingham                         else
11159b70ddb3SJim Ingham                             all_in_function = false;
1116481cef25SGreg Clayton                     }
1117481cef25SGreg Clayton                 }
1118481cef25SGreg Clayton             }
1119481cef25SGreg Clayton         }
1120481cef25SGreg Clayton 
1121481cef25SGreg Clayton         if (step_over_until_addrs.empty())
1122481cef25SGreg Clayton         {
11239b70ddb3SJim Ingham             if (all_in_function)
11249b70ddb3SJim Ingham             {
1125481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
1126fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1127481cef25SGreg Clayton             }
1128481cef25SGreg Clayton             else
112986edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
11309b70ddb3SJim Ingham         }
11319b70ddb3SJim Ingham         else
1132481cef25SGreg Clayton         {
11334d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1134481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
1135481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
1136481cef25SGreg Clayton                                                                         stop_other_threads,
11374d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
1138481cef25SGreg Clayton 
11394d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1140481cef25SGreg Clayton         }
1141481cef25SGreg Clayton     }
1142481cef25SGreg Clayton     else
1143481cef25SGreg Clayton     {
1144481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
1145481cef25SGreg Clayton     }
1146481cef25SGreg Clayton     return sb_error;
1147481cef25SGreg Clayton }
1148481cef25SGreg Clayton 
11494413758cSJim Ingham SBError
11502bdbfd50SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
11512bdbfd50SJim Ingham {
11522bdbfd50SJim Ingham     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11532bdbfd50SJim Ingham     SBError sb_error;
11542bdbfd50SJim Ingham 
11552bdbfd50SJim Ingham     Mutex::Locker api_locker;
11562bdbfd50SJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11572bdbfd50SJim Ingham 
11582bdbfd50SJim Ingham     if (log)
11592bdbfd50SJim Ingham     {
11602bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
11612bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11622bdbfd50SJim Ingham                      script_class_name);
11632bdbfd50SJim Ingham     }
11642bdbfd50SJim Ingham 
11652bdbfd50SJim Ingham 
11662bdbfd50SJim Ingham     if (!exe_ctx.HasThreadScope())
11672bdbfd50SJim Ingham     {
11682bdbfd50SJim Ingham         sb_error.SetErrorString("this SBThread object is invalid");
11692bdbfd50SJim Ingham         return sb_error;
11702bdbfd50SJim Ingham     }
11712bdbfd50SJim Ingham 
11722bdbfd50SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11732bdbfd50SJim Ingham     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
11742bdbfd50SJim Ingham 
11752bdbfd50SJim Ingham     if (thread_plan_sp)
11762bdbfd50SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
11772bdbfd50SJim Ingham     else
11782bdbfd50SJim Ingham     {
11792bdbfd50SJim Ingham         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
11802bdbfd50SJim Ingham         if (log)
11812bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
11822bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11832bdbfd50SJim Ingham                      script_class_name);
11842bdbfd50SJim Ingham     }
11852bdbfd50SJim Ingham 
11862bdbfd50SJim Ingham     return sb_error;
11872bdbfd50SJim Ingham }
11882bdbfd50SJim Ingham 
11892bdbfd50SJim Ingham SBError
1190f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1191f86248d9SRichard Mitton {
1192f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1193f86248d9SRichard Mitton     SBError sb_error;
1194f86248d9SRichard Mitton 
1195f86248d9SRichard Mitton     Mutex::Locker api_locker;
1196f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1197f86248d9SRichard Mitton 
1198f86248d9SRichard Mitton     if (log)
1199324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1200324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1201324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
1202f86248d9SRichard Mitton 
1203f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
1204f86248d9SRichard Mitton     {
1205f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
1206f86248d9SRichard Mitton         return sb_error;
1207f86248d9SRichard Mitton     }
1208f86248d9SRichard Mitton 
1209f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
1210f86248d9SRichard Mitton 
1211f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
1212f86248d9SRichard Mitton     sb_error.SetError (err);
1213f86248d9SRichard Mitton     return sb_error;
1214f86248d9SRichard Mitton }
1215f86248d9SRichard Mitton 
1216f86248d9SRichard Mitton SBError
1217cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
12184413758cSJim Ingham {
12194413758cSJim Ingham     SBError sb_error;
12204413758cSJim Ingham 
12215160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12224413758cSJim Ingham 
12234413758cSJim Ingham     Mutex::Locker api_locker;
12244413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12254413758cSJim Ingham 
12264413758cSJim Ingham 
12274413758cSJim Ingham     if (log)
1228324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1229324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1230324a1036SSaleem Abdulrasool                      frame.GetFrameID());
12314413758cSJim Ingham 
12324413758cSJim Ingham     if (exe_ctx.HasThreadScope())
12334413758cSJim Ingham     {
12344413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1235cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
12364413758cSJim Ingham     }
12374413758cSJim Ingham 
12384413758cSJim Ingham     return sb_error;
12394413758cSJim Ingham }
12404413758cSJim Ingham 
1241481cef25SGreg Clayton 
1242722a0cdcSGreg Clayton bool
1243722a0cdcSGreg Clayton SBThread::Suspend()
1244722a0cdcSGreg Clayton {
12455160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12467fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1247c9858e4dSGreg Clayton     bool result = false;
12481ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1249722a0cdcSGreg Clayton     {
1250c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1251c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1252c9858e4dSGreg Clayton         {
12531ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1254c9858e4dSGreg Clayton             result = true;
1255722a0cdcSGreg Clayton         }
1256c9858e4dSGreg Clayton         else
1257c9858e4dSGreg Clayton         {
1258c9858e4dSGreg Clayton             if (log)
1259324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1260324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1261c9858e4dSGreg Clayton         }
1262c9858e4dSGreg Clayton     }
1263c9858e4dSGreg Clayton     if (log)
1264324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1265324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1266c9858e4dSGreg Clayton     return result;
1267722a0cdcSGreg Clayton }
1268722a0cdcSGreg Clayton 
1269722a0cdcSGreg Clayton bool
1270722a0cdcSGreg Clayton SBThread::Resume ()
1271722a0cdcSGreg Clayton {
12725160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12737fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1274c9858e4dSGreg Clayton     bool result = false;
12751ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1276722a0cdcSGreg Clayton     {
1277c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1278c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1279c9858e4dSGreg Clayton         {
12806c9ed91cSJim Ingham             const bool override_suspend = true;
12816c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1282c9858e4dSGreg Clayton             result = true;
1283722a0cdcSGreg Clayton         }
1284c9858e4dSGreg Clayton         else
1285c9858e4dSGreg Clayton         {
1286c9858e4dSGreg Clayton             if (log)
1287324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1288324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1289c9858e4dSGreg Clayton         }
1290c9858e4dSGreg Clayton     }
1291c9858e4dSGreg Clayton     if (log)
1292324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1293324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1294c9858e4dSGreg Clayton     return result;
1295722a0cdcSGreg Clayton }
1296722a0cdcSGreg Clayton 
1297722a0cdcSGreg Clayton bool
1298722a0cdcSGreg Clayton SBThread::IsSuspended()
1299722a0cdcSGreg Clayton {
13007fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13011ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
13021ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1303722a0cdcSGreg Clayton     return false;
1304722a0cdcSGreg Clayton }
1305722a0cdcSGreg Clayton 
1306a75418dbSAndrew Kaylor bool
1307a75418dbSAndrew Kaylor SBThread::IsStopped()
1308a75418dbSAndrew Kaylor {
1309a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1310a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1311a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1312a75418dbSAndrew Kaylor     return false;
1313a75418dbSAndrew Kaylor }
1314a75418dbSAndrew Kaylor 
131530fdc8d8SChris Lattner SBProcess
131630fdc8d8SChris Lattner SBThread::GetProcess ()
131730fdc8d8SChris Lattner {
1318b9556accSGreg Clayton     SBProcess sb_process;
13197fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
132130fdc8d8SChris Lattner     {
132230fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
13231ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
132430fdc8d8SChris Lattner     }
1325ceb6b139SCaroline Tice 
13265160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1327ceb6b139SCaroline Tice     if (log)
1328ceb6b139SCaroline Tice     {
1329481cef25SGreg Clayton         SBStream frame_desc_strm;
1330b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1331324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1332324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1333324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1334324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1335ceb6b139SCaroline Tice     }
1336ceb6b139SCaroline Tice 
1337b9556accSGreg Clayton     return sb_process;
133830fdc8d8SChris Lattner }
133930fdc8d8SChris Lattner 
134030fdc8d8SChris Lattner uint32_t
134130fdc8d8SChris Lattner SBThread::GetNumFrames ()
134230fdc8d8SChris Lattner {
13435160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1344ceb6b139SCaroline Tice 
1345ceb6b139SCaroline Tice     uint32_t num_frames = 0;
13464fc6cb9cSJim Ingham     Mutex::Locker api_locker;
13474fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13484fc6cb9cSJim Ingham 
13491ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1350af67cecdSGreg Clayton     {
13517fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13527fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13537fdf9ef1SGreg Clayton         {
13541ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1355af67cecdSGreg Clayton         }
1356c9858e4dSGreg Clayton         else
1357c9858e4dSGreg Clayton         {
1358c9858e4dSGreg Clayton             if (log)
1359324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1360324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1361c9858e4dSGreg Clayton         }
13627fdf9ef1SGreg Clayton     }
1363ceb6b139SCaroline Tice 
1364ceb6b139SCaroline Tice     if (log)
1365324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1366324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1367ceb6b139SCaroline Tice 
1368ceb6b139SCaroline Tice     return num_frames;
136930fdc8d8SChris Lattner }
137030fdc8d8SChris Lattner 
137130fdc8d8SChris Lattner SBFrame
137230fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
137330fdc8d8SChris Lattner {
13745160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1375ceb6b139SCaroline Tice 
137630fdc8d8SChris Lattner     SBFrame sb_frame;
1377b57e4a1bSJason Molenda     StackFrameSP frame_sp;
13784fc6cb9cSJim Ingham     Mutex::Locker api_locker;
13794fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13804fc6cb9cSJim Ingham 
13811ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1382af67cecdSGreg Clayton     {
13837fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13847fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13857fdf9ef1SGreg Clayton         {
13861ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1387b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1388af67cecdSGreg Clayton         }
1389c9858e4dSGreg Clayton         else
1390c9858e4dSGreg Clayton         {
1391c9858e4dSGreg Clayton             if (log)
1392324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1393324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1394c9858e4dSGreg Clayton         }
13957fdf9ef1SGreg Clayton     }
1396ceb6b139SCaroline Tice 
1397ceb6b139SCaroline Tice     if (log)
1398ceb6b139SCaroline Tice     {
1399481cef25SGreg Clayton         SBStream frame_desc_strm;
1400481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
14014838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1402324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1403324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1404324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1405ceb6b139SCaroline Tice     }
1406ceb6b139SCaroline Tice 
140730fdc8d8SChris Lattner     return sb_frame;
140830fdc8d8SChris Lattner }
140930fdc8d8SChris Lattner 
1410f028a1fbSGreg Clayton lldb::SBFrame
1411f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1412f028a1fbSGreg Clayton {
14135160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1414f028a1fbSGreg Clayton 
1415f028a1fbSGreg Clayton     SBFrame sb_frame;
1416b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14174fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14184fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14194fc6cb9cSJim Ingham 
14201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1421af67cecdSGreg Clayton     {
14227fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14237fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14247fdf9ef1SGreg Clayton         {
14251ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1426b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1427af67cecdSGreg Clayton         }
1428c9858e4dSGreg Clayton         else
1429c9858e4dSGreg Clayton         {
1430c9858e4dSGreg Clayton             if (log)
1431324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1432324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1433c9858e4dSGreg Clayton         }
14347fdf9ef1SGreg Clayton     }
1435f028a1fbSGreg Clayton 
1436f028a1fbSGreg Clayton     if (log)
1437f028a1fbSGreg Clayton     {
1438481cef25SGreg Clayton         SBStream frame_desc_strm;
1439481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1440f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1441324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1442324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1443324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1444f028a1fbSGreg Clayton     }
1445f028a1fbSGreg Clayton 
1446f028a1fbSGreg Clayton     return sb_frame;
1447f028a1fbSGreg Clayton }
1448f028a1fbSGreg Clayton 
1449f028a1fbSGreg Clayton lldb::SBFrame
1450f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1451f028a1fbSGreg Clayton {
14525160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1453f028a1fbSGreg Clayton 
1454f028a1fbSGreg Clayton     SBFrame sb_frame;
1455b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14564fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14574fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14584fc6cb9cSJim Ingham 
14591ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1460f028a1fbSGreg Clayton     {
14617fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14627fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14637fdf9ef1SGreg Clayton         {
14641ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
14651ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1466f028a1fbSGreg Clayton             if (frame_sp)
1467f028a1fbSGreg Clayton             {
14681ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1469b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1470f028a1fbSGreg Clayton             }
1471f028a1fbSGreg Clayton         }
1472c9858e4dSGreg Clayton         else
1473c9858e4dSGreg Clayton         {
1474c9858e4dSGreg Clayton             if (log)
1475324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1476324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1477c9858e4dSGreg Clayton         }
14787fdf9ef1SGreg Clayton     }
1479f028a1fbSGreg Clayton 
1480f028a1fbSGreg Clayton     if (log)
1481f028a1fbSGreg Clayton     {
1482481cef25SGreg Clayton         SBStream frame_desc_strm;
1483481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1484f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1485324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1486324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1487324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1488f028a1fbSGreg Clayton     }
1489f028a1fbSGreg Clayton     return sb_frame;
1490f028a1fbSGreg Clayton }
1491f028a1fbSGreg Clayton 
14924f465cffSJim Ingham bool
14934f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
14944f465cffSJim Ingham {
14954f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
14964f465cffSJim Ingham }
14974f465cffSJim Ingham 
14984f465cffSJim Ingham SBFrame
14994f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
15004f465cffSJim Ingham {
15014f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
15024f465cffSJim Ingham 
15034f465cffSJim Ingham }
15044f465cffSJim Ingham 
15054f465cffSJim Ingham SBThread
15064f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
15074f465cffSJim Ingham {
15084f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
15094f465cffSJim Ingham }
1510f028a1fbSGreg Clayton 
151130fdc8d8SChris Lattner bool
151230fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
151330fdc8d8SChris Lattner {
15147fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
151530fdc8d8SChris Lattner }
151630fdc8d8SChris Lattner 
151730fdc8d8SChris Lattner bool
151830fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
151930fdc8d8SChris Lattner {
15207fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
152130fdc8d8SChris Lattner }
1522dde9cff3SCaroline Tice 
1523dde9cff3SCaroline Tice bool
15244f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
15254f465cffSJim Ingham {
15264f465cffSJim Ingham     Stream &strm = status.ref();
15274f465cffSJim Ingham 
15284f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
15294f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
15304f465cffSJim Ingham     {
15314f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
15324f465cffSJim Ingham     }
15334f465cffSJim Ingham     else
15344f465cffSJim Ingham         strm.PutCString ("No status");
15354f465cffSJim Ingham 
15364f465cffSJim Ingham     return true;
15374f465cffSJim Ingham }
15384f465cffSJim Ingham 
15394f465cffSJim Ingham bool
1540ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1541ceb6b139SCaroline Tice {
1542da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1543da7bc7d0SGreg Clayton 
15447fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
15451ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1546ceb6b139SCaroline Tice     {
1547603985fcSJim Ingham         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1548603985fcSJim Ingham         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1549ceb6b139SCaroline Tice     }
1550ceb6b139SCaroline Tice     else
1551da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1552ceb6b139SCaroline Tice 
1553ceb6b139SCaroline Tice     return true;
1554ceb6b139SCaroline Tice }
15555dd4916fSJason Molenda 
15565dd4916fSJason Molenda SBThread
1557008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
15585dd4916fSJason Molenda {
15595dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
15605dd4916fSJason Molenda     Mutex::Locker api_locker;
15615dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
15625dd4916fSJason Molenda     SBThread sb_origin_thread;
15635dd4916fSJason Molenda 
15645dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
15655dd4916fSJason Molenda     {
15665dd4916fSJason Molenda         Process::StopLocker stop_locker;
15675dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
15685dd4916fSJason Molenda         {
15697a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
15705dd4916fSJason Molenda             if (real_thread)
15715dd4916fSJason Molenda             {
15725dd4916fSJason Molenda                 ConstString type_const (type);
15737a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
15747a2f7904SJason Molenda                 if (process)
15757a2f7904SJason Molenda                 {
15767a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
15775dd4916fSJason Molenda                     if (runtime)
15785dd4916fSJason Molenda                     {
1579008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1580a6e9130dSJason Molenda                         if (new_thread_sp)
1581a6e9130dSJason Molenda                         {
15827a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
15837a2f7904SJason Molenda                             // object.
15847a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
15857a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1586a6e9130dSJason Molenda                             if (log)
1587a6e9130dSJason Molenda                             {
1588a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1589a6e9130dSJason Molenda                                 if (queue_name == NULL)
1590a6e9130dSJason Molenda                                     queue_name = "";
15912bdbfd50SJim Ingham                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
15922bdbfd50SJim Ingham                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1593324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1594324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1595324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1596324a1036SSaleem Abdulrasool                                              queue_name);
1597a6e9130dSJason Molenda                             }
1598a6e9130dSJason Molenda                         }
15997a2f7904SJason Molenda                     }
16005dd4916fSJason Molenda                 }
16015dd4916fSJason Molenda             }
16025dd4916fSJason Molenda         }
16035dd4916fSJason Molenda         else
16045dd4916fSJason Molenda         {
16055dd4916fSJason Molenda             if (log)
1606324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1607324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
16085dd4916fSJason Molenda         }
16095dd4916fSJason Molenda     }
16105dd4916fSJason Molenda 
1611ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1612324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1613324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
16145dd4916fSJason Molenda     return sb_origin_thread;
16155dd4916fSJason Molenda }
16168ee9cb58SJason Molenda 
16178ee9cb58SJason Molenda uint32_t
16188ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
16198ee9cb58SJason Molenda {
16208ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16218ee9cb58SJason Molenda     if (thread_sp)
16228ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
16238ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
16248ee9cb58SJason Molenda }
1625b4892cd2SJason Molenda 
1626b4892cd2SJason Molenda bool
1627b4892cd2SJason Molenda SBThread::SafeToCallFunctions ()
1628b4892cd2SJason Molenda {
1629b4892cd2SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1630b4892cd2SJason Molenda     if (thread_sp)
1631b4892cd2SJason Molenda         return thread_sp->SafeToCallFunctions();
1632b4892cd2SJason Molenda     return true;
1633b4892cd2SJason Molenda }
16342bdbfd50SJim Ingham 
16352bdbfd50SJim Ingham lldb_private::Thread *
16362bdbfd50SJim Ingham SBThread::operator->()
16372bdbfd50SJim Ingham {
16382bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16392bdbfd50SJim Ingham     if (thread_sp)
16402bdbfd50SJim Ingham         return thread_sp.get();
16412bdbfd50SJim Ingham     else
16422bdbfd50SJim Ingham         return NULL;
16432bdbfd50SJim Ingham }
16442bdbfd50SJim Ingham 
16452bdbfd50SJim Ingham lldb_private::Thread *
16462bdbfd50SJim Ingham SBThread::get()
16472bdbfd50SJim Ingham {
16482bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
16492bdbfd50SJim Ingham     if (thread_sp)
16502bdbfd50SJim Ingham         return thread_sp.get();
16512bdbfd50SJim Ingham     else
16522bdbfd50SJim Ingham         return NULL;
16532bdbfd50SJim Ingham }
16542bdbfd50SJim Ingham 
1655