130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124c5de699SEli Friedman #include "lldb/API/SBThread.h"
1330fdc8d8SChris Lattner 
1430fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
174e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
186611103cSGreg Clayton #include "lldb/Core/Debugger.h"
19a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2130fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
22705b1809SJason Molenda #include "lldb/Core/StructuredData.h"
236611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
24*93749ab3SZachary Turner #include "lldb/Symbol/SymbolContext.h"
25*93749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h"
265dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
29b9ffa98cSJason Molenda #include "lldb/Target/Queue.h"
30*93749ab3SZachary Turner #include "lldb/Target/UnixSignals.h"
31f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
3230fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner 
404c5de699SEli Friedman #include "lldb/API/SBAddress.h"
414c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
424f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4373ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
444c5de699SEli Friedman #include "lldb/API/SBProcess.h"
452bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h"
4673ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4730fdc8d8SChris Lattner 
4830fdc8d8SChris Lattner using namespace lldb;
4930fdc8d8SChris Lattner using namespace lldb_private;
5030fdc8d8SChris Lattner 
514f465cffSJim Ingham const char *
524f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
534f465cffSJim Ingham {
544f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
554f465cffSJim Ingham }
564f465cffSJim Ingham 
57cfd1acedSGreg Clayton //----------------------------------------------------------------------
58cfd1acedSGreg Clayton // Constructors
59cfd1acedSGreg Clayton //----------------------------------------------------------------------
6030fdc8d8SChris Lattner SBThread::SBThread () :
617fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
6230fdc8d8SChris Lattner {
6330fdc8d8SChris Lattner }
6430fdc8d8SChris Lattner 
6530fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
667fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6730fdc8d8SChris Lattner {
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
7092ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
717fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
7230fdc8d8SChris Lattner {
737fdf9ef1SGreg Clayton 
7430fdc8d8SChris Lattner }
7530fdc8d8SChris Lattner 
7630fdc8d8SChris Lattner //----------------------------------------------------------------------
77cfd1acedSGreg Clayton // Assignment operator
78cfd1acedSGreg Clayton //----------------------------------------------------------------------
79cfd1acedSGreg Clayton 
80cfd1acedSGreg Clayton const lldb::SBThread &
81cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
82cfd1acedSGreg Clayton {
83cfd1acedSGreg Clayton     if (this != &rhs)
847fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
85cfd1acedSGreg Clayton     return *this;
86cfd1acedSGreg Clayton }
87cfd1acedSGreg Clayton 
88cfd1acedSGreg Clayton //----------------------------------------------------------------------
8930fdc8d8SChris Lattner // Destructor
9030fdc8d8SChris Lattner //----------------------------------------------------------------------
9130fdc8d8SChris Lattner SBThread::~SBThread()
9230fdc8d8SChris Lattner {
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
95b9ffa98cSJason Molenda lldb::SBQueue
96b9ffa98cSJason Molenda SBThread::GetQueue () const
97b9ffa98cSJason Molenda {
98b9ffa98cSJason Molenda     SBQueue sb_queue;
99b9ffa98cSJason Molenda     QueueSP queue_sp;
100b9ffa98cSJason Molenda     Mutex::Locker api_locker;
101b9ffa98cSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
102b9ffa98cSJason Molenda 
103b9ffa98cSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
104b9ffa98cSJason Molenda     if (exe_ctx.HasThreadScope())
105b9ffa98cSJason Molenda     {
106b9ffa98cSJason Molenda         Process::StopLocker stop_locker;
107b9ffa98cSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
108b9ffa98cSJason Molenda         {
109b9ffa98cSJason Molenda             queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
110b9ffa98cSJason Molenda             if (queue_sp)
111b9ffa98cSJason Molenda             {
112b9ffa98cSJason Molenda                 sb_queue.SetQueue (queue_sp);
113b9ffa98cSJason Molenda             }
114b9ffa98cSJason Molenda         }
115b9ffa98cSJason Molenda         else
116b9ffa98cSJason Molenda         {
117b9ffa98cSJason Molenda             if (log)
118b9ffa98cSJason Molenda                 log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running",
119b9ffa98cSJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
120b9ffa98cSJason Molenda         }
121b9ffa98cSJason Molenda     }
122b9ffa98cSJason Molenda 
123b9ffa98cSJason Molenda     if (log)
124b9ffa98cSJason Molenda         log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)",
125b9ffa98cSJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
126b9ffa98cSJason Molenda 
127b9ffa98cSJason Molenda     return sb_queue;
128b9ffa98cSJason Molenda }
129b9ffa98cSJason Molenda 
130b9ffa98cSJason Molenda 
13130fdc8d8SChris Lattner bool
13230fdc8d8SChris Lattner SBThread::IsValid() const
13330fdc8d8SChris Lattner {
1347fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
13530fdc8d8SChris Lattner }
13630fdc8d8SChris Lattner 
13748e42549SGreg Clayton void
13848e42549SGreg Clayton SBThread::Clear ()
13948e42549SGreg Clayton {
1407fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
14148e42549SGreg Clayton }
14248e42549SGreg Clayton 
14348e42549SGreg Clayton 
14430fdc8d8SChris Lattner StopReason
14530fdc8d8SChris Lattner SBThread::GetStopReason()
14630fdc8d8SChris Lattner {
1475160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
148ceb6b139SCaroline Tice 
149ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1504fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1514fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1524fc6cb9cSJim Ingham 
1531ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
15430fdc8d8SChris Lattner     {
1557fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1567fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1577fdf9ef1SGreg Clayton         {
15897d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
15930fdc8d8SChris Lattner         }
160c9858e4dSGreg Clayton         else
161c9858e4dSGreg Clayton         {
162c9858e4dSGreg Clayton             if (log)
163324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
164324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
165c9858e4dSGreg Clayton         }
1667fdf9ef1SGreg Clayton     }
167ceb6b139SCaroline Tice 
168ceb6b139SCaroline Tice     if (log)
169324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
170324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
171750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
172ceb6b139SCaroline Tice 
173ceb6b139SCaroline Tice     return reason;
17430fdc8d8SChris Lattner }
17530fdc8d8SChris Lattner 
17630fdc8d8SChris Lattner size_t
1774e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1784e78f606SGreg Clayton {
1794fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1804fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1814fc6cb9cSJim Ingham 
1821ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1834e78f606SGreg Clayton     {
1847fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1857fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1867fdf9ef1SGreg Clayton         {
1871ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1884e78f606SGreg Clayton             if (stop_info_sp)
1894e78f606SGreg Clayton             {
1904e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1914e78f606SGreg Clayton                 switch (reason)
1924e78f606SGreg Clayton                 {
1934e78f606SGreg Clayton                 case eStopReasonInvalid:
1944e78f606SGreg Clayton                 case eStopReasonNone:
1954e78f606SGreg Clayton                 case eStopReasonTrace:
19690ba8115SGreg Clayton                 case eStopReasonExec:
1974e78f606SGreg Clayton                 case eStopReasonPlanComplete:
198f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
199afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2004e78f606SGreg Clayton                     // There is no data for these stop reasons.
2014e78f606SGreg Clayton                     return 0;
2024e78f606SGreg Clayton 
2034e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2044e78f606SGreg Clayton                     {
2054e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2061ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2074e78f606SGreg Clayton                         if (bp_site_sp)
2084e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
2094e78f606SGreg Clayton                         else
2104e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
2114e78f606SGreg Clayton                     }
2124e78f606SGreg Clayton                     break;
2134e78f606SGreg Clayton 
2144e78f606SGreg Clayton                 case eStopReasonWatchpoint:
215290fa41bSJohnny Chen                     return 1;
2164e78f606SGreg Clayton 
2174e78f606SGreg Clayton                 case eStopReasonSignal:
2184e78f606SGreg Clayton                     return 1;
2194e78f606SGreg Clayton 
2204e78f606SGreg Clayton                 case eStopReasonException:
2214e78f606SGreg Clayton                     return 1;
2224e78f606SGreg Clayton                 }
2234e78f606SGreg Clayton             }
2244e78f606SGreg Clayton         }
225c9858e4dSGreg Clayton         else
226c9858e4dSGreg Clayton         {
2275160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
228c9858e4dSGreg Clayton             if (log)
229324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
230324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
231c9858e4dSGreg Clayton         }
2327fdf9ef1SGreg Clayton     }
2334e78f606SGreg Clayton     return 0;
2344e78f606SGreg Clayton }
2354e78f606SGreg Clayton 
2364e78f606SGreg Clayton uint64_t
2374e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
2384e78f606SGreg Clayton {
2394fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2404fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2414fc6cb9cSJim Ingham 
2421ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2434e78f606SGreg Clayton     {
2447fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2457fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2467fdf9ef1SGreg Clayton         {
2471ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2481ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2494e78f606SGreg Clayton             if (stop_info_sp)
2504e78f606SGreg Clayton             {
2514e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2524e78f606SGreg Clayton                 switch (reason)
2534e78f606SGreg Clayton                 {
2544e78f606SGreg Clayton                 case eStopReasonInvalid:
2554e78f606SGreg Clayton                 case eStopReasonNone:
2564e78f606SGreg Clayton                 case eStopReasonTrace:
25790ba8115SGreg Clayton                 case eStopReasonExec:
2584e78f606SGreg Clayton                 case eStopReasonPlanComplete:
259f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
260afdf842bSKuba Brecka                 case eStopReasonInstrumentation:
2614e78f606SGreg Clayton                     // There is no data for these stop reasons.
2624e78f606SGreg Clayton                     return 0;
2634e78f606SGreg Clayton 
2644e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2654e78f606SGreg Clayton                     {
2664e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2671ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2684e78f606SGreg Clayton                         if (bp_site_sp)
2694e78f606SGreg Clayton                         {
2704e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2714e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2724e78f606SGreg Clayton                             if (bp_loc_sp)
2734e78f606SGreg Clayton                             {
2748334e14eSGreg Clayton                                 if (idx & 1)
2754e78f606SGreg Clayton                                 {
2764e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2774e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2784e78f606SGreg Clayton                                 }
2794e78f606SGreg Clayton                                 else
2804e78f606SGreg Clayton                                 {
2814e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2824e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2834e78f606SGreg Clayton                                 }
2844e78f606SGreg Clayton                             }
2854e78f606SGreg Clayton                         }
2864e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2874e78f606SGreg Clayton                     }
2884e78f606SGreg Clayton                     break;
2894e78f606SGreg Clayton 
2904e78f606SGreg Clayton                 case eStopReasonWatchpoint:
291290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2924e78f606SGreg Clayton 
2934e78f606SGreg Clayton                 case eStopReasonSignal:
2944e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2954e78f606SGreg Clayton 
2964e78f606SGreg Clayton                 case eStopReasonException:
2974e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2984e78f606SGreg Clayton                 }
2994e78f606SGreg Clayton             }
3004e78f606SGreg Clayton         }
301c9858e4dSGreg Clayton         else
302c9858e4dSGreg Clayton         {
3035160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
304c9858e4dSGreg Clayton             if (log)
305324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
306324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
307c9858e4dSGreg Clayton         }
3087fdf9ef1SGreg Clayton     }
3094e78f606SGreg Clayton     return 0;
3104e78f606SGreg Clayton }
3114e78f606SGreg Clayton 
312afdf842bSKuba Brecka bool
313afdf842bSKuba Brecka SBThread::GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream)
314afdf842bSKuba Brecka {
315afdf842bSKuba Brecka     Stream &strm = stream.ref();
316afdf842bSKuba Brecka 
317afdf842bSKuba Brecka     ExecutionContext exe_ctx (m_opaque_sp.get());
318afdf842bSKuba Brecka     if (! exe_ctx.HasThreadScope())
319afdf842bSKuba Brecka         return false;
320afdf842bSKuba Brecka 
321afdf842bSKuba Brecka 
322afdf842bSKuba Brecka     StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
323afdf842bSKuba Brecka     StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
324afdf842bSKuba Brecka     if (! info)
325afdf842bSKuba Brecka         return false;
326afdf842bSKuba Brecka 
327afdf842bSKuba Brecka     info->Dump(strm);
328afdf842bSKuba Brecka 
329afdf842bSKuba Brecka     return true;
330afdf842bSKuba Brecka }
331afdf842bSKuba Brecka 
3324e78f606SGreg Clayton size_t
33330fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
33430fdc8d8SChris Lattner {
3355160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
336ceb6b139SCaroline Tice 
3374fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3384fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3394fc6cb9cSJim Ingham 
3401ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
34130fdc8d8SChris Lattner     {
3427fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3437fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3447fdf9ef1SGreg Clayton         {
3457fdf9ef1SGreg Clayton 
3461ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
347b15bfc75SJim Ingham             if (stop_info_sp)
34830fdc8d8SChris Lattner             {
349b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
35030fdc8d8SChris Lattner                 if (stop_desc)
35130fdc8d8SChris Lattner                 {
352ceb6b139SCaroline Tice                     if (log)
3534838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
354324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
355324a1036SSaleem Abdulrasool                                      stop_desc);
35630fdc8d8SChris Lattner                     if (dst)
35730fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
35830fdc8d8SChris Lattner                     else
35930fdc8d8SChris Lattner                     {
36030fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
36130fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
36230fdc8d8SChris Lattner                     }
36330fdc8d8SChris Lattner                 }
36430fdc8d8SChris Lattner                 else
36530fdc8d8SChris Lattner                 {
36630fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
367b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
36830fdc8d8SChris Lattner                     {
36930fdc8d8SChris Lattner                     case eStopReasonTrace:
37030fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
37130fdc8d8SChris Lattner                         {
37230fdc8d8SChris Lattner                             static char trace_desc[] = "step";
37330fdc8d8SChris Lattner                             stop_desc = trace_desc;
37430fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
37530fdc8d8SChris Lattner                         }
37630fdc8d8SChris Lattner                         break;
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
37930fdc8d8SChris Lattner                         {
38030fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
38130fdc8d8SChris Lattner                             stop_desc = bp_desc;
38230fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
38330fdc8d8SChris Lattner                         }
38430fdc8d8SChris Lattner                         break;
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
38730fdc8d8SChris Lattner                         {
38830fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
38930fdc8d8SChris Lattner                             stop_desc = wp_desc;
39030fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
39130fdc8d8SChris Lattner                         }
39230fdc8d8SChris Lattner                         break;
39330fdc8d8SChris Lattner 
39430fdc8d8SChris Lattner                     case eStopReasonSignal:
39530fdc8d8SChris Lattner                         {
3961ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
39730fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
39830fdc8d8SChris Lattner                             {
39930fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
40030fdc8d8SChris Lattner                                 stop_desc = signal_desc;
40130fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
40230fdc8d8SChris Lattner                             }
40330fdc8d8SChris Lattner                         }
40430fdc8d8SChris Lattner                         break;
40530fdc8d8SChris Lattner 
40630fdc8d8SChris Lattner                     case eStopReasonException:
40730fdc8d8SChris Lattner                         {
40830fdc8d8SChris Lattner                             char exc_desc[] = "exception";
40930fdc8d8SChris Lattner                             stop_desc = exc_desc;
41030fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
41130fdc8d8SChris Lattner                         }
41230fdc8d8SChris Lattner                         break;
413c982c768SGreg Clayton 
41490ba8115SGreg Clayton                     case eStopReasonExec:
41590ba8115SGreg Clayton                         {
41690ba8115SGreg Clayton                             char exc_desc[] = "exec";
41790ba8115SGreg Clayton                             stop_desc = exc_desc;
41890ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
41990ba8115SGreg Clayton                         }
42090ba8115SGreg Clayton                         break;
42190ba8115SGreg Clayton 
422f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
423f85defaeSAndrew Kaylor                         {
424f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
425f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
426f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
427f85defaeSAndrew Kaylor                         }
428f85defaeSAndrew Kaylor                         break;
429c982c768SGreg Clayton                     default:
430c982c768SGreg Clayton                         break;
43130fdc8d8SChris Lattner                     }
43230fdc8d8SChris Lattner 
43330fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
43430fdc8d8SChris Lattner                     {
435ceb6b139SCaroline Tice                         if (log)
43693aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
437324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
438324a1036SSaleem Abdulrasool                                          stop_desc);
439ceb6b139SCaroline Tice 
44030fdc8d8SChris Lattner                         if (dst)
44130fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner                         if (stop_desc_len == 0)
44430fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
44530fdc8d8SChris Lattner 
44630fdc8d8SChris Lattner                         return stop_desc_len;
44730fdc8d8SChris Lattner                     }
44830fdc8d8SChris Lattner                 }
44930fdc8d8SChris Lattner             }
45030fdc8d8SChris Lattner         }
451c9858e4dSGreg Clayton         else
452c9858e4dSGreg Clayton         {
4535160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
454c9858e4dSGreg Clayton             if (log)
455324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
456324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
457c9858e4dSGreg Clayton         }
4587fdf9ef1SGreg Clayton     }
45930fdc8d8SChris Lattner     if (dst)
46030fdc8d8SChris Lattner         *dst = 0;
46130fdc8d8SChris Lattner     return 0;
46230fdc8d8SChris Lattner }
46330fdc8d8SChris Lattner 
46473ca05a2SJim Ingham SBValue
46573ca05a2SJim Ingham SBThread::GetStopReturnValue ()
46673ca05a2SJim Ingham {
4675160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
46873ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
4694fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4704fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4714fc6cb9cSJim Ingham 
4721ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
47373ca05a2SJim Ingham     {
4747fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4757fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4767fdf9ef1SGreg Clayton         {
4771ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
47873ca05a2SJim Ingham             if (stop_info_sp)
47973ca05a2SJim Ingham             {
48073ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
48173ca05a2SJim Ingham             }
48273ca05a2SJim Ingham         }
483c9858e4dSGreg Clayton         else
484c9858e4dSGreg Clayton         {
485c9858e4dSGreg Clayton             if (log)
486324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
487324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
488c9858e4dSGreg Clayton         }
4897fdf9ef1SGreg Clayton     }
49073ca05a2SJim Ingham 
49173ca05a2SJim Ingham     if (log)
492324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
493324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
49473ca05a2SJim Ingham                      return_valobj_sp.get()
49573ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
49673ca05a2SJim Ingham                         : "<no return value>");
49773ca05a2SJim Ingham 
49873ca05a2SJim Ingham     return SBValue (return_valobj_sp);
49973ca05a2SJim Ingham }
50073ca05a2SJim Ingham 
50130fdc8d8SChris Lattner void
50230fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
50330fdc8d8SChris Lattner {
5047fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
50530fdc8d8SChris Lattner }
50630fdc8d8SChris Lattner 
50730fdc8d8SChris Lattner lldb::tid_t
50830fdc8d8SChris Lattner SBThread::GetThreadID () const
50930fdc8d8SChris Lattner {
5107fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
51117a6ad05SGreg Clayton     if (thread_sp)
5121ac04c30SGreg Clayton         return thread_sp->GetID();
5131ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
51430fdc8d8SChris Lattner }
51530fdc8d8SChris Lattner 
51630fdc8d8SChris Lattner uint32_t
51730fdc8d8SChris Lattner SBThread::GetIndexID () const
51830fdc8d8SChris Lattner {
5197fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
52017a6ad05SGreg Clayton     if (thread_sp)
52117a6ad05SGreg Clayton         return thread_sp->GetIndexID();
52230fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
52330fdc8d8SChris Lattner }
5241ac04c30SGreg Clayton 
52530fdc8d8SChris Lattner const char *
52630fdc8d8SChris Lattner SBThread::GetName () const
52730fdc8d8SChris Lattner {
5285160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5294838131bSGreg Clayton     const char *name = NULL;
5304fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5314fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5324fc6cb9cSJim Ingham 
5331ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
534af67cecdSGreg Clayton     {
5357fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5367fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5377fdf9ef1SGreg Clayton         {
5381ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
539af67cecdSGreg Clayton         }
540c9858e4dSGreg Clayton         else
541c9858e4dSGreg Clayton         {
542c9858e4dSGreg Clayton             if (log)
543324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
544324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
545c9858e4dSGreg Clayton         }
5467fdf9ef1SGreg Clayton     }
547ceb6b139SCaroline Tice 
548ceb6b139SCaroline Tice     if (log)
549324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
550324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
551324a1036SSaleem Abdulrasool                      name ? name : "NULL");
552ceb6b139SCaroline Tice 
5534838131bSGreg Clayton     return name;
55430fdc8d8SChris Lattner }
55530fdc8d8SChris Lattner 
55630fdc8d8SChris Lattner const char *
55730fdc8d8SChris Lattner SBThread::GetQueueName () const
55830fdc8d8SChris Lattner {
5594838131bSGreg Clayton     const char *name = NULL;
5604fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5614fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5624fc6cb9cSJim Ingham 
5635160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5641ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
565af67cecdSGreg Clayton     {
5667fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5677fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5687fdf9ef1SGreg Clayton         {
5691ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
570af67cecdSGreg Clayton         }
571c9858e4dSGreg Clayton         else
572c9858e4dSGreg Clayton         {
573c9858e4dSGreg Clayton             if (log)
574324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
575324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
576c9858e4dSGreg Clayton         }
5777fdf9ef1SGreg Clayton     }
578ceb6b139SCaroline Tice 
579ceb6b139SCaroline Tice     if (log)
580324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
581324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
582324a1036SSaleem Abdulrasool                      name ? name : "NULL");
583ceb6b139SCaroline Tice 
5844838131bSGreg Clayton     return name;
58530fdc8d8SChris Lattner }
58630fdc8d8SChris Lattner 
5874fdb5863SJason Molenda lldb::queue_id_t
5884fdb5863SJason Molenda SBThread::GetQueueID () const
5894fdb5863SJason Molenda {
5904fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
5914fdb5863SJason Molenda     Mutex::Locker api_locker;
5924fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5934fdb5863SJason Molenda 
5944fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5954fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
5964fdb5863SJason Molenda     {
5974fdb5863SJason Molenda         Process::StopLocker stop_locker;
5984fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5994fdb5863SJason Molenda         {
6004fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
6014fdb5863SJason Molenda         }
6024fdb5863SJason Molenda         else
6034fdb5863SJason Molenda         {
6044fdb5863SJason Molenda             if (log)
605324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
606324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
6074fdb5863SJason Molenda         }
6084fdb5863SJason Molenda     }
6094fdb5863SJason Molenda 
6104fdb5863SJason Molenda     if (log)
611324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
612324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
6134fdb5863SJason Molenda 
6144fdb5863SJason Molenda     return id;
6154fdb5863SJason Molenda }
6164fdb5863SJason Molenda 
617705b1809SJason Molenda bool
618705b1809SJason Molenda SBThread::GetInfoItemByPathAsString (const char *path, SBStream &strm)
619705b1809SJason Molenda {
620705b1809SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
621705b1809SJason Molenda     bool success = false;
622705b1809SJason Molenda     Mutex::Locker api_locker;
623705b1809SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
624705b1809SJason Molenda 
625705b1809SJason Molenda     if (exe_ctx.HasThreadScope())
626705b1809SJason Molenda     {
627705b1809SJason Molenda         Process::StopLocker stop_locker;
628705b1809SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
629705b1809SJason Molenda         {
630705b1809SJason Molenda             Thread *thread = exe_ctx.GetThreadPtr();
631705b1809SJason Molenda             StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
632705b1809SJason Molenda             if (info_root_sp)
633705b1809SJason Molenda             {
634705b1809SJason Molenda                 StructuredData::ObjectSP node = info_root_sp->GetObjectForDotSeparatedPath (path);
635705b1809SJason Molenda                 if (node)
636705b1809SJason Molenda                 {
637705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeString)
638705b1809SJason Molenda                     {
639705b1809SJason Molenda                         strm.Printf ("%s", node->GetAsString()->GetValue().c_str());
640705b1809SJason Molenda                         success = true;
641705b1809SJason Molenda                     }
642705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeInteger)
643705b1809SJason Molenda                     {
644705b1809SJason Molenda                         strm.Printf ("0x%" PRIx64, node->GetAsInteger()->GetValue());
645705b1809SJason Molenda                         success = true;
646705b1809SJason Molenda                     }
647705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeFloat)
648705b1809SJason Molenda                     {
649705b1809SJason Molenda                         strm.Printf ("0x%f", node->GetAsFloat()->GetValue());
650705b1809SJason Molenda                         success = true;
651705b1809SJason Molenda                     }
652705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeBoolean)
653705b1809SJason Molenda                     {
654705b1809SJason Molenda                         if (node->GetAsBoolean()->GetValue() == true)
655705b1809SJason Molenda                             strm.Printf ("true");
656705b1809SJason Molenda                         else
657705b1809SJason Molenda                             strm.Printf ("false");
658705b1809SJason Molenda                         success = true;
659705b1809SJason Molenda                     }
660705b1809SJason Molenda                     if (node->GetType() == StructuredData::Type::eTypeNull)
661705b1809SJason Molenda                     {
662705b1809SJason Molenda                         strm.Printf ("null");
663705b1809SJason Molenda                         success = true;
664705b1809SJason Molenda                     }
665705b1809SJason Molenda                 }
666705b1809SJason Molenda             }
667705b1809SJason Molenda         }
668705b1809SJason Molenda         else
669705b1809SJason Molenda         {
670705b1809SJason Molenda             if (log)
671705b1809SJason Molenda                 log->Printf ("SBThread(%p)::GetInfoItemByPathAsString() => error: process is running",
672705b1809SJason Molenda                              static_cast<void*>(exe_ctx.GetThreadPtr()));
673705b1809SJason Molenda         }
674705b1809SJason Molenda     }
675705b1809SJason Molenda 
676705b1809SJason Molenda     if (log)
677705b1809SJason Molenda         log->Printf ("SBThread(%p)::GetInfoItemByPathAsString () => %s",
678705b1809SJason Molenda                      static_cast<void*>(exe_ctx.GetThreadPtr()),
679705b1809SJason Molenda                      strm.GetData());
680705b1809SJason Molenda 
681705b1809SJason Molenda     return success;
682705b1809SJason Molenda }
683705b1809SJason Molenda 
684705b1809SJason Molenda 
68564e7ead1SJim Ingham SBError
68664e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
68764e7ead1SJim Ingham {
68864e7ead1SJim Ingham     SBError sb_error;
68964e7ead1SJim Ingham 
69064e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
69164e7ead1SJim Ingham     if (!process)
69264e7ead1SJim Ingham     {
69364e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
69464e7ead1SJim Ingham         return sb_error;
69564e7ead1SJim Ingham     }
69664e7ead1SJim Ingham 
69764e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
69864e7ead1SJim Ingham     if (!thread)
69964e7ead1SJim Ingham     {
70064e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
70164e7ead1SJim Ingham         return sb_error;
70264e7ead1SJim Ingham     }
70364e7ead1SJim Ingham 
70464e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
70564e7ead1SJim Ingham     // then a "continue" will resume the plan.
70664e7ead1SJim Ingham     if (new_plan != NULL)
70764e7ead1SJim Ingham     {
70864e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
70964e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
71064e7ead1SJim Ingham     }
71164e7ead1SJim Ingham 
71264e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
71364e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
71464e7ead1SJim Ingham 
715dc6224e0SGreg Clayton     if (process->GetTarget().GetDebugger().GetAsyncExecution ())
716dc6224e0SGreg Clayton         sb_error.ref() = process->Resume ();
717dc6224e0SGreg Clayton     else
718dc6224e0SGreg Clayton         sb_error.ref() = process->ResumeSynchronous (NULL);
71964e7ead1SJim Ingham 
72064e7ead1SJim Ingham     return sb_error;
72164e7ead1SJim Ingham }
72230fdc8d8SChris Lattner 
72330fdc8d8SChris Lattner void
72430fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
72530fdc8d8SChris Lattner {
7265160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
727ceb6b139SCaroline Tice 
7284fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7294fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7304fc6cb9cSJim Ingham 
73117a6ad05SGreg Clayton 
732ceb6b139SCaroline Tice     if (log)
733324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
734324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
735ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
736ceb6b139SCaroline Tice 
7371ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
73830fdc8d8SChris Lattner     {
7391ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7407ba6e991SJim Ingham         bool abort_other_plans = false;
741b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
74230fdc8d8SChris Lattner 
7434d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
74430fdc8d8SChris Lattner         if (frame_sp)
74530fdc8d8SChris Lattner         {
74630fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
74730fdc8d8SChris Lattner             {
7484b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
74930fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
7504d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
75130fdc8d8SChris Lattner                                                                     sc.line_entry.range,
75230fdc8d8SChris Lattner                                                                     sc,
7534b4b2478SJim Ingham                                                                     stop_other_threads,
7544b4b2478SJim Ingham                                                                     avoid_no_debug);
75530fdc8d8SChris Lattner             }
75630fdc8d8SChris Lattner             else
75730fdc8d8SChris Lattner             {
7584d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
75930fdc8d8SChris Lattner                                                                                abort_other_plans,
76030fdc8d8SChris Lattner                                                                                stop_other_threads);
76130fdc8d8SChris Lattner             }
76230fdc8d8SChris Lattner         }
76330fdc8d8SChris Lattner 
76464e7ead1SJim Ingham         // This returns an error, we should use it!
7654d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
76630fdc8d8SChris Lattner     }
76730fdc8d8SChris Lattner }
76830fdc8d8SChris Lattner 
76930fdc8d8SChris Lattner void
77030fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
77130fdc8d8SChris Lattner {
772c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
773c627682eSJim Ingham }
774c627682eSJim Ingham 
775c627682eSJim Ingham void
776c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
777c627682eSJim Ingham {
7785160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
779ceb6b139SCaroline Tice 
7804fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7814fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
78217a6ad05SGreg Clayton 
78317a6ad05SGreg Clayton     if (log)
784c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
785324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
786c627682eSJim Ingham                      target_name? target_name: "<NULL>",
78717a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
788c627682eSJim Ingham 
7891ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
79030fdc8d8SChris Lattner     {
7917ba6e991SJim Ingham         bool abort_other_plans = false;
79230fdc8d8SChris Lattner 
7931ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
794b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
7954d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
79630fdc8d8SChris Lattner 
79730fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
79830fdc8d8SChris Lattner         {
7994b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
8004b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
80130fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
8024d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
80330fdc8d8SChris Lattner                                                               sc.line_entry.range,
80430fdc8d8SChris Lattner                                                               sc,
805c627682eSJim Ingham                                                               target_name,
806474966a4SGreg Clayton                                                               stop_other_threads,
8074b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
8084b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
80930fdc8d8SChris Lattner         }
81030fdc8d8SChris Lattner         else
81130fdc8d8SChris Lattner         {
8124d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
81330fdc8d8SChris Lattner                                                                            abort_other_plans,
81430fdc8d8SChris Lattner                                                                            stop_other_threads);
81530fdc8d8SChris Lattner         }
81630fdc8d8SChris Lattner 
81764e7ead1SJim Ingham         // This returns an error, we should use it!
8184d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
81930fdc8d8SChris Lattner     }
82030fdc8d8SChris Lattner }
82130fdc8d8SChris Lattner 
82230fdc8d8SChris Lattner void
82330fdc8d8SChris Lattner SBThread::StepOut ()
82430fdc8d8SChris Lattner {
8255160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
826ceb6b139SCaroline Tice 
8274fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8284fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8294fc6cb9cSJim Ingham 
830ceb6b139SCaroline Tice 
83117a6ad05SGreg Clayton     if (log)
832324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
833324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
83417a6ad05SGreg Clayton 
8351ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
83630fdc8d8SChris Lattner     {
8377ba6e991SJim Ingham         bool abort_other_plans = false;
83894b09246SJim Ingham         bool stop_other_threads = false;
83930fdc8d8SChris Lattner 
8401ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8411ac04c30SGreg Clayton 
8424b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
8434d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
844481cef25SGreg Clayton                                                                     NULL,
845481cef25SGreg Clayton                                                                     false,
846481cef25SGreg Clayton                                                                     stop_other_threads,
847481cef25SGreg Clayton                                                                     eVoteYes,
848481cef25SGreg Clayton                                                                     eVoteNoOpinion,
8494b4b2478SJim Ingham                                                                     0,
8504b4b2478SJim Ingham                                                                     avoid_no_debug));
851481cef25SGreg Clayton 
85264e7ead1SJim Ingham         // This returns an error, we should use it!
8534d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
854481cef25SGreg Clayton     }
855481cef25SGreg Clayton }
856481cef25SGreg Clayton 
857481cef25SGreg Clayton void
858481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
859481cef25SGreg Clayton {
8605160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
861481cef25SGreg Clayton 
8624fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8634fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8644fc6cb9cSJim Ingham 
865b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
866481cef25SGreg Clayton     if (log)
867481cef25SGreg Clayton     {
868481cef25SGreg Clayton         SBStream frame_desc_strm;
869481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
870324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
871324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
872324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
873324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
874481cef25SGreg Clayton     }
875481cef25SGreg Clayton 
8761ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
877481cef25SGreg Clayton     {
8787ba6e991SJim Ingham         bool abort_other_plans = false;
87994b09246SJim Ingham         bool stop_other_threads = false;
8801ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
881481cef25SGreg Clayton 
8824d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
883481cef25SGreg Clayton                                                                     NULL,
884481cef25SGreg Clayton                                                                     false,
885481cef25SGreg Clayton                                                                     stop_other_threads,
886481cef25SGreg Clayton                                                                     eVoteYes,
887481cef25SGreg Clayton                                                                     eVoteNoOpinion,
8884d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
88930fdc8d8SChris Lattner 
89064e7ead1SJim Ingham         // This returns an error, we should use it!
8914d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
89230fdc8d8SChris Lattner     }
89330fdc8d8SChris Lattner }
89430fdc8d8SChris Lattner 
89530fdc8d8SChris Lattner void
89630fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
89730fdc8d8SChris Lattner {
8985160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
899ceb6b139SCaroline Tice 
9004fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9014fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9024fc6cb9cSJim Ingham 
9031ac04c30SGreg Clayton 
904ceb6b139SCaroline Tice 
90517a6ad05SGreg Clayton     if (log)
906324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
907324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
90817a6ad05SGreg Clayton 
9091ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
91030fdc8d8SChris Lattner     {
9111ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9124d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
91364e7ead1SJim Ingham 
91464e7ead1SJim Ingham         // This returns an error, we should use it!
9154d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
91630fdc8d8SChris Lattner     }
91730fdc8d8SChris Lattner }
91830fdc8d8SChris Lattner 
91930fdc8d8SChris Lattner void
92030fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
92130fdc8d8SChris Lattner {
9225160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
923ceb6b139SCaroline Tice 
9244fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9254fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9264fc6cb9cSJim Ingham 
927ceb6b139SCaroline Tice 
92817a6ad05SGreg Clayton     if (log)
929324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
930324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
93117a6ad05SGreg Clayton 
9321ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
93330fdc8d8SChris Lattner     {
9347ba6e991SJim Ingham         bool abort_other_plans = false;
93530fdc8d8SChris Lattner         bool stop_other_threads = true;
93630fdc8d8SChris Lattner 
937e72dfb32SGreg Clayton         Address target_addr (addr);
93830fdc8d8SChris Lattner 
9391ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9401ac04c30SGreg Clayton 
9412bdbfd50SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans,
9422bdbfd50SJim Ingham                                                                          target_addr,
9432bdbfd50SJim Ingham                                                                          stop_other_threads));
94464e7ead1SJim Ingham 
94564e7ead1SJim Ingham         // This returns an error, we should use it!
9464d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
94730fdc8d8SChris Lattner     }
94830fdc8d8SChris Lattner }
94930fdc8d8SChris Lattner 
950481cef25SGreg Clayton SBError
951481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
952481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
953481cef25SGreg Clayton                          uint32_t line)
954481cef25SGreg Clayton {
955481cef25SGreg Clayton     SBError sb_error;
9565160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
957481cef25SGreg Clayton     char path[PATH_MAX];
958481cef25SGreg Clayton 
9594fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9604fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9614fc6cb9cSJim Ingham 
962b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
96317a6ad05SGreg Clayton 
964481cef25SGreg Clayton     if (log)
965481cef25SGreg Clayton     {
966481cef25SGreg Clayton         SBStream frame_desc_strm;
967481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
968481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
969481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
970324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
971324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
972324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
973481cef25SGreg Clayton     }
974481cef25SGreg Clayton 
9751ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
976481cef25SGreg Clayton     {
9771ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
9781ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
979481cef25SGreg Clayton 
980481cef25SGreg Clayton         if (line == 0)
981481cef25SGreg Clayton         {
982481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
983481cef25SGreg Clayton             return sb_error;
984481cef25SGreg Clayton         }
985481cef25SGreg Clayton 
986b9556accSGreg Clayton         if (!frame_sp)
987481cef25SGreg Clayton         {
9881ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
989481cef25SGreg Clayton             if (!frame_sp)
9901ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
991481cef25SGreg Clayton         }
992481cef25SGreg Clayton 
993481cef25SGreg Clayton         SymbolContext frame_sc;
994481cef25SGreg Clayton         if (!frame_sp)
995481cef25SGreg Clayton         {
996481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
997481cef25SGreg Clayton             return sb_error;
998481cef25SGreg Clayton         }
999481cef25SGreg Clayton 
1000481cef25SGreg Clayton         // If we have a frame, get its line
1001481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
1002481cef25SGreg Clayton                                                eSymbolContextFunction  |
1003481cef25SGreg Clayton                                                eSymbolContextLineEntry |
1004481cef25SGreg Clayton                                                eSymbolContextSymbol    );
1005481cef25SGreg Clayton 
1006481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
1007481cef25SGreg Clayton         {
1008481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
1009481cef25SGreg Clayton             return sb_error;
1010481cef25SGreg Clayton         }
1011481cef25SGreg Clayton 
1012481cef25SGreg Clayton         FileSpec step_file_spec;
1013481cef25SGreg Clayton         if (sb_file_spec.IsValid())
1014481cef25SGreg Clayton         {
1015481cef25SGreg Clayton             // The file spec passed in was valid, so use it
1016481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
1017481cef25SGreg Clayton         }
1018481cef25SGreg Clayton         else
1019481cef25SGreg Clayton         {
1020481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
1021481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
1022481cef25SGreg Clayton             else
1023481cef25SGreg Clayton             {
1024481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
1025481cef25SGreg Clayton                 return sb_error;
1026481cef25SGreg Clayton             }
1027481cef25SGreg Clayton         }
1028481cef25SGreg Clayton 
10299b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
10309b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
10319b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
10329b70ddb3SJim Ingham         // error message.
10339b70ddb3SJim Ingham 
10349b70ddb3SJim Ingham         bool all_in_function = true;
10359b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
10369b70ddb3SJim Ingham 
1037481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
10387ba6e991SJim Ingham         const bool abort_other_plans = false;
1039c02e3344SJim Ingham         const bool stop_other_threads = false;
1040481cef25SGreg Clayton         const bool check_inlines = true;
1041481cef25SGreg Clayton         const bool exact = false;
1042481cef25SGreg Clayton 
1043481cef25SGreg Clayton         SymbolContextList sc_list;
10449b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
10459b70ddb3SJim Ingham                                                                                line,
10469b70ddb3SJim Ingham                                                                                check_inlines,
10479b70ddb3SJim Ingham                                                                                exact,
10489b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
10499b70ddb3SJim Ingham                                                                                sc_list);
1050481cef25SGreg Clayton         if (num_matches > 0)
1051481cef25SGreg Clayton         {
1052481cef25SGreg Clayton             SymbolContext sc;
1053481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
1054481cef25SGreg Clayton             {
1055481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
1056481cef25SGreg Clayton                 {
10579b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
1058481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
1059481cef25SGreg Clayton                     {
10609b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
1061481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
10629b70ddb3SJim Ingham                         else
10639b70ddb3SJim Ingham                             all_in_function = false;
1064481cef25SGreg Clayton                     }
1065481cef25SGreg Clayton                 }
1066481cef25SGreg Clayton             }
1067481cef25SGreg Clayton         }
1068481cef25SGreg Clayton 
1069481cef25SGreg Clayton         if (step_over_until_addrs.empty())
1070481cef25SGreg Clayton         {
10719b70ddb3SJim Ingham             if (all_in_function)
10729b70ddb3SJim Ingham             {
1073481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
1074fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
1075481cef25SGreg Clayton             }
1076481cef25SGreg Clayton             else
107786edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
10789b70ddb3SJim Ingham         }
10799b70ddb3SJim Ingham         else
1080481cef25SGreg Clayton         {
10814d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
1082481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
1083481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
1084481cef25SGreg Clayton                                                                         stop_other_threads,
10854d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
1086481cef25SGreg Clayton 
10874d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
1088481cef25SGreg Clayton         }
1089481cef25SGreg Clayton     }
1090481cef25SGreg Clayton     else
1091481cef25SGreg Clayton     {
1092481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
1093481cef25SGreg Clayton     }
1094481cef25SGreg Clayton     return sb_error;
1095481cef25SGreg Clayton }
1096481cef25SGreg Clayton 
10974413758cSJim Ingham SBError
10982bdbfd50SJim Ingham SBThread::StepUsingScriptedThreadPlan (const char *script_class_name)
10992bdbfd50SJim Ingham {
11002bdbfd50SJim Ingham     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11012bdbfd50SJim Ingham     SBError sb_error;
11022bdbfd50SJim Ingham 
11032bdbfd50SJim Ingham     Mutex::Locker api_locker;
11042bdbfd50SJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11052bdbfd50SJim Ingham 
11062bdbfd50SJim Ingham     if (log)
11072bdbfd50SJim Ingham     {
11082bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
11092bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11102bdbfd50SJim Ingham                      script_class_name);
11112bdbfd50SJim Ingham     }
11122bdbfd50SJim Ingham 
11132bdbfd50SJim Ingham 
11142bdbfd50SJim Ingham     if (!exe_ctx.HasThreadScope())
11152bdbfd50SJim Ingham     {
11162bdbfd50SJim Ingham         sb_error.SetErrorString("this SBThread object is invalid");
11172bdbfd50SJim Ingham         return sb_error;
11182bdbfd50SJim Ingham     }
11192bdbfd50SJim Ingham 
11202bdbfd50SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
11212bdbfd50SJim Ingham     ThreadPlanSP thread_plan_sp = thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
11222bdbfd50SJim Ingham 
11232bdbfd50SJim Ingham     if (thread_plan_sp)
11242bdbfd50SJim Ingham         sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
11252bdbfd50SJim Ingham     else
11262bdbfd50SJim Ingham     {
11272bdbfd50SJim Ingham         sb_error.SetErrorStringWithFormat("Error queuing thread plan for class: %s.", script_class_name);
11282bdbfd50SJim Ingham         if (log)
11292bdbfd50SJim Ingham         log->Printf ("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing thread plan for class: %s",
11302bdbfd50SJim Ingham                      static_cast<void*>(exe_ctx.GetThreadPtr()),
11312bdbfd50SJim Ingham                      script_class_name);
11322bdbfd50SJim Ingham     }
11332bdbfd50SJim Ingham 
11342bdbfd50SJim Ingham     return sb_error;
11352bdbfd50SJim Ingham }
11362bdbfd50SJim Ingham 
11372bdbfd50SJim Ingham SBError
1138f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
1139f86248d9SRichard Mitton {
1140f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1141f86248d9SRichard Mitton     SBError sb_error;
1142f86248d9SRichard Mitton 
1143f86248d9SRichard Mitton     Mutex::Locker api_locker;
1144f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1145f86248d9SRichard Mitton 
1146f86248d9SRichard Mitton     if (log)
1147324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1148324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1149324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
1150f86248d9SRichard Mitton 
1151f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
1152f86248d9SRichard Mitton     {
1153f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
1154f86248d9SRichard Mitton         return sb_error;
1155f86248d9SRichard Mitton     }
1156f86248d9SRichard Mitton 
1157f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
1158f86248d9SRichard Mitton 
1159f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
1160f86248d9SRichard Mitton     sb_error.SetError (err);
1161f86248d9SRichard Mitton     return sb_error;
1162f86248d9SRichard Mitton }
1163f86248d9SRichard Mitton 
1164f86248d9SRichard Mitton SBError
1165cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
11664413758cSJim Ingham {
11674413758cSJim Ingham     SBError sb_error;
11684413758cSJim Ingham 
11695160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11704413758cSJim Ingham 
11714413758cSJim Ingham     Mutex::Locker api_locker;
11724413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11734413758cSJim Ingham 
11744413758cSJim Ingham 
11754413758cSJim Ingham     if (log)
1176324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1177324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1178324a1036SSaleem Abdulrasool                      frame.GetFrameID());
11794413758cSJim Ingham 
11804413758cSJim Ingham     if (exe_ctx.HasThreadScope())
11814413758cSJim Ingham     {
11824413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1183cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
11844413758cSJim Ingham     }
11854413758cSJim Ingham 
11864413758cSJim Ingham     return sb_error;
11874413758cSJim Ingham }
11884413758cSJim Ingham 
1189481cef25SGreg Clayton 
1190722a0cdcSGreg Clayton bool
1191722a0cdcSGreg Clayton SBThread::Suspend()
1192722a0cdcSGreg Clayton {
11935160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
11947fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1195c9858e4dSGreg Clayton     bool result = false;
11961ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1197722a0cdcSGreg Clayton     {
1198c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1199c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1200c9858e4dSGreg Clayton         {
12011ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1202c9858e4dSGreg Clayton             result = true;
1203722a0cdcSGreg Clayton         }
1204c9858e4dSGreg Clayton         else
1205c9858e4dSGreg Clayton         {
1206c9858e4dSGreg Clayton             if (log)
1207324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1208324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1209c9858e4dSGreg Clayton         }
1210c9858e4dSGreg Clayton     }
1211c9858e4dSGreg Clayton     if (log)
1212324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1213324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1214c9858e4dSGreg Clayton     return result;
1215722a0cdcSGreg Clayton }
1216722a0cdcSGreg Clayton 
1217722a0cdcSGreg Clayton bool
1218722a0cdcSGreg Clayton SBThread::Resume ()
1219722a0cdcSGreg Clayton {
12205160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12217fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1222c9858e4dSGreg Clayton     bool result = false;
12231ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1224722a0cdcSGreg Clayton     {
1225c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1226c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1227c9858e4dSGreg Clayton         {
12286c9ed91cSJim Ingham             const bool override_suspend = true;
12296c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1230c9858e4dSGreg Clayton             result = true;
1231722a0cdcSGreg Clayton         }
1232c9858e4dSGreg Clayton         else
1233c9858e4dSGreg Clayton         {
1234c9858e4dSGreg Clayton             if (log)
1235324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1236324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1237c9858e4dSGreg Clayton         }
1238c9858e4dSGreg Clayton     }
1239c9858e4dSGreg Clayton     if (log)
1240324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1241324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1242c9858e4dSGreg Clayton     return result;
1243722a0cdcSGreg Clayton }
1244722a0cdcSGreg Clayton 
1245722a0cdcSGreg Clayton bool
1246722a0cdcSGreg Clayton SBThread::IsSuspended()
1247722a0cdcSGreg Clayton {
12487fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
12491ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
12501ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1251722a0cdcSGreg Clayton     return false;
1252722a0cdcSGreg Clayton }
1253722a0cdcSGreg Clayton 
1254a75418dbSAndrew Kaylor bool
1255a75418dbSAndrew Kaylor SBThread::IsStopped()
1256a75418dbSAndrew Kaylor {
1257a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1258a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1259a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1260a75418dbSAndrew Kaylor     return false;
1261a75418dbSAndrew Kaylor }
1262a75418dbSAndrew Kaylor 
126330fdc8d8SChris Lattner SBProcess
126430fdc8d8SChris Lattner SBThread::GetProcess ()
126530fdc8d8SChris Lattner {
1266b9556accSGreg Clayton     SBProcess sb_process;
12677fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
12681ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
126930fdc8d8SChris Lattner     {
127030fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
12711ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
127230fdc8d8SChris Lattner     }
1273ceb6b139SCaroline Tice 
12745160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1275ceb6b139SCaroline Tice     if (log)
1276ceb6b139SCaroline Tice     {
1277481cef25SGreg Clayton         SBStream frame_desc_strm;
1278b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1279324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1280324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1281324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1282324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1283ceb6b139SCaroline Tice     }
1284ceb6b139SCaroline Tice 
1285b9556accSGreg Clayton     return sb_process;
128630fdc8d8SChris Lattner }
128730fdc8d8SChris Lattner 
128830fdc8d8SChris Lattner uint32_t
128930fdc8d8SChris Lattner SBThread::GetNumFrames ()
129030fdc8d8SChris Lattner {
12915160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1292ceb6b139SCaroline Tice 
1293ceb6b139SCaroline Tice     uint32_t num_frames = 0;
12944fc6cb9cSJim Ingham     Mutex::Locker api_locker;
12954fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12964fc6cb9cSJim Ingham 
12971ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1298af67cecdSGreg Clayton     {
12997fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13007fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13017fdf9ef1SGreg Clayton         {
13021ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1303af67cecdSGreg Clayton         }
1304c9858e4dSGreg Clayton         else
1305c9858e4dSGreg Clayton         {
1306c9858e4dSGreg Clayton             if (log)
1307324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1308324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1309c9858e4dSGreg Clayton         }
13107fdf9ef1SGreg Clayton     }
1311ceb6b139SCaroline Tice 
1312ceb6b139SCaroline Tice     if (log)
1313324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1314324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1315ceb6b139SCaroline Tice 
1316ceb6b139SCaroline Tice     return num_frames;
131730fdc8d8SChris Lattner }
131830fdc8d8SChris Lattner 
131930fdc8d8SChris Lattner SBFrame
132030fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
132130fdc8d8SChris Lattner {
13225160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1323ceb6b139SCaroline Tice 
132430fdc8d8SChris Lattner     SBFrame sb_frame;
1325b57e4a1bSJason Molenda     StackFrameSP frame_sp;
13264fc6cb9cSJim Ingham     Mutex::Locker api_locker;
13274fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13284fc6cb9cSJim Ingham 
13291ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1330af67cecdSGreg Clayton     {
13317fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13327fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13337fdf9ef1SGreg Clayton         {
13341ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1335b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1336af67cecdSGreg Clayton         }
1337c9858e4dSGreg Clayton         else
1338c9858e4dSGreg Clayton         {
1339c9858e4dSGreg Clayton             if (log)
1340324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1341324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1342c9858e4dSGreg Clayton         }
13437fdf9ef1SGreg Clayton     }
1344ceb6b139SCaroline Tice 
1345ceb6b139SCaroline Tice     if (log)
1346ceb6b139SCaroline Tice     {
1347481cef25SGreg Clayton         SBStream frame_desc_strm;
1348481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
13494838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1350324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1351324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1352324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1353ceb6b139SCaroline Tice     }
1354ceb6b139SCaroline Tice 
135530fdc8d8SChris Lattner     return sb_frame;
135630fdc8d8SChris Lattner }
135730fdc8d8SChris Lattner 
1358f028a1fbSGreg Clayton lldb::SBFrame
1359f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1360f028a1fbSGreg Clayton {
13615160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1362f028a1fbSGreg Clayton 
1363f028a1fbSGreg Clayton     SBFrame sb_frame;
1364b57e4a1bSJason Molenda     StackFrameSP frame_sp;
13654fc6cb9cSJim Ingham     Mutex::Locker api_locker;
13664fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13674fc6cb9cSJim Ingham 
13681ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1369af67cecdSGreg Clayton     {
13707fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
13717fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13727fdf9ef1SGreg Clayton         {
13731ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1374b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1375af67cecdSGreg Clayton         }
1376c9858e4dSGreg Clayton         else
1377c9858e4dSGreg Clayton         {
1378c9858e4dSGreg Clayton             if (log)
1379324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1380324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1381c9858e4dSGreg Clayton         }
13827fdf9ef1SGreg Clayton     }
1383f028a1fbSGreg Clayton 
1384f028a1fbSGreg Clayton     if (log)
1385f028a1fbSGreg Clayton     {
1386481cef25SGreg Clayton         SBStream frame_desc_strm;
1387481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1388f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1389324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1390324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1391324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1392f028a1fbSGreg Clayton     }
1393f028a1fbSGreg Clayton 
1394f028a1fbSGreg Clayton     return sb_frame;
1395f028a1fbSGreg Clayton }
1396f028a1fbSGreg Clayton 
1397f028a1fbSGreg Clayton lldb::SBFrame
1398f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1399f028a1fbSGreg Clayton {
14005160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1401f028a1fbSGreg Clayton 
1402f028a1fbSGreg Clayton     SBFrame sb_frame;
1403b57e4a1bSJason Molenda     StackFrameSP frame_sp;
14044fc6cb9cSJim Ingham     Mutex::Locker api_locker;
14054fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
14064fc6cb9cSJim Ingham 
14071ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1408f028a1fbSGreg Clayton     {
14097fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
14107fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
14117fdf9ef1SGreg Clayton         {
14121ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
14131ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1414f028a1fbSGreg Clayton             if (frame_sp)
1415f028a1fbSGreg Clayton             {
14161ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1417b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1418f028a1fbSGreg Clayton             }
1419f028a1fbSGreg Clayton         }
1420c9858e4dSGreg Clayton         else
1421c9858e4dSGreg Clayton         {
1422c9858e4dSGreg Clayton             if (log)
1423324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1424324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1425c9858e4dSGreg Clayton         }
14267fdf9ef1SGreg Clayton     }
1427f028a1fbSGreg Clayton 
1428f028a1fbSGreg Clayton     if (log)
1429f028a1fbSGreg Clayton     {
1430481cef25SGreg Clayton         SBStream frame_desc_strm;
1431481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1432f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1433324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1434324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1435324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1436f028a1fbSGreg Clayton     }
1437f028a1fbSGreg Clayton     return sb_frame;
1438f028a1fbSGreg Clayton }
1439f028a1fbSGreg Clayton 
14404f465cffSJim Ingham bool
14414f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
14424f465cffSJim Ingham {
14434f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
14444f465cffSJim Ingham }
14454f465cffSJim Ingham 
14464f465cffSJim Ingham SBFrame
14474f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
14484f465cffSJim Ingham {
14494f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
14504f465cffSJim Ingham 
14514f465cffSJim Ingham }
14524f465cffSJim Ingham 
14534f465cffSJim Ingham SBThread
14544f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
14554f465cffSJim Ingham {
14564f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
14574f465cffSJim Ingham }
1458f028a1fbSGreg Clayton 
145930fdc8d8SChris Lattner bool
146030fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
146130fdc8d8SChris Lattner {
14627fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
146330fdc8d8SChris Lattner }
146430fdc8d8SChris Lattner 
146530fdc8d8SChris Lattner bool
146630fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
146730fdc8d8SChris Lattner {
14687fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
146930fdc8d8SChris Lattner }
1470dde9cff3SCaroline Tice 
1471dde9cff3SCaroline Tice bool
14724f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
14734f465cffSJim Ingham {
14744f465cffSJim Ingham     Stream &strm = status.ref();
14754f465cffSJim Ingham 
14764f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
14774f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
14784f465cffSJim Ingham     {
14794f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
14804f465cffSJim Ingham     }
14814f465cffSJim Ingham     else
14824f465cffSJim Ingham         strm.PutCString ("No status");
14834f465cffSJim Ingham 
14844f465cffSJim Ingham     return true;
14854f465cffSJim Ingham }
14864f465cffSJim Ingham 
14874f465cffSJim Ingham bool
1488ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1489ceb6b139SCaroline Tice {
1490da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1491da7bc7d0SGreg Clayton 
14927fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
14931ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1494ceb6b139SCaroline Tice     {
1495603985fcSJim Ingham         exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, LLDB_INVALID_THREAD_ID);
1496603985fcSJim Ingham         //strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1497ceb6b139SCaroline Tice     }
1498ceb6b139SCaroline Tice     else
1499da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1500ceb6b139SCaroline Tice 
1501ceb6b139SCaroline Tice     return true;
1502ceb6b139SCaroline Tice }
15035dd4916fSJason Molenda 
15045dd4916fSJason Molenda SBThread
1505008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
15065dd4916fSJason Molenda {
15075dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
15085dd4916fSJason Molenda     Mutex::Locker api_locker;
15095dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
15105dd4916fSJason Molenda     SBThread sb_origin_thread;
15115dd4916fSJason Molenda 
15125dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
15135dd4916fSJason Molenda     {
15145dd4916fSJason Molenda         Process::StopLocker stop_locker;
15155dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
15165dd4916fSJason Molenda         {
15177a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
15185dd4916fSJason Molenda             if (real_thread)
15195dd4916fSJason Molenda             {
15205dd4916fSJason Molenda                 ConstString type_const (type);
15217a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
15227a2f7904SJason Molenda                 if (process)
15237a2f7904SJason Molenda                 {
15247a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
15255dd4916fSJason Molenda                     if (runtime)
15265dd4916fSJason Molenda                     {
1527008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1528a6e9130dSJason Molenda                         if (new_thread_sp)
1529a6e9130dSJason Molenda                         {
15307a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
15317a2f7904SJason Molenda                             // object.
15327a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
15337a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1534a6e9130dSJason Molenda                             if (log)
1535a6e9130dSJason Molenda                             {
1536a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1537a6e9130dSJason Molenda                                 if (queue_name == NULL)
1538a6e9130dSJason Molenda                                     queue_name = "";
15392bdbfd50SJim Ingham                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread "
15402bdbfd50SJim Ingham                                              "created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1541324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1542324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1543324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1544324a1036SSaleem Abdulrasool                                              queue_name);
1545a6e9130dSJason Molenda                             }
1546a6e9130dSJason Molenda                         }
15477a2f7904SJason Molenda                     }
15485dd4916fSJason Molenda                 }
15495dd4916fSJason Molenda             }
15505dd4916fSJason Molenda         }
15515dd4916fSJason Molenda         else
15525dd4916fSJason Molenda         {
15535dd4916fSJason Molenda             if (log)
1554324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1555324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
15565dd4916fSJason Molenda         }
15575dd4916fSJason Molenda     }
15585dd4916fSJason Molenda 
1559ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1560324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1561324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
15625dd4916fSJason Molenda     return sb_origin_thread;
15635dd4916fSJason Molenda }
15648ee9cb58SJason Molenda 
15658ee9cb58SJason Molenda uint32_t
15668ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
15678ee9cb58SJason Molenda {
15688ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15698ee9cb58SJason Molenda     if (thread_sp)
15708ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
15718ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
15728ee9cb58SJason Molenda }
1573b4892cd2SJason Molenda 
1574b4892cd2SJason Molenda bool
1575b4892cd2SJason Molenda SBThread::SafeToCallFunctions ()
1576b4892cd2SJason Molenda {
1577b4892cd2SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1578b4892cd2SJason Molenda     if (thread_sp)
1579b4892cd2SJason Molenda         return thread_sp->SafeToCallFunctions();
1580b4892cd2SJason Molenda     return true;
1581b4892cd2SJason Molenda }
15822bdbfd50SJim Ingham 
15832bdbfd50SJim Ingham lldb_private::Thread *
15842bdbfd50SJim Ingham SBThread::operator->()
15852bdbfd50SJim Ingham {
15862bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15872bdbfd50SJim Ingham     if (thread_sp)
15882bdbfd50SJim Ingham         return thread_sp.get();
15892bdbfd50SJim Ingham     else
15902bdbfd50SJim Ingham         return NULL;
15912bdbfd50SJim Ingham }
15922bdbfd50SJim Ingham 
15932bdbfd50SJim Ingham lldb_private::Thread *
15942bdbfd50SJim Ingham SBThread::get()
15952bdbfd50SJim Ingham {
15962bdbfd50SJim Ingham     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
15972bdbfd50SJim Ingham     if (thread_sp)
15982bdbfd50SJim Ingham         return thread_sp.get();
15992bdbfd50SJim Ingham     else
16002bdbfd50SJim Ingham         return NULL;
16012bdbfd50SJim Ingham }
16022bdbfd50SJim Ingham 
1603