130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124c5de699SEli Friedman #include "lldb/API/SBThread.h"
1330fdc8d8SChris Lattner 
1430fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
174e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
186611103cSGreg Clayton #include "lldb/Core/Debugger.h"
19a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2130fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
235dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2630fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2730fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
28f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2930fdc8d8SChris Lattner #include "lldb/Target/Target.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3530fdc8d8SChris Lattner 
3630fdc8d8SChris Lattner 
374c5de699SEli Friedman #include "lldb/API/SBAddress.h"
384c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
394f465cffSJim Ingham #include "lldb/API/SBEvent.h"
4073ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
414c5de699SEli Friedman #include "lldb/API/SBProcess.h"
4273ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4330fdc8d8SChris Lattner 
4430fdc8d8SChris Lattner using namespace lldb;
4530fdc8d8SChris Lattner using namespace lldb_private;
4630fdc8d8SChris Lattner 
474f465cffSJim Ingham const char *
484f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
494f465cffSJim Ingham {
504f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
514f465cffSJim Ingham }
524f465cffSJim Ingham 
53cfd1acedSGreg Clayton //----------------------------------------------------------------------
54cfd1acedSGreg Clayton // Constructors
55cfd1acedSGreg Clayton //----------------------------------------------------------------------
5630fdc8d8SChris Lattner SBThread::SBThread () :
577fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
5830fdc8d8SChris Lattner {
5930fdc8d8SChris Lattner }
6030fdc8d8SChris Lattner 
6130fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
627fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6330fdc8d8SChris Lattner {
6430fdc8d8SChris Lattner }
6530fdc8d8SChris Lattner 
6692ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
677fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
6830fdc8d8SChris Lattner {
697fdf9ef1SGreg Clayton 
7030fdc8d8SChris Lattner }
7130fdc8d8SChris Lattner 
7230fdc8d8SChris Lattner //----------------------------------------------------------------------
73cfd1acedSGreg Clayton // Assignment operator
74cfd1acedSGreg Clayton //----------------------------------------------------------------------
75cfd1acedSGreg Clayton 
76cfd1acedSGreg Clayton const lldb::SBThread &
77cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
78cfd1acedSGreg Clayton {
79cfd1acedSGreg Clayton     if (this != &rhs)
807fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
81cfd1acedSGreg Clayton     return *this;
82cfd1acedSGreg Clayton }
83cfd1acedSGreg Clayton 
84cfd1acedSGreg Clayton //----------------------------------------------------------------------
8530fdc8d8SChris Lattner // Destructor
8630fdc8d8SChris Lattner //----------------------------------------------------------------------
8730fdc8d8SChris Lattner SBThread::~SBThread()
8830fdc8d8SChris Lattner {
8930fdc8d8SChris Lattner }
9030fdc8d8SChris Lattner 
9130fdc8d8SChris Lattner bool
9230fdc8d8SChris Lattner SBThread::IsValid() const
9330fdc8d8SChris Lattner {
947fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
9530fdc8d8SChris Lattner }
9630fdc8d8SChris Lattner 
9748e42549SGreg Clayton void
9848e42549SGreg Clayton SBThread::Clear ()
9948e42549SGreg Clayton {
1007fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
10148e42549SGreg Clayton }
10248e42549SGreg Clayton 
10348e42549SGreg Clayton 
10430fdc8d8SChris Lattner StopReason
10530fdc8d8SChris Lattner SBThread::GetStopReason()
10630fdc8d8SChris Lattner {
1075160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
108ceb6b139SCaroline Tice 
109ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1104fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1114fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1124fc6cb9cSJim Ingham 
1131ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
11430fdc8d8SChris Lattner     {
1157fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1167fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1177fdf9ef1SGreg Clayton         {
11897d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
11930fdc8d8SChris Lattner         }
120c9858e4dSGreg Clayton         else
121c9858e4dSGreg Clayton         {
122c9858e4dSGreg Clayton             if (log)
123c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
124c9858e4dSGreg Clayton         }
1257fdf9ef1SGreg Clayton     }
126ceb6b139SCaroline Tice 
127ceb6b139SCaroline Tice     if (log)
1281ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
129750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
130ceb6b139SCaroline Tice 
131ceb6b139SCaroline Tice     return reason;
13230fdc8d8SChris Lattner }
13330fdc8d8SChris Lattner 
13430fdc8d8SChris Lattner size_t
1354e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1364e78f606SGreg Clayton {
1374fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1384fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1394fc6cb9cSJim Ingham 
1401ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1414e78f606SGreg Clayton     {
1427fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1437fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1447fdf9ef1SGreg Clayton         {
1451ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1464e78f606SGreg Clayton             if (stop_info_sp)
1474e78f606SGreg Clayton             {
1484e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1494e78f606SGreg Clayton                 switch (reason)
1504e78f606SGreg Clayton                 {
1514e78f606SGreg Clayton                 case eStopReasonInvalid:
1524e78f606SGreg Clayton                 case eStopReasonNone:
1534e78f606SGreg Clayton                 case eStopReasonTrace:
15490ba8115SGreg Clayton                 case eStopReasonExec:
1554e78f606SGreg Clayton                 case eStopReasonPlanComplete:
156f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
1574e78f606SGreg Clayton                     // There is no data for these stop reasons.
1584e78f606SGreg Clayton                     return 0;
1594e78f606SGreg Clayton 
1604e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1614e78f606SGreg Clayton                     {
1624e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1631ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1644e78f606SGreg Clayton                         if (bp_site_sp)
1654e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1664e78f606SGreg Clayton                         else
1674e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1684e78f606SGreg Clayton                     }
1694e78f606SGreg Clayton                     break;
1704e78f606SGreg Clayton 
1714e78f606SGreg Clayton                 case eStopReasonWatchpoint:
172290fa41bSJohnny Chen                     return 1;
1734e78f606SGreg Clayton 
1744e78f606SGreg Clayton                 case eStopReasonSignal:
1754e78f606SGreg Clayton                     return 1;
1764e78f606SGreg Clayton 
1774e78f606SGreg Clayton                 case eStopReasonException:
1784e78f606SGreg Clayton                     return 1;
1794e78f606SGreg Clayton                 }
1804e78f606SGreg Clayton             }
1814e78f606SGreg Clayton         }
182c9858e4dSGreg Clayton         else
183c9858e4dSGreg Clayton         {
1845160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
185c9858e4dSGreg Clayton             if (log)
186c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
187c9858e4dSGreg Clayton         }
1887fdf9ef1SGreg Clayton     }
1894e78f606SGreg Clayton     return 0;
1904e78f606SGreg Clayton }
1914e78f606SGreg Clayton 
1924e78f606SGreg Clayton uint64_t
1934e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1944e78f606SGreg Clayton {
1954fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1964fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1974fc6cb9cSJim Ingham 
1981ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1994e78f606SGreg Clayton     {
2007fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2017fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2027fdf9ef1SGreg Clayton         {
2031ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2041ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2054e78f606SGreg Clayton             if (stop_info_sp)
2064e78f606SGreg Clayton             {
2074e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2084e78f606SGreg Clayton                 switch (reason)
2094e78f606SGreg Clayton                 {
2104e78f606SGreg Clayton                 case eStopReasonInvalid:
2114e78f606SGreg Clayton                 case eStopReasonNone:
2124e78f606SGreg Clayton                 case eStopReasonTrace:
21390ba8115SGreg Clayton                 case eStopReasonExec:
2144e78f606SGreg Clayton                 case eStopReasonPlanComplete:
215f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
2164e78f606SGreg Clayton                     // There is no data for these stop reasons.
2174e78f606SGreg Clayton                     return 0;
2184e78f606SGreg Clayton 
2194e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2204e78f606SGreg Clayton                     {
2214e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2221ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2234e78f606SGreg Clayton                         if (bp_site_sp)
2244e78f606SGreg Clayton                         {
2254e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2264e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2274e78f606SGreg Clayton                             if (bp_loc_sp)
2284e78f606SGreg Clayton                             {
2294e78f606SGreg Clayton                                 if (bp_index & 1)
2304e78f606SGreg Clayton                                 {
2314e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2324e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2334e78f606SGreg Clayton                                 }
2344e78f606SGreg Clayton                                 else
2354e78f606SGreg Clayton                                 {
2364e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2374e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2384e78f606SGreg Clayton                                 }
2394e78f606SGreg Clayton                             }
2404e78f606SGreg Clayton                         }
2414e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2424e78f606SGreg Clayton                     }
2434e78f606SGreg Clayton                     break;
2444e78f606SGreg Clayton 
2454e78f606SGreg Clayton                 case eStopReasonWatchpoint:
246290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2474e78f606SGreg Clayton 
2484e78f606SGreg Clayton                 case eStopReasonSignal:
2494e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2504e78f606SGreg Clayton 
2514e78f606SGreg Clayton                 case eStopReasonException:
2524e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2534e78f606SGreg Clayton                 }
2544e78f606SGreg Clayton             }
2554e78f606SGreg Clayton         }
256c9858e4dSGreg Clayton         else
257c9858e4dSGreg Clayton         {
2585160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
259c9858e4dSGreg Clayton             if (log)
260c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
261c9858e4dSGreg Clayton         }
2627fdf9ef1SGreg Clayton     }
2634e78f606SGreg Clayton     return 0;
2644e78f606SGreg Clayton }
2654e78f606SGreg Clayton 
2664e78f606SGreg Clayton size_t
26730fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
26830fdc8d8SChris Lattner {
2695160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
270ceb6b139SCaroline Tice 
2714fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2724fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2734fc6cb9cSJim Ingham 
2741ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
27530fdc8d8SChris Lattner     {
2767fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2777fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2787fdf9ef1SGreg Clayton         {
2797fdf9ef1SGreg Clayton 
2801ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
281b15bfc75SJim Ingham             if (stop_info_sp)
28230fdc8d8SChris Lattner             {
283b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
28430fdc8d8SChris Lattner                 if (stop_desc)
28530fdc8d8SChris Lattner                 {
286ceb6b139SCaroline Tice                     if (log)
2874838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2881ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
28930fdc8d8SChris Lattner                     if (dst)
29030fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
29130fdc8d8SChris Lattner                     else
29230fdc8d8SChris Lattner                     {
29330fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
29430fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
29530fdc8d8SChris Lattner                     }
29630fdc8d8SChris Lattner                 }
29730fdc8d8SChris Lattner                 else
29830fdc8d8SChris Lattner                 {
29930fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
300b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
30130fdc8d8SChris Lattner                     {
30230fdc8d8SChris Lattner                     case eStopReasonTrace:
30330fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
30430fdc8d8SChris Lattner                         {
30530fdc8d8SChris Lattner                             static char trace_desc[] = "step";
30630fdc8d8SChris Lattner                             stop_desc = trace_desc;
30730fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
30830fdc8d8SChris Lattner                         }
30930fdc8d8SChris Lattner                         break;
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
31230fdc8d8SChris Lattner                         {
31330fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
31430fdc8d8SChris Lattner                             stop_desc = bp_desc;
31530fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
31630fdc8d8SChris Lattner                         }
31730fdc8d8SChris Lattner                         break;
31830fdc8d8SChris Lattner 
31930fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
32030fdc8d8SChris Lattner                         {
32130fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
32230fdc8d8SChris Lattner                             stop_desc = wp_desc;
32330fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
32430fdc8d8SChris Lattner                         }
32530fdc8d8SChris Lattner                         break;
32630fdc8d8SChris Lattner 
32730fdc8d8SChris Lattner                     case eStopReasonSignal:
32830fdc8d8SChris Lattner                         {
3291ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
33030fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
33130fdc8d8SChris Lattner                             {
33230fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
33330fdc8d8SChris Lattner                                 stop_desc = signal_desc;
33430fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
33530fdc8d8SChris Lattner                             }
33630fdc8d8SChris Lattner                         }
33730fdc8d8SChris Lattner                         break;
33830fdc8d8SChris Lattner 
33930fdc8d8SChris Lattner                     case eStopReasonException:
34030fdc8d8SChris Lattner                         {
34130fdc8d8SChris Lattner                             char exc_desc[] = "exception";
34230fdc8d8SChris Lattner                             stop_desc = exc_desc;
34330fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
34430fdc8d8SChris Lattner                         }
34530fdc8d8SChris Lattner                         break;
346c982c768SGreg Clayton 
34790ba8115SGreg Clayton                     case eStopReasonExec:
34890ba8115SGreg Clayton                         {
34990ba8115SGreg Clayton                             char exc_desc[] = "exec";
35090ba8115SGreg Clayton                             stop_desc = exc_desc;
35190ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
35290ba8115SGreg Clayton                         }
35390ba8115SGreg Clayton                         break;
35490ba8115SGreg Clayton 
355f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
356f85defaeSAndrew Kaylor                         {
357f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
358f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
359f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
360f85defaeSAndrew Kaylor                         }
361f85defaeSAndrew Kaylor                         break;
362c982c768SGreg Clayton                     default:
363c982c768SGreg Clayton                         break;
36430fdc8d8SChris Lattner                     }
36530fdc8d8SChris Lattner 
36630fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
36730fdc8d8SChris Lattner                     {
368ceb6b139SCaroline Tice                         if (log)
36993aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3701ac04c30SGreg Clayton                                          exe_ctx.GetThreadPtr(), stop_desc);
371ceb6b139SCaroline Tice 
37230fdc8d8SChris Lattner                         if (dst)
37330fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
37430fdc8d8SChris Lattner 
37530fdc8d8SChris Lattner                         if (stop_desc_len == 0)
37630fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner                         return stop_desc_len;
37930fdc8d8SChris Lattner                     }
38030fdc8d8SChris Lattner                 }
38130fdc8d8SChris Lattner             }
38230fdc8d8SChris Lattner         }
383c9858e4dSGreg Clayton         else
384c9858e4dSGreg Clayton         {
3855160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
386c9858e4dSGreg Clayton             if (log)
387c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
388c9858e4dSGreg Clayton         }
3897fdf9ef1SGreg Clayton     }
39030fdc8d8SChris Lattner     if (dst)
39130fdc8d8SChris Lattner         *dst = 0;
39230fdc8d8SChris Lattner     return 0;
39330fdc8d8SChris Lattner }
39430fdc8d8SChris Lattner 
39573ca05a2SJim Ingham SBValue
39673ca05a2SJim Ingham SBThread::GetStopReturnValue ()
39773ca05a2SJim Ingham {
3985160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
39973ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
4004fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4014fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4024fc6cb9cSJim Ingham 
4031ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
40473ca05a2SJim Ingham     {
4057fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4067fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4077fdf9ef1SGreg Clayton         {
4081ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
40973ca05a2SJim Ingham             if (stop_info_sp)
41073ca05a2SJim Ingham             {
41173ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
41273ca05a2SJim Ingham             }
41373ca05a2SJim Ingham         }
414c9858e4dSGreg Clayton         else
415c9858e4dSGreg Clayton         {
416c9858e4dSGreg Clayton             if (log)
417c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
418c9858e4dSGreg Clayton         }
4197fdf9ef1SGreg Clayton     }
42073ca05a2SJim Ingham 
42173ca05a2SJim Ingham     if (log)
4221ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
42373ca05a2SJim Ingham                                                                   return_valobj_sp.get()
42473ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
42573ca05a2SJim Ingham                                                                         : "<no return value>");
42673ca05a2SJim Ingham 
42773ca05a2SJim Ingham     return SBValue (return_valobj_sp);
42873ca05a2SJim Ingham }
42973ca05a2SJim Ingham 
43030fdc8d8SChris Lattner void
43130fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
43230fdc8d8SChris Lattner {
4337fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
43430fdc8d8SChris Lattner }
43530fdc8d8SChris Lattner 
43630fdc8d8SChris Lattner lldb::tid_t
43730fdc8d8SChris Lattner SBThread::GetThreadID () const
43830fdc8d8SChris Lattner {
4397fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44017a6ad05SGreg Clayton     if (thread_sp)
4411ac04c30SGreg Clayton         return thread_sp->GetID();
4421ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
44330fdc8d8SChris Lattner }
44430fdc8d8SChris Lattner 
44530fdc8d8SChris Lattner uint32_t
44630fdc8d8SChris Lattner SBThread::GetIndexID () const
44730fdc8d8SChris Lattner {
4487fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44917a6ad05SGreg Clayton     if (thread_sp)
45017a6ad05SGreg Clayton         return thread_sp->GetIndexID();
45130fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
45230fdc8d8SChris Lattner }
4531ac04c30SGreg Clayton 
45430fdc8d8SChris Lattner const char *
45530fdc8d8SChris Lattner SBThread::GetName () const
45630fdc8d8SChris Lattner {
4575160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4584838131bSGreg Clayton     const char *name = NULL;
4594fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4604fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4614fc6cb9cSJim Ingham 
4621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
463af67cecdSGreg Clayton     {
4647fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4657fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4667fdf9ef1SGreg Clayton         {
4671ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
468af67cecdSGreg Clayton         }
469c9858e4dSGreg Clayton         else
470c9858e4dSGreg Clayton         {
471c9858e4dSGreg Clayton             if (log)
472c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
473c9858e4dSGreg Clayton         }
4747fdf9ef1SGreg Clayton     }
475ceb6b139SCaroline Tice 
476ceb6b139SCaroline Tice     if (log)
4771ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
478ceb6b139SCaroline Tice 
4794838131bSGreg Clayton     return name;
48030fdc8d8SChris Lattner }
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner const char *
48330fdc8d8SChris Lattner SBThread::GetQueueName () const
48430fdc8d8SChris Lattner {
4854838131bSGreg Clayton     const char *name = NULL;
4864fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4874fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4884fc6cb9cSJim Ingham 
4895160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
491af67cecdSGreg Clayton     {
4927fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4937fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4947fdf9ef1SGreg Clayton         {
4951ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
496af67cecdSGreg Clayton         }
497c9858e4dSGreg Clayton         else
498c9858e4dSGreg Clayton         {
499c9858e4dSGreg Clayton             if (log)
500c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
501c9858e4dSGreg Clayton         }
5027fdf9ef1SGreg Clayton     }
503ceb6b139SCaroline Tice 
504ceb6b139SCaroline Tice     if (log)
5051ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
506ceb6b139SCaroline Tice 
5074838131bSGreg Clayton     return name;
50830fdc8d8SChris Lattner }
50930fdc8d8SChris Lattner 
5104fdb5863SJason Molenda lldb::queue_id_t
5114fdb5863SJason Molenda SBThread::GetQueueID () const
5124fdb5863SJason Molenda {
5134fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
5144fdb5863SJason Molenda     Mutex::Locker api_locker;
5154fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5164fdb5863SJason Molenda 
5174fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5184fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
5194fdb5863SJason Molenda     {
5204fdb5863SJason Molenda         Process::StopLocker stop_locker;
5214fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5224fdb5863SJason Molenda         {
5234fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
5244fdb5863SJason Molenda         }
5254fdb5863SJason Molenda         else
5264fdb5863SJason Molenda         {
5274fdb5863SJason Molenda             if (log)
5284fdb5863SJason Molenda                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", exe_ctx.GetThreadPtr());
5294fdb5863SJason Molenda         }
5304fdb5863SJason Molenda     }
5314fdb5863SJason Molenda 
5324fdb5863SJason Molenda     if (log)
5334fdb5863SJason Molenda         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, exe_ctx.GetThreadPtr(), id);
5344fdb5863SJason Molenda 
5354fdb5863SJason Molenda     return id;
5364fdb5863SJason Molenda }
5374fdb5863SJason Molenda 
53864e7ead1SJim Ingham SBError
53964e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
54064e7ead1SJim Ingham {
54164e7ead1SJim Ingham     SBError sb_error;
54264e7ead1SJim Ingham 
54364e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
54464e7ead1SJim Ingham     if (!process)
54564e7ead1SJim Ingham     {
54664e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
54764e7ead1SJim Ingham         return sb_error;
54864e7ead1SJim Ingham     }
54964e7ead1SJim Ingham 
55064e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
55164e7ead1SJim Ingham     if (!thread)
55264e7ead1SJim Ingham     {
55364e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
55464e7ead1SJim Ingham         return sb_error;
55564e7ead1SJim Ingham     }
55664e7ead1SJim Ingham 
55764e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
55864e7ead1SJim Ingham     // then a "continue" will resume the plan.
55964e7ead1SJim Ingham     if (new_plan != NULL)
56064e7ead1SJim Ingham     {
56164e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
56264e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
56364e7ead1SJim Ingham     }
56464e7ead1SJim Ingham 
56564e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
56664e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
56764e7ead1SJim Ingham     sb_error.ref() = process->Resume();
56864e7ead1SJim Ingham 
56964e7ead1SJim Ingham     if (sb_error.Success())
57064e7ead1SJim Ingham     {
57164e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
57264e7ead1SJim Ingham         // process to stop yet again!
57364e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
57464e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
57564e7ead1SJim Ingham     }
57664e7ead1SJim Ingham 
57764e7ead1SJim Ingham     return sb_error;
57864e7ead1SJim Ingham }
57930fdc8d8SChris Lattner 
58030fdc8d8SChris Lattner void
58130fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
58230fdc8d8SChris Lattner {
5835160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
584ceb6b139SCaroline Tice 
5854fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5864fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5874fc6cb9cSJim Ingham 
58817a6ad05SGreg Clayton 
589ceb6b139SCaroline Tice     if (log)
5901ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
591ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
592ceb6b139SCaroline Tice 
5931ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
59430fdc8d8SChris Lattner     {
5951ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5967ba6e991SJim Ingham         bool abort_other_plans = false;
597b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
59830fdc8d8SChris Lattner 
5994d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
60030fdc8d8SChris Lattner         if (frame_sp)
60130fdc8d8SChris Lattner         {
60230fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
60330fdc8d8SChris Lattner             {
6044b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
60530fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
6064d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
60730fdc8d8SChris Lattner                                                                     sc.line_entry.range,
60830fdc8d8SChris Lattner                                                                     sc,
6094b4b2478SJim Ingham                                                                     stop_other_threads,
6104b4b2478SJim Ingham                                                                     avoid_no_debug);
61130fdc8d8SChris Lattner             }
61230fdc8d8SChris Lattner             else
61330fdc8d8SChris Lattner             {
6144d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
61530fdc8d8SChris Lattner                                                                             abort_other_plans,
61630fdc8d8SChris Lattner                                                                             stop_other_threads);
61730fdc8d8SChris Lattner             }
61830fdc8d8SChris Lattner         }
61930fdc8d8SChris Lattner 
62064e7ead1SJim Ingham         // This returns an error, we should use it!
6214d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
62230fdc8d8SChris Lattner     }
62330fdc8d8SChris Lattner }
62430fdc8d8SChris Lattner 
62530fdc8d8SChris Lattner void
62630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
62730fdc8d8SChris Lattner {
628c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
629c627682eSJim Ingham }
630c627682eSJim Ingham 
631c627682eSJim Ingham void
632c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
633c627682eSJim Ingham {
6345160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
635ceb6b139SCaroline Tice 
6364fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6374fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
63817a6ad05SGreg Clayton 
63917a6ad05SGreg Clayton     if (log)
640c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
641c627682eSJim Ingham                      exe_ctx.GetThreadPtr(),
642c627682eSJim Ingham                      target_name? target_name: "<NULL>",
64317a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
644c627682eSJim Ingham 
6451ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
64630fdc8d8SChris Lattner     {
6477ba6e991SJim Ingham         bool abort_other_plans = false;
64830fdc8d8SChris Lattner 
6491ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
650b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
6514d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
65230fdc8d8SChris Lattner 
65330fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
65430fdc8d8SChris Lattner         {
6554b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
6564b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
65730fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
6584d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
65930fdc8d8SChris Lattner                                                               sc.line_entry.range,
66030fdc8d8SChris Lattner                                                               sc,
661c627682eSJim Ingham                                                               target_name,
662474966a4SGreg Clayton                                                               stop_other_threads,
6634b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
6644b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
66530fdc8d8SChris Lattner         }
66630fdc8d8SChris Lattner         else
66730fdc8d8SChris Lattner         {
6684d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
66930fdc8d8SChris Lattner                                                                         abort_other_plans,
67030fdc8d8SChris Lattner                                                                         stop_other_threads);
67130fdc8d8SChris Lattner         }
67230fdc8d8SChris Lattner 
67364e7ead1SJim Ingham         // This returns an error, we should use it!
6744d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
67530fdc8d8SChris Lattner     }
67630fdc8d8SChris Lattner }
67730fdc8d8SChris Lattner 
67830fdc8d8SChris Lattner void
67930fdc8d8SChris Lattner SBThread::StepOut ()
68030fdc8d8SChris Lattner {
6815160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
682ceb6b139SCaroline Tice 
6834fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6844fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6854fc6cb9cSJim Ingham 
686ceb6b139SCaroline Tice 
68717a6ad05SGreg Clayton     if (log)
6881ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
68917a6ad05SGreg Clayton 
6901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
69130fdc8d8SChris Lattner     {
6927ba6e991SJim Ingham         bool abort_other_plans = false;
69394b09246SJim Ingham         bool stop_other_threads = false;
69430fdc8d8SChris Lattner 
6951ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6961ac04c30SGreg Clayton 
6974b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
6984d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
699481cef25SGreg Clayton                                                                   NULL,
700481cef25SGreg Clayton                                                                   false,
701481cef25SGreg Clayton                                                                   stop_other_threads,
702481cef25SGreg Clayton                                                                   eVoteYes,
703481cef25SGreg Clayton                                                                   eVoteNoOpinion,
7044b4b2478SJim Ingham                                                                   0,
7054b4b2478SJim Ingham                                                                   avoid_no_debug));
706481cef25SGreg Clayton 
70764e7ead1SJim Ingham         // This returns an error, we should use it!
7084d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
709481cef25SGreg Clayton     }
710481cef25SGreg Clayton }
711481cef25SGreg Clayton 
712481cef25SGreg Clayton void
713481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
714481cef25SGreg Clayton {
7155160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
716481cef25SGreg Clayton 
7174fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7184fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7194fc6cb9cSJim Ingham 
720b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
721481cef25SGreg Clayton     if (log)
722481cef25SGreg Clayton     {
723481cef25SGreg Clayton         SBStream frame_desc_strm;
724481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
7251ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
726481cef25SGreg Clayton     }
727481cef25SGreg Clayton 
7281ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
729481cef25SGreg Clayton     {
7307ba6e991SJim Ingham         bool abort_other_plans = false;
73194b09246SJim Ingham         bool stop_other_threads = false;
7321ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
733481cef25SGreg Clayton 
7344d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
735481cef25SGreg Clayton                                                                     NULL,
736481cef25SGreg Clayton                                                                     false,
737481cef25SGreg Clayton                                                                     stop_other_threads,
738481cef25SGreg Clayton                                                                     eVoteYes,
739481cef25SGreg Clayton                                                                     eVoteNoOpinion,
7404d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
74130fdc8d8SChris Lattner 
74264e7ead1SJim Ingham         // This returns an error, we should use it!
7434d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
74430fdc8d8SChris Lattner     }
74530fdc8d8SChris Lattner }
74630fdc8d8SChris Lattner 
74730fdc8d8SChris Lattner void
74830fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
74930fdc8d8SChris Lattner {
7505160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
751ceb6b139SCaroline Tice 
7524fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7534fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7544fc6cb9cSJim Ingham 
7551ac04c30SGreg Clayton 
756ceb6b139SCaroline Tice 
75717a6ad05SGreg Clayton     if (log)
7581ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
75917a6ad05SGreg Clayton 
7601ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
76130fdc8d8SChris Lattner     {
7621ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7634d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
76464e7ead1SJim Ingham 
76564e7ead1SJim Ingham         // This returns an error, we should use it!
7664d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
76730fdc8d8SChris Lattner     }
76830fdc8d8SChris Lattner }
76930fdc8d8SChris Lattner 
77030fdc8d8SChris Lattner void
77130fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
77230fdc8d8SChris Lattner {
7735160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
774ceb6b139SCaroline Tice 
7754fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7764fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7774fc6cb9cSJim Ingham 
778ceb6b139SCaroline Tice 
77917a6ad05SGreg Clayton     if (log)
780d01b2953SDaniel Malea         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
78117a6ad05SGreg Clayton 
7821ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
78330fdc8d8SChris Lattner     {
7847ba6e991SJim Ingham         bool abort_other_plans = false;
78530fdc8d8SChris Lattner         bool stop_other_threads = true;
78630fdc8d8SChris Lattner 
787e72dfb32SGreg Clayton         Address target_addr (addr);
78830fdc8d8SChris Lattner 
7891ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7901ac04c30SGreg Clayton 
7914d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
79264e7ead1SJim Ingham 
79364e7ead1SJim Ingham         // This returns an error, we should use it!
7944d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
79530fdc8d8SChris Lattner     }
79630fdc8d8SChris Lattner }
79730fdc8d8SChris Lattner 
798481cef25SGreg Clayton SBError
799481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
800481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
801481cef25SGreg Clayton                          uint32_t line)
802481cef25SGreg Clayton {
803481cef25SGreg Clayton     SBError sb_error;
8045160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
805481cef25SGreg Clayton     char path[PATH_MAX];
806481cef25SGreg Clayton 
8074fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8084fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8094fc6cb9cSJim Ingham 
810b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
81117a6ad05SGreg Clayton 
812481cef25SGreg Clayton     if (log)
813481cef25SGreg Clayton     {
814481cef25SGreg Clayton         SBStream frame_desc_strm;
815481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
816481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
817481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
8181ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
819b9556accSGreg Clayton                      frame_sp.get(),
820481cef25SGreg Clayton                      frame_desc_strm.GetData(),
821481cef25SGreg Clayton                      path, line);
822481cef25SGreg Clayton     }
823481cef25SGreg Clayton 
8241ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
825481cef25SGreg Clayton     {
8261ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
8271ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
828481cef25SGreg Clayton 
829481cef25SGreg Clayton         if (line == 0)
830481cef25SGreg Clayton         {
831481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
832481cef25SGreg Clayton             return sb_error;
833481cef25SGreg Clayton         }
834481cef25SGreg Clayton 
835b9556accSGreg Clayton         if (!frame_sp)
836481cef25SGreg Clayton         {
8371ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
838481cef25SGreg Clayton             if (!frame_sp)
8391ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
840481cef25SGreg Clayton         }
841481cef25SGreg Clayton 
842481cef25SGreg Clayton         SymbolContext frame_sc;
843481cef25SGreg Clayton         if (!frame_sp)
844481cef25SGreg Clayton         {
845481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
846481cef25SGreg Clayton             return sb_error;
847481cef25SGreg Clayton         }
848481cef25SGreg Clayton 
849481cef25SGreg Clayton         // If we have a frame, get its line
850481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
851481cef25SGreg Clayton                                                eSymbolContextFunction  |
852481cef25SGreg Clayton                                                eSymbolContextLineEntry |
853481cef25SGreg Clayton                                                eSymbolContextSymbol    );
854481cef25SGreg Clayton 
855481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
856481cef25SGreg Clayton         {
857481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
858481cef25SGreg Clayton             return sb_error;
859481cef25SGreg Clayton         }
860481cef25SGreg Clayton 
861481cef25SGreg Clayton         FileSpec step_file_spec;
862481cef25SGreg Clayton         if (sb_file_spec.IsValid())
863481cef25SGreg Clayton         {
864481cef25SGreg Clayton             // The file spec passed in was valid, so use it
865481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
866481cef25SGreg Clayton         }
867481cef25SGreg Clayton         else
868481cef25SGreg Clayton         {
869481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
870481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
871481cef25SGreg Clayton             else
872481cef25SGreg Clayton             {
873481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
874481cef25SGreg Clayton                 return sb_error;
875481cef25SGreg Clayton             }
876481cef25SGreg Clayton         }
877481cef25SGreg Clayton 
8789b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
8799b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
8809b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
8819b70ddb3SJim Ingham         // error message.
8829b70ddb3SJim Ingham 
8839b70ddb3SJim Ingham         bool all_in_function = true;
8849b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
8859b70ddb3SJim Ingham 
886481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
8877ba6e991SJim Ingham         const bool abort_other_plans = false;
888c02e3344SJim Ingham         const bool stop_other_threads = false;
889481cef25SGreg Clayton         const bool check_inlines = true;
890481cef25SGreg Clayton         const bool exact = false;
891481cef25SGreg Clayton 
892481cef25SGreg Clayton         SymbolContextList sc_list;
8939b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
8949b70ddb3SJim Ingham                                                                                line,
8959b70ddb3SJim Ingham                                                                                check_inlines,
8969b70ddb3SJim Ingham                                                                                exact,
8979b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
8989b70ddb3SJim Ingham                                                                                sc_list);
899481cef25SGreg Clayton         if (num_matches > 0)
900481cef25SGreg Clayton         {
901481cef25SGreg Clayton             SymbolContext sc;
902481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
903481cef25SGreg Clayton             {
904481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
905481cef25SGreg Clayton                 {
9069b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
907481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
908481cef25SGreg Clayton                     {
9099b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
910481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
9119b70ddb3SJim Ingham                         else
9129b70ddb3SJim Ingham                             all_in_function = false;
913481cef25SGreg Clayton                     }
914481cef25SGreg Clayton                 }
915481cef25SGreg Clayton             }
916481cef25SGreg Clayton         }
917481cef25SGreg Clayton 
918481cef25SGreg Clayton         if (step_over_until_addrs.empty())
919481cef25SGreg Clayton         {
9209b70ddb3SJim Ingham             if (all_in_function)
9219b70ddb3SJim Ingham             {
922481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
923fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
924481cef25SGreg Clayton             }
925481cef25SGreg Clayton             else
92686edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
9279b70ddb3SJim Ingham         }
9289b70ddb3SJim Ingham         else
929481cef25SGreg Clayton         {
9304d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
931481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
932481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
933481cef25SGreg Clayton                                                                         stop_other_threads,
9344d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
935481cef25SGreg Clayton 
9364d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
937481cef25SGreg Clayton         }
938481cef25SGreg Clayton     }
939481cef25SGreg Clayton     else
940481cef25SGreg Clayton     {
941481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
942481cef25SGreg Clayton     }
943481cef25SGreg Clayton     return sb_error;
944481cef25SGreg Clayton }
945481cef25SGreg Clayton 
9464413758cSJim Ingham SBError
947f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
948f86248d9SRichard Mitton {
949f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
950f86248d9SRichard Mitton     SBError sb_error;
951f86248d9SRichard Mitton 
952f86248d9SRichard Mitton     Mutex::Locker api_locker;
953f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
954f86248d9SRichard Mitton 
955f86248d9SRichard Mitton     if (log)
956f86248d9SRichard Mitton         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", exe_ctx.GetThreadPtr(), file_spec->GetPath().c_str(), line);
957f86248d9SRichard Mitton 
958f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
959f86248d9SRichard Mitton     {
960f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
961f86248d9SRichard Mitton         return sb_error;
962f86248d9SRichard Mitton     }
963f86248d9SRichard Mitton 
964f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
965f86248d9SRichard Mitton 
966f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
967f86248d9SRichard Mitton     sb_error.SetError (err);
968f86248d9SRichard Mitton     return sb_error;
969f86248d9SRichard Mitton }
970f86248d9SRichard Mitton 
971f86248d9SRichard Mitton SBError
972cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
9734413758cSJim Ingham {
9744413758cSJim Ingham     SBError sb_error;
9754413758cSJim Ingham 
9765160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9774413758cSJim Ingham 
9784413758cSJim Ingham     Mutex::Locker api_locker;
9794413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9804413758cSJim Ingham 
9814413758cSJim Ingham 
9824413758cSJim Ingham     if (log)
983cb640dd8SJim Ingham         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
9844413758cSJim Ingham 
9854413758cSJim Ingham     if (exe_ctx.HasThreadScope())
9864413758cSJim Ingham     {
9874413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
988cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9894413758cSJim Ingham     }
9904413758cSJim Ingham 
9914413758cSJim Ingham     return sb_error;
9924413758cSJim Ingham }
9934413758cSJim Ingham 
994481cef25SGreg Clayton 
995722a0cdcSGreg Clayton bool
996722a0cdcSGreg Clayton SBThread::Suspend()
997722a0cdcSGreg Clayton {
9985160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9997fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1000c9858e4dSGreg Clayton     bool result = false;
10011ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1002722a0cdcSGreg Clayton     {
1003c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1004c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1005c9858e4dSGreg Clayton         {
10061ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1007c9858e4dSGreg Clayton             result = true;
1008722a0cdcSGreg Clayton         }
1009c9858e4dSGreg Clayton         else
1010c9858e4dSGreg Clayton         {
1011c9858e4dSGreg Clayton             if (log)
1012c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
1013c9858e4dSGreg Clayton         }
1014c9858e4dSGreg Clayton     }
1015c9858e4dSGreg Clayton     if (log)
1016c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
1017c9858e4dSGreg Clayton     return result;
1018722a0cdcSGreg Clayton }
1019722a0cdcSGreg Clayton 
1020722a0cdcSGreg Clayton bool
1021722a0cdcSGreg Clayton SBThread::Resume ()
1022722a0cdcSGreg Clayton {
10235160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10247fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1025c9858e4dSGreg Clayton     bool result = false;
10261ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1027722a0cdcSGreg Clayton     {
1028c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1029c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1030c9858e4dSGreg Clayton         {
1031*6c9ed91cSJim Ingham             const bool override_suspend = true;
1032*6c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1033c9858e4dSGreg Clayton             result = true;
1034722a0cdcSGreg Clayton         }
1035c9858e4dSGreg Clayton         else
1036c9858e4dSGreg Clayton         {
1037c9858e4dSGreg Clayton             if (log)
1038c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
1039c9858e4dSGreg Clayton         }
1040c9858e4dSGreg Clayton     }
1041c9858e4dSGreg Clayton     if (log)
1042c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
1043c9858e4dSGreg Clayton     return result;
1044722a0cdcSGreg Clayton }
1045722a0cdcSGreg Clayton 
1046722a0cdcSGreg Clayton bool
1047722a0cdcSGreg Clayton SBThread::IsSuspended()
1048722a0cdcSGreg Clayton {
10497fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10501ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
10511ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1052722a0cdcSGreg Clayton     return false;
1053722a0cdcSGreg Clayton }
1054722a0cdcSGreg Clayton 
1055a75418dbSAndrew Kaylor bool
1056a75418dbSAndrew Kaylor SBThread::IsStopped()
1057a75418dbSAndrew Kaylor {
1058a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1059a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1060a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1061a75418dbSAndrew Kaylor     return false;
1062a75418dbSAndrew Kaylor }
1063a75418dbSAndrew Kaylor 
106430fdc8d8SChris Lattner SBProcess
106530fdc8d8SChris Lattner SBThread::GetProcess ()
106630fdc8d8SChris Lattner {
1067b9556accSGreg Clayton     SBProcess sb_process;
10687fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10691ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
107030fdc8d8SChris Lattner     {
107130fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
10721ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
107330fdc8d8SChris Lattner     }
1074ceb6b139SCaroline Tice 
10755160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1076ceb6b139SCaroline Tice     if (log)
1077ceb6b139SCaroline Tice     {
1078481cef25SGreg Clayton         SBStream frame_desc_strm;
1079b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
10801ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
10810a2df227SEnrico Granata                      sb_process.GetSP().get(), frame_desc_strm.GetData());
1082ceb6b139SCaroline Tice     }
1083ceb6b139SCaroline Tice 
1084b9556accSGreg Clayton     return sb_process;
108530fdc8d8SChris Lattner }
108630fdc8d8SChris Lattner 
108730fdc8d8SChris Lattner uint32_t
108830fdc8d8SChris Lattner SBThread::GetNumFrames ()
108930fdc8d8SChris Lattner {
10905160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1091ceb6b139SCaroline Tice 
1092ceb6b139SCaroline Tice     uint32_t num_frames = 0;
10934fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10944fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10954fc6cb9cSJim Ingham 
10961ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1097af67cecdSGreg Clayton     {
10987fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10997fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11007fdf9ef1SGreg Clayton         {
11011ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1102af67cecdSGreg Clayton         }
1103c9858e4dSGreg Clayton         else
1104c9858e4dSGreg Clayton         {
1105c9858e4dSGreg Clayton             if (log)
1106c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1107c9858e4dSGreg Clayton         }
11087fdf9ef1SGreg Clayton     }
1109ceb6b139SCaroline Tice 
1110ceb6b139SCaroline Tice     if (log)
11111ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1112ceb6b139SCaroline Tice 
1113ceb6b139SCaroline Tice     return num_frames;
111430fdc8d8SChris Lattner }
111530fdc8d8SChris Lattner 
111630fdc8d8SChris Lattner SBFrame
111730fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
111830fdc8d8SChris Lattner {
11195160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1120ceb6b139SCaroline Tice 
112130fdc8d8SChris Lattner     SBFrame sb_frame;
1122b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11234fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11244fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11254fc6cb9cSJim Ingham 
11261ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1127af67cecdSGreg Clayton     {
11287fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11297fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11307fdf9ef1SGreg Clayton         {
11311ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1132b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1133af67cecdSGreg Clayton         }
1134c9858e4dSGreg Clayton         else
1135c9858e4dSGreg Clayton         {
1136c9858e4dSGreg Clayton             if (log)
1137c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1138c9858e4dSGreg Clayton         }
11397fdf9ef1SGreg Clayton     }
1140ceb6b139SCaroline Tice 
1141ceb6b139SCaroline Tice     if (log)
1142ceb6b139SCaroline Tice     {
1143481cef25SGreg Clayton         SBStream frame_desc_strm;
1144481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
11454838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
11461ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1147ceb6b139SCaroline Tice     }
1148ceb6b139SCaroline Tice 
114930fdc8d8SChris Lattner     return sb_frame;
115030fdc8d8SChris Lattner }
115130fdc8d8SChris Lattner 
1152f028a1fbSGreg Clayton lldb::SBFrame
1153f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1154f028a1fbSGreg Clayton {
11555160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1156f028a1fbSGreg Clayton 
1157f028a1fbSGreg Clayton     SBFrame sb_frame;
1158b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11594fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11604fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11614fc6cb9cSJim Ingham 
11621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1163af67cecdSGreg Clayton     {
11647fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11657fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11667fdf9ef1SGreg Clayton         {
11671ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1168b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1169af67cecdSGreg Clayton         }
1170c9858e4dSGreg Clayton         else
1171c9858e4dSGreg Clayton         {
1172c9858e4dSGreg Clayton             if (log)
1173c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1174c9858e4dSGreg Clayton         }
11757fdf9ef1SGreg Clayton     }
1176f028a1fbSGreg Clayton 
1177f028a1fbSGreg Clayton     if (log)
1178f028a1fbSGreg Clayton     {
1179481cef25SGreg Clayton         SBStream frame_desc_strm;
1180481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1181f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
11821ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1183f028a1fbSGreg Clayton     }
1184f028a1fbSGreg Clayton 
1185f028a1fbSGreg Clayton     return sb_frame;
1186f028a1fbSGreg Clayton }
1187f028a1fbSGreg Clayton 
1188f028a1fbSGreg Clayton lldb::SBFrame
1189f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1190f028a1fbSGreg Clayton {
11915160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1192f028a1fbSGreg Clayton 
1193f028a1fbSGreg Clayton     SBFrame sb_frame;
1194b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11954fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11964fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11974fc6cb9cSJim Ingham 
11981ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1199f028a1fbSGreg Clayton     {
12007fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12017fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12027fdf9ef1SGreg Clayton         {
12031ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
12041ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1205f028a1fbSGreg Clayton             if (frame_sp)
1206f028a1fbSGreg Clayton             {
12071ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1208b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1209f028a1fbSGreg Clayton             }
1210f028a1fbSGreg Clayton         }
1211c9858e4dSGreg Clayton         else
1212c9858e4dSGreg Clayton         {
1213c9858e4dSGreg Clayton             if (log)
1214c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1215c9858e4dSGreg Clayton         }
12167fdf9ef1SGreg Clayton     }
1217f028a1fbSGreg Clayton 
1218f028a1fbSGreg Clayton     if (log)
1219f028a1fbSGreg Clayton     {
1220481cef25SGreg Clayton         SBStream frame_desc_strm;
1221481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1222f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
12231ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1224f028a1fbSGreg Clayton     }
1225f028a1fbSGreg Clayton     return sb_frame;
1226f028a1fbSGreg Clayton }
1227f028a1fbSGreg Clayton 
12284f465cffSJim Ingham bool
12294f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
12304f465cffSJim Ingham {
12314f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
12324f465cffSJim Ingham }
12334f465cffSJim Ingham 
12344f465cffSJim Ingham SBFrame
12354f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
12364f465cffSJim Ingham {
12374f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
12384f465cffSJim Ingham 
12394f465cffSJim Ingham }
12404f465cffSJim Ingham 
12414f465cffSJim Ingham SBThread
12424f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
12434f465cffSJim Ingham {
12444f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
12454f465cffSJim Ingham }
1246f028a1fbSGreg Clayton 
124730fdc8d8SChris Lattner bool
124830fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
124930fdc8d8SChris Lattner {
12507fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
125130fdc8d8SChris Lattner }
125230fdc8d8SChris Lattner 
125330fdc8d8SChris Lattner bool
125430fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
125530fdc8d8SChris Lattner {
12567fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
125730fdc8d8SChris Lattner }
1258dde9cff3SCaroline Tice 
1259dde9cff3SCaroline Tice bool
12604f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
12614f465cffSJim Ingham {
12624f465cffSJim Ingham     Stream &strm = status.ref();
12634f465cffSJim Ingham 
12644f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
12654f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
12664f465cffSJim Ingham     {
12674f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
12684f465cffSJim Ingham     }
12694f465cffSJim Ingham     else
12704f465cffSJim Ingham         strm.PutCString ("No status");
12714f465cffSJim Ingham 
12724f465cffSJim Ingham     return true;
12734f465cffSJim Ingham }
12744f465cffSJim Ingham 
12754f465cffSJim Ingham bool
1276ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1277ceb6b139SCaroline Tice {
1278da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1279da7bc7d0SGreg Clayton 
12807fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
12811ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1282ceb6b139SCaroline Tice     {
1283d01b2953SDaniel Malea         strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1284ceb6b139SCaroline Tice     }
1285ceb6b139SCaroline Tice     else
1286da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1287ceb6b139SCaroline Tice 
1288ceb6b139SCaroline Tice     return true;
1289ceb6b139SCaroline Tice }
12905dd4916fSJason Molenda 
12915dd4916fSJason Molenda SBThread
1292008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
12935dd4916fSJason Molenda {
12945dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
12955dd4916fSJason Molenda     Mutex::Locker api_locker;
12965dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12975dd4916fSJason Molenda     SBThread sb_origin_thread;
12985dd4916fSJason Molenda 
12995dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
13005dd4916fSJason Molenda     {
13015dd4916fSJason Molenda         Process::StopLocker stop_locker;
13025dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13035dd4916fSJason Molenda         {
13047a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
13055dd4916fSJason Molenda             if (real_thread)
13065dd4916fSJason Molenda             {
13075dd4916fSJason Molenda                 ConstString type_const (type);
13087a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
13097a2f7904SJason Molenda                 if (process)
13107a2f7904SJason Molenda                 {
13117a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
13125dd4916fSJason Molenda                     if (runtime)
13135dd4916fSJason Molenda                     {
1314008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1315a6e9130dSJason Molenda                         if (new_thread_sp)
1316a6e9130dSJason Molenda                         {
13177a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
13187a2f7904SJason Molenda                             // object.
13197a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
13207a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1321a6e9130dSJason Molenda                             if (log)
1322a6e9130dSJason Molenda                             {
1323a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1324a6e9130dSJason Molenda                                 if (queue_name == NULL)
1325a6e9130dSJason Molenda                                     queue_name = "";
1326a6e9130dSJason Molenda                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", exe_ctx.GetThreadPtr(), new_thread_sp.get(), new_thread_sp->GetQueueID(), queue_name);
1327a6e9130dSJason Molenda                             }
1328a6e9130dSJason Molenda                         }
13297a2f7904SJason Molenda                     }
13305dd4916fSJason Molenda                 }
13315dd4916fSJason Molenda             }
13325dd4916fSJason Molenda         }
13335dd4916fSJason Molenda         else
13345dd4916fSJason Molenda         {
13355dd4916fSJason Molenda             if (log)
1336a6e9130dSJason Molenda                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", exe_ctx.GetThreadPtr());
13375dd4916fSJason Molenda         }
13385dd4916fSJason Molenda     }
13395dd4916fSJason Molenda 
1340ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1341ac605f4aSJason Molenda     {
1342ac605f4aSJason Molenda         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", exe_ctx.GetThreadPtr());
1343ac605f4aSJason Molenda     }
13445dd4916fSJason Molenda     return sb_origin_thread;
13455dd4916fSJason Molenda }
13468ee9cb58SJason Molenda 
13478ee9cb58SJason Molenda uint32_t
13488ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
13498ee9cb58SJason Molenda {
13508ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13518ee9cb58SJason Molenda     if (thread_sp)
13528ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
13538ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
13548ee9cb58SJason Molenda }
1355