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)
123324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running",
124324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
125c9858e4dSGreg Clayton         }
1267fdf9ef1SGreg Clayton     }
127ceb6b139SCaroline Tice 
128ceb6b139SCaroline Tice     if (log)
129324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReason () => %s",
130324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
131750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
132ceb6b139SCaroline Tice 
133ceb6b139SCaroline Tice     return reason;
13430fdc8d8SChris Lattner }
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner size_t
1374e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1384e78f606SGreg Clayton {
1394fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1404fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1414fc6cb9cSJim Ingham 
1421ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1434e78f606SGreg Clayton     {
1447fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1457fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1467fdf9ef1SGreg Clayton         {
1471ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1484e78f606SGreg Clayton             if (stop_info_sp)
1494e78f606SGreg Clayton             {
1504e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1514e78f606SGreg Clayton                 switch (reason)
1524e78f606SGreg Clayton                 {
1534e78f606SGreg Clayton                 case eStopReasonInvalid:
1544e78f606SGreg Clayton                 case eStopReasonNone:
1554e78f606SGreg Clayton                 case eStopReasonTrace:
15690ba8115SGreg Clayton                 case eStopReasonExec:
1574e78f606SGreg Clayton                 case eStopReasonPlanComplete:
158f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
1594e78f606SGreg Clayton                     // There is no data for these stop reasons.
1604e78f606SGreg Clayton                     return 0;
1614e78f606SGreg Clayton 
1624e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1634e78f606SGreg Clayton                     {
1644e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1651ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1664e78f606SGreg Clayton                         if (bp_site_sp)
1674e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1684e78f606SGreg Clayton                         else
1694e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1704e78f606SGreg Clayton                     }
1714e78f606SGreg Clayton                     break;
1724e78f606SGreg Clayton 
1734e78f606SGreg Clayton                 case eStopReasonWatchpoint:
174290fa41bSJohnny Chen                     return 1;
1754e78f606SGreg Clayton 
1764e78f606SGreg Clayton                 case eStopReasonSignal:
1774e78f606SGreg Clayton                     return 1;
1784e78f606SGreg Clayton 
1794e78f606SGreg Clayton                 case eStopReasonException:
1804e78f606SGreg Clayton                     return 1;
1814e78f606SGreg Clayton                 }
1824e78f606SGreg Clayton             }
1834e78f606SGreg Clayton         }
184c9858e4dSGreg Clayton         else
185c9858e4dSGreg Clayton         {
1865160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
187c9858e4dSGreg Clayton             if (log)
188324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running",
189324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
190c9858e4dSGreg Clayton         }
1917fdf9ef1SGreg Clayton     }
1924e78f606SGreg Clayton     return 0;
1934e78f606SGreg Clayton }
1944e78f606SGreg Clayton 
1954e78f606SGreg Clayton uint64_t
1964e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1974e78f606SGreg Clayton {
1984fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1994fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2004fc6cb9cSJim Ingham 
2011ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
2024e78f606SGreg Clayton     {
2037fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2047fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2057fdf9ef1SGreg Clayton         {
2061ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2071ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2084e78f606SGreg Clayton             if (stop_info_sp)
2094e78f606SGreg Clayton             {
2104e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2114e78f606SGreg Clayton                 switch (reason)
2124e78f606SGreg Clayton                 {
2134e78f606SGreg Clayton                 case eStopReasonInvalid:
2144e78f606SGreg Clayton                 case eStopReasonNone:
2154e78f606SGreg Clayton                 case eStopReasonTrace:
21690ba8115SGreg Clayton                 case eStopReasonExec:
2174e78f606SGreg Clayton                 case eStopReasonPlanComplete:
218f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
2194e78f606SGreg Clayton                     // There is no data for these stop reasons.
2204e78f606SGreg Clayton                     return 0;
2214e78f606SGreg Clayton 
2224e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2234e78f606SGreg Clayton                     {
2244e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2251ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2264e78f606SGreg Clayton                         if (bp_site_sp)
2274e78f606SGreg Clayton                         {
2284e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2294e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2304e78f606SGreg Clayton                             if (bp_loc_sp)
2314e78f606SGreg Clayton                             {
232*8334e14eSGreg Clayton                                 if (idx & 1)
2334e78f606SGreg Clayton                                 {
2344e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2354e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2364e78f606SGreg Clayton                                 }
2374e78f606SGreg Clayton                                 else
2384e78f606SGreg Clayton                                 {
2394e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2404e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2414e78f606SGreg Clayton                                 }
2424e78f606SGreg Clayton                             }
2434e78f606SGreg Clayton                         }
2444e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2454e78f606SGreg Clayton                     }
2464e78f606SGreg Clayton                     break;
2474e78f606SGreg Clayton 
2484e78f606SGreg Clayton                 case eStopReasonWatchpoint:
249290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2504e78f606SGreg Clayton 
2514e78f606SGreg Clayton                 case eStopReasonSignal:
2524e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2534e78f606SGreg Clayton 
2544e78f606SGreg Clayton                 case eStopReasonException:
2554e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2564e78f606SGreg Clayton                 }
2574e78f606SGreg Clayton             }
2584e78f606SGreg Clayton         }
259c9858e4dSGreg Clayton         else
260c9858e4dSGreg Clayton         {
2615160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
262c9858e4dSGreg Clayton             if (log)
263324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running",
264324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
265c9858e4dSGreg Clayton         }
2667fdf9ef1SGreg Clayton     }
2674e78f606SGreg Clayton     return 0;
2684e78f606SGreg Clayton }
2694e78f606SGreg Clayton 
2704e78f606SGreg Clayton size_t
27130fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
27230fdc8d8SChris Lattner {
2735160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
274ceb6b139SCaroline Tice 
2754fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2764fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2774fc6cb9cSJim Ingham 
2781ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
27930fdc8d8SChris Lattner     {
2807fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2817fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2827fdf9ef1SGreg Clayton         {
2837fdf9ef1SGreg Clayton 
2841ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
285b15bfc75SJim Ingham             if (stop_info_sp)
28630fdc8d8SChris Lattner             {
287b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
28830fdc8d8SChris Lattner                 if (stop_desc)
28930fdc8d8SChris Lattner                 {
290ceb6b139SCaroline Tice                     if (log)
2914838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
292324a1036SSaleem Abdulrasool                                      static_cast<void*>(exe_ctx.GetThreadPtr()),
293324a1036SSaleem Abdulrasool                                      stop_desc);
29430fdc8d8SChris Lattner                     if (dst)
29530fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
29630fdc8d8SChris Lattner                     else
29730fdc8d8SChris Lattner                     {
29830fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
29930fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
30030fdc8d8SChris Lattner                     }
30130fdc8d8SChris Lattner                 }
30230fdc8d8SChris Lattner                 else
30330fdc8d8SChris Lattner                 {
30430fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
305b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
30630fdc8d8SChris Lattner                     {
30730fdc8d8SChris Lattner                     case eStopReasonTrace:
30830fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
30930fdc8d8SChris Lattner                         {
31030fdc8d8SChris Lattner                             static char trace_desc[] = "step";
31130fdc8d8SChris Lattner                             stop_desc = trace_desc;
31230fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
31330fdc8d8SChris Lattner                         }
31430fdc8d8SChris Lattner                         break;
31530fdc8d8SChris Lattner 
31630fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
31730fdc8d8SChris Lattner                         {
31830fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
31930fdc8d8SChris Lattner                             stop_desc = bp_desc;
32030fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
32130fdc8d8SChris Lattner                         }
32230fdc8d8SChris Lattner                         break;
32330fdc8d8SChris Lattner 
32430fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
32530fdc8d8SChris Lattner                         {
32630fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
32730fdc8d8SChris Lattner                             stop_desc = wp_desc;
32830fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
32930fdc8d8SChris Lattner                         }
33030fdc8d8SChris Lattner                         break;
33130fdc8d8SChris Lattner 
33230fdc8d8SChris Lattner                     case eStopReasonSignal:
33330fdc8d8SChris Lattner                         {
3341ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
33530fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
33630fdc8d8SChris Lattner                             {
33730fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
33830fdc8d8SChris Lattner                                 stop_desc = signal_desc;
33930fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
34030fdc8d8SChris Lattner                             }
34130fdc8d8SChris Lattner                         }
34230fdc8d8SChris Lattner                         break;
34330fdc8d8SChris Lattner 
34430fdc8d8SChris Lattner                     case eStopReasonException:
34530fdc8d8SChris Lattner                         {
34630fdc8d8SChris Lattner                             char exc_desc[] = "exception";
34730fdc8d8SChris Lattner                             stop_desc = exc_desc;
34830fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
34930fdc8d8SChris Lattner                         }
35030fdc8d8SChris Lattner                         break;
351c982c768SGreg Clayton 
35290ba8115SGreg Clayton                     case eStopReasonExec:
35390ba8115SGreg Clayton                         {
35490ba8115SGreg Clayton                             char exc_desc[] = "exec";
35590ba8115SGreg Clayton                             stop_desc = exc_desc;
35690ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
35790ba8115SGreg Clayton                         }
35890ba8115SGreg Clayton                         break;
35990ba8115SGreg Clayton 
360f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
361f85defaeSAndrew Kaylor                         {
362f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
363f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
364f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
365f85defaeSAndrew Kaylor                         }
366f85defaeSAndrew Kaylor                         break;
367c982c768SGreg Clayton                     default:
368c982c768SGreg Clayton                         break;
36930fdc8d8SChris Lattner                     }
37030fdc8d8SChris Lattner 
37130fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
37230fdc8d8SChris Lattner                     {
373ceb6b139SCaroline Tice                         if (log)
37493aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
375324a1036SSaleem Abdulrasool                                          static_cast<void*>(exe_ctx.GetThreadPtr()),
376324a1036SSaleem Abdulrasool                                          stop_desc);
377ceb6b139SCaroline Tice 
37830fdc8d8SChris Lattner                         if (dst)
37930fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
38030fdc8d8SChris Lattner 
38130fdc8d8SChris Lattner                         if (stop_desc_len == 0)
38230fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
38330fdc8d8SChris Lattner 
38430fdc8d8SChris Lattner                         return stop_desc_len;
38530fdc8d8SChris Lattner                     }
38630fdc8d8SChris Lattner                 }
38730fdc8d8SChris Lattner             }
38830fdc8d8SChris Lattner         }
389c9858e4dSGreg Clayton         else
390c9858e4dSGreg Clayton         {
3915160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
392c9858e4dSGreg Clayton             if (log)
393324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running",
394324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
395c9858e4dSGreg Clayton         }
3967fdf9ef1SGreg Clayton     }
39730fdc8d8SChris Lattner     if (dst)
39830fdc8d8SChris Lattner         *dst = 0;
39930fdc8d8SChris Lattner     return 0;
40030fdc8d8SChris Lattner }
40130fdc8d8SChris Lattner 
40273ca05a2SJim Ingham SBValue
40373ca05a2SJim Ingham SBThread::GetStopReturnValue ()
40473ca05a2SJim Ingham {
4055160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
40673ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
4074fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4084fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4094fc6cb9cSJim Ingham 
4101ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
41173ca05a2SJim Ingham     {
4127fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4137fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4147fdf9ef1SGreg Clayton         {
4151ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
41673ca05a2SJim Ingham             if (stop_info_sp)
41773ca05a2SJim Ingham             {
41873ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
41973ca05a2SJim Ingham             }
42073ca05a2SJim Ingham         }
421c9858e4dSGreg Clayton         else
422c9858e4dSGreg Clayton         {
423c9858e4dSGreg Clayton             if (log)
424324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running",
425324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
426c9858e4dSGreg Clayton         }
4277fdf9ef1SGreg Clayton     }
42873ca05a2SJim Ingham 
42973ca05a2SJim Ingham     if (log)
430324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s",
431324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
43273ca05a2SJim Ingham                      return_valobj_sp.get()
43373ca05a2SJim Ingham                         ? return_valobj_sp->GetValueAsCString()
43473ca05a2SJim Ingham                         : "<no return value>");
43573ca05a2SJim Ingham 
43673ca05a2SJim Ingham     return SBValue (return_valobj_sp);
43773ca05a2SJim Ingham }
43873ca05a2SJim Ingham 
43930fdc8d8SChris Lattner void
44030fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
44130fdc8d8SChris Lattner {
4427fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
44330fdc8d8SChris Lattner }
44430fdc8d8SChris Lattner 
44530fdc8d8SChris Lattner lldb::tid_t
44630fdc8d8SChris Lattner SBThread::GetThreadID () const
44730fdc8d8SChris Lattner {
4487fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44917a6ad05SGreg Clayton     if (thread_sp)
4501ac04c30SGreg Clayton         return thread_sp->GetID();
4511ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
45230fdc8d8SChris Lattner }
45330fdc8d8SChris Lattner 
45430fdc8d8SChris Lattner uint32_t
45530fdc8d8SChris Lattner SBThread::GetIndexID () const
45630fdc8d8SChris Lattner {
4577fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
45817a6ad05SGreg Clayton     if (thread_sp)
45917a6ad05SGreg Clayton         return thread_sp->GetIndexID();
46030fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
46130fdc8d8SChris Lattner }
4621ac04c30SGreg Clayton 
46330fdc8d8SChris Lattner const char *
46430fdc8d8SChris Lattner SBThread::GetName () const
46530fdc8d8SChris Lattner {
4665160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4674838131bSGreg Clayton     const char *name = NULL;
4684fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4694fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4704fc6cb9cSJim Ingham 
4711ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
472af67cecdSGreg Clayton     {
4737fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4747fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4757fdf9ef1SGreg Clayton         {
4761ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
477af67cecdSGreg Clayton         }
478c9858e4dSGreg Clayton         else
479c9858e4dSGreg Clayton         {
480c9858e4dSGreg Clayton             if (log)
481324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetName() => error: process is running",
482324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
483c9858e4dSGreg Clayton         }
4847fdf9ef1SGreg Clayton     }
485ceb6b139SCaroline Tice 
486ceb6b139SCaroline Tice     if (log)
487324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetName () => %s",
488324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
489324a1036SSaleem Abdulrasool                      name ? name : "NULL");
490ceb6b139SCaroline Tice 
4914838131bSGreg Clayton     return name;
49230fdc8d8SChris Lattner }
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner const char *
49530fdc8d8SChris Lattner SBThread::GetQueueName () const
49630fdc8d8SChris Lattner {
4974838131bSGreg Clayton     const char *name = NULL;
4984fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4994fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5004fc6cb9cSJim Ingham 
5015160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5021ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
503af67cecdSGreg Clayton     {
5047fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
5057fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5067fdf9ef1SGreg Clayton         {
5071ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
508af67cecdSGreg Clayton         }
509c9858e4dSGreg Clayton         else
510c9858e4dSGreg Clayton         {
511c9858e4dSGreg Clayton             if (log)
512324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running",
513324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
514c9858e4dSGreg Clayton         }
5157fdf9ef1SGreg Clayton     }
516ceb6b139SCaroline Tice 
517ceb6b139SCaroline Tice     if (log)
518324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueName () => %s",
519324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
520324a1036SSaleem Abdulrasool                      name ? name : "NULL");
521ceb6b139SCaroline Tice 
5224838131bSGreg Clayton     return name;
52330fdc8d8SChris Lattner }
52430fdc8d8SChris Lattner 
5254fdb5863SJason Molenda lldb::queue_id_t
5264fdb5863SJason Molenda SBThread::GetQueueID () const
5274fdb5863SJason Molenda {
5284fdb5863SJason Molenda     queue_id_t id = LLDB_INVALID_QUEUE_ID;
5294fdb5863SJason Molenda     Mutex::Locker api_locker;
5304fdb5863SJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5314fdb5863SJason Molenda 
5324fdb5863SJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
5334fdb5863SJason Molenda     if (exe_ctx.HasThreadScope())
5344fdb5863SJason Molenda     {
5354fdb5863SJason Molenda         Process::StopLocker stop_locker;
5364fdb5863SJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
5374fdb5863SJason Molenda         {
5384fdb5863SJason Molenda             id = exe_ctx.GetThreadPtr()->GetQueueID();
5394fdb5863SJason Molenda         }
5404fdb5863SJason Molenda         else
5414fdb5863SJason Molenda         {
5424fdb5863SJason Molenda             if (log)
543324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetQueueID() => error: process is running",
544324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
5454fdb5863SJason Molenda         }
5464fdb5863SJason Molenda     }
5474fdb5863SJason Molenda 
5484fdb5863SJason Molenda     if (log)
549324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
550324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), id);
5514fdb5863SJason Molenda 
5524fdb5863SJason Molenda     return id;
5534fdb5863SJason Molenda }
5544fdb5863SJason Molenda 
55564e7ead1SJim Ingham SBError
55664e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
55764e7ead1SJim Ingham {
55864e7ead1SJim Ingham     SBError sb_error;
55964e7ead1SJim Ingham 
56064e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
56164e7ead1SJim Ingham     if (!process)
56264e7ead1SJim Ingham     {
56364e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
56464e7ead1SJim Ingham         return sb_error;
56564e7ead1SJim Ingham     }
56664e7ead1SJim Ingham 
56764e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
56864e7ead1SJim Ingham     if (!thread)
56964e7ead1SJim Ingham     {
57064e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
57164e7ead1SJim Ingham         return sb_error;
57264e7ead1SJim Ingham     }
57364e7ead1SJim Ingham 
57464e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
57564e7ead1SJim Ingham     // then a "continue" will resume the plan.
57664e7ead1SJim Ingham     if (new_plan != NULL)
57764e7ead1SJim Ingham     {
57864e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
57964e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
58064e7ead1SJim Ingham     }
58164e7ead1SJim Ingham 
58264e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
58364e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
58464e7ead1SJim Ingham     sb_error.ref() = process->Resume();
58564e7ead1SJim Ingham 
58664e7ead1SJim Ingham     if (sb_error.Success())
58764e7ead1SJim Ingham     {
58864e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
58964e7ead1SJim Ingham         // process to stop yet again!
59064e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
59164e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
59264e7ead1SJim Ingham     }
59364e7ead1SJim Ingham 
59464e7ead1SJim Ingham     return sb_error;
59564e7ead1SJim Ingham }
59630fdc8d8SChris Lattner 
59730fdc8d8SChris Lattner void
59830fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
59930fdc8d8SChris Lattner {
6005160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
601ceb6b139SCaroline Tice 
6024fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6034fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6044fc6cb9cSJim Ingham 
60517a6ad05SGreg Clayton 
606ceb6b139SCaroline Tice     if (log)
607324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')",
608324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
609ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
610ceb6b139SCaroline Tice 
6111ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
61230fdc8d8SChris Lattner     {
6131ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6147ba6e991SJim Ingham         bool abort_other_plans = false;
615b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
61630fdc8d8SChris Lattner 
6174d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
61830fdc8d8SChris Lattner         if (frame_sp)
61930fdc8d8SChris Lattner         {
62030fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
62130fdc8d8SChris Lattner             {
6224b4b2478SJim Ingham                 const LazyBool avoid_no_debug = eLazyBoolCalculate;
62330fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
6244d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
62530fdc8d8SChris Lattner                                                                     sc.line_entry.range,
62630fdc8d8SChris Lattner                                                                     sc,
6274b4b2478SJim Ingham                                                                     stop_other_threads,
6284b4b2478SJim Ingham                                                                     avoid_no_debug);
62930fdc8d8SChris Lattner             }
63030fdc8d8SChris Lattner             else
63130fdc8d8SChris Lattner             {
6324d56e9c1SJim Ingham                 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
63330fdc8d8SChris Lattner                                                                                abort_other_plans,
63430fdc8d8SChris Lattner                                                                                stop_other_threads);
63530fdc8d8SChris Lattner             }
63630fdc8d8SChris Lattner         }
63730fdc8d8SChris Lattner 
63864e7ead1SJim Ingham         // This returns an error, we should use it!
6394d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
64030fdc8d8SChris Lattner     }
64130fdc8d8SChris Lattner }
64230fdc8d8SChris Lattner 
64330fdc8d8SChris Lattner void
64430fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
64530fdc8d8SChris Lattner {
646c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
647c627682eSJim Ingham }
648c627682eSJim Ingham 
649c627682eSJim Ingham void
650c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
651c627682eSJim Ingham {
6525160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
653ceb6b139SCaroline Tice 
6544fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6554fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
65617a6ad05SGreg Clayton 
65717a6ad05SGreg Clayton     if (log)
658c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
659324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
660c627682eSJim Ingham                      target_name? target_name: "<NULL>",
66117a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
662c627682eSJim Ingham 
6631ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
66430fdc8d8SChris Lattner     {
6657ba6e991SJim Ingham         bool abort_other_plans = false;
66630fdc8d8SChris Lattner 
6671ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
668b57e4a1bSJason Molenda         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
6694d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp;
67030fdc8d8SChris Lattner 
67130fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
67230fdc8d8SChris Lattner         {
6734b4b2478SJim Ingham             const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate;
6744b4b2478SJim Ingham             const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate;
67530fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
6764d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
67730fdc8d8SChris Lattner                                                               sc.line_entry.range,
67830fdc8d8SChris Lattner                                                               sc,
679c627682eSJim Ingham                                                               target_name,
680474966a4SGreg Clayton                                                               stop_other_threads,
6814b4b2478SJim Ingham                                                               step_in_avoids_code_without_debug_info,
6824b4b2478SJim Ingham                                                               step_out_avoids_code_without_debug_info);
68330fdc8d8SChris Lattner         }
68430fdc8d8SChris Lattner         else
68530fdc8d8SChris Lattner         {
6864d56e9c1SJim Ingham             new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
68730fdc8d8SChris Lattner                                                                            abort_other_plans,
68830fdc8d8SChris Lattner                                                                            stop_other_threads);
68930fdc8d8SChris Lattner         }
69030fdc8d8SChris Lattner 
69164e7ead1SJim Ingham         // This returns an error, we should use it!
6924d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
69330fdc8d8SChris Lattner     }
69430fdc8d8SChris Lattner }
69530fdc8d8SChris Lattner 
69630fdc8d8SChris Lattner void
69730fdc8d8SChris Lattner SBThread::StepOut ()
69830fdc8d8SChris Lattner {
6995160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
700ceb6b139SCaroline Tice 
7014fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7024fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7034fc6cb9cSJim Ingham 
704ceb6b139SCaroline Tice 
70517a6ad05SGreg Clayton     if (log)
706324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOut ()",
707324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()));
70817a6ad05SGreg Clayton 
7091ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
71030fdc8d8SChris Lattner     {
7117ba6e991SJim Ingham         bool abort_other_plans = false;
71294b09246SJim Ingham         bool stop_other_threads = false;
71330fdc8d8SChris Lattner 
7141ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7151ac04c30SGreg Clayton 
7164b4b2478SJim Ingham         const LazyBool avoid_no_debug = eLazyBoolCalculate;
7174d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
718481cef25SGreg Clayton                                                                     NULL,
719481cef25SGreg Clayton                                                                     false,
720481cef25SGreg Clayton                                                                     stop_other_threads,
721481cef25SGreg Clayton                                                                     eVoteYes,
722481cef25SGreg Clayton                                                                     eVoteNoOpinion,
7234b4b2478SJim Ingham                                                                     0,
7244b4b2478SJim Ingham                                                                     avoid_no_debug));
725481cef25SGreg Clayton 
72664e7ead1SJim Ingham         // This returns an error, we should use it!
7274d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
728481cef25SGreg Clayton     }
729481cef25SGreg Clayton }
730481cef25SGreg Clayton 
731481cef25SGreg Clayton void
732481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
733481cef25SGreg Clayton {
7345160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
735481cef25SGreg Clayton 
7364fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7374fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7384fc6cb9cSJim Ingham 
739b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
740481cef25SGreg Clayton     if (log)
741481cef25SGreg Clayton     {
742481cef25SGreg Clayton         SBStream frame_desc_strm;
743481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
744324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
745324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
746324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
747324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
748481cef25SGreg Clayton     }
749481cef25SGreg Clayton 
7501ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
751481cef25SGreg Clayton     {
7527ba6e991SJim Ingham         bool abort_other_plans = false;
75394b09246SJim Ingham         bool stop_other_threads = false;
7541ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
755481cef25SGreg Clayton 
7564d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
757481cef25SGreg Clayton                                                                     NULL,
758481cef25SGreg Clayton                                                                     false,
759481cef25SGreg Clayton                                                                     stop_other_threads,
760481cef25SGreg Clayton                                                                     eVoteYes,
761481cef25SGreg Clayton                                                                     eVoteNoOpinion,
7624d56e9c1SJim Ingham                                                                     frame_sp->GetFrameIndex()));
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::StepInstruction (bool step_over)
77130fdc8d8SChris Lattner {
7725160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
773ceb6b139SCaroline Tice 
7744fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7754fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7764fc6cb9cSJim Ingham 
7771ac04c30SGreg Clayton 
778ceb6b139SCaroline Tice 
77917a6ad05SGreg Clayton     if (log)
780324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)",
781324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), step_over);
78217a6ad05SGreg Clayton 
7831ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
78430fdc8d8SChris Lattner     {
7851ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7864d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
78764e7ead1SJim Ingham 
78864e7ead1SJim Ingham         // This returns an error, we should use it!
7894d56e9c1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan_sp.get());
79030fdc8d8SChris Lattner     }
79130fdc8d8SChris Lattner }
79230fdc8d8SChris Lattner 
79330fdc8d8SChris Lattner void
79430fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
79530fdc8d8SChris Lattner {
7965160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
797ceb6b139SCaroline Tice 
7984fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7994fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8004fc6cb9cSJim Ingham 
801ceb6b139SCaroline Tice 
80217a6ad05SGreg Clayton     if (log)
803324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
804324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), addr);
80517a6ad05SGreg Clayton 
8061ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
80730fdc8d8SChris Lattner     {
8087ba6e991SJim Ingham         bool abort_other_plans = false;
80930fdc8d8SChris Lattner         bool stop_other_threads = true;
81030fdc8d8SChris Lattner 
811e72dfb32SGreg Clayton         Address target_addr (addr);
81230fdc8d8SChris Lattner 
8131ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
8141ac04c30SGreg Clayton 
8154d56e9c1SJim Ingham         ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
81664e7ead1SJim Ingham 
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 
822481cef25SGreg Clayton SBError
823481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
824481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
825481cef25SGreg Clayton                          uint32_t line)
826481cef25SGreg Clayton {
827481cef25SGreg Clayton     SBError sb_error;
8285160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
829481cef25SGreg Clayton     char path[PATH_MAX];
830481cef25SGreg Clayton 
8314fc6cb9cSJim Ingham     Mutex::Locker api_locker;
8324fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8334fc6cb9cSJim Ingham 
834b57e4a1bSJason Molenda     StackFrameSP frame_sp (sb_frame.GetFrameSP());
83517a6ad05SGreg Clayton 
836481cef25SGreg Clayton     if (log)
837481cef25SGreg Clayton     {
838481cef25SGreg Clayton         SBStream frame_desc_strm;
839481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
840481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
841481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
842324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
843324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
844324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData(), path, line);
845481cef25SGreg Clayton     }
846481cef25SGreg Clayton 
8471ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
848481cef25SGreg Clayton     {
8491ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
8501ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
851481cef25SGreg Clayton 
852481cef25SGreg Clayton         if (line == 0)
853481cef25SGreg Clayton         {
854481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
855481cef25SGreg Clayton             return sb_error;
856481cef25SGreg Clayton         }
857481cef25SGreg Clayton 
858b9556accSGreg Clayton         if (!frame_sp)
859481cef25SGreg Clayton         {
8601ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
861481cef25SGreg Clayton             if (!frame_sp)
8621ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
863481cef25SGreg Clayton         }
864481cef25SGreg Clayton 
865481cef25SGreg Clayton         SymbolContext frame_sc;
866481cef25SGreg Clayton         if (!frame_sp)
867481cef25SGreg Clayton         {
868481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
869481cef25SGreg Clayton             return sb_error;
870481cef25SGreg Clayton         }
871481cef25SGreg Clayton 
872481cef25SGreg Clayton         // If we have a frame, get its line
873481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
874481cef25SGreg Clayton                                                eSymbolContextFunction  |
875481cef25SGreg Clayton                                                eSymbolContextLineEntry |
876481cef25SGreg Clayton                                                eSymbolContextSymbol    );
877481cef25SGreg Clayton 
878481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
879481cef25SGreg Clayton         {
880481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
881481cef25SGreg Clayton             return sb_error;
882481cef25SGreg Clayton         }
883481cef25SGreg Clayton 
884481cef25SGreg Clayton         FileSpec step_file_spec;
885481cef25SGreg Clayton         if (sb_file_spec.IsValid())
886481cef25SGreg Clayton         {
887481cef25SGreg Clayton             // The file spec passed in was valid, so use it
888481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
889481cef25SGreg Clayton         }
890481cef25SGreg Clayton         else
891481cef25SGreg Clayton         {
892481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
893481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
894481cef25SGreg Clayton             else
895481cef25SGreg Clayton             {
896481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
897481cef25SGreg Clayton                 return sb_error;
898481cef25SGreg Clayton             }
899481cef25SGreg Clayton         }
900481cef25SGreg Clayton 
9019b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
9029b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
9039b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
9049b70ddb3SJim Ingham         // error message.
9059b70ddb3SJim Ingham 
9069b70ddb3SJim Ingham         bool all_in_function = true;
9079b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
9089b70ddb3SJim Ingham 
909481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
9107ba6e991SJim Ingham         const bool abort_other_plans = false;
911c02e3344SJim Ingham         const bool stop_other_threads = false;
912481cef25SGreg Clayton         const bool check_inlines = true;
913481cef25SGreg Clayton         const bool exact = false;
914481cef25SGreg Clayton 
915481cef25SGreg Clayton         SymbolContextList sc_list;
9169b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
9179b70ddb3SJim Ingham                                                                                line,
9189b70ddb3SJim Ingham                                                                                check_inlines,
9199b70ddb3SJim Ingham                                                                                exact,
9209b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
9219b70ddb3SJim Ingham                                                                                sc_list);
922481cef25SGreg Clayton         if (num_matches > 0)
923481cef25SGreg Clayton         {
924481cef25SGreg Clayton             SymbolContext sc;
925481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
926481cef25SGreg Clayton             {
927481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
928481cef25SGreg Clayton                 {
9299b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
930481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
931481cef25SGreg Clayton                     {
9329b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
933481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
9349b70ddb3SJim Ingham                         else
9359b70ddb3SJim Ingham                             all_in_function = false;
936481cef25SGreg Clayton                     }
937481cef25SGreg Clayton                 }
938481cef25SGreg Clayton             }
939481cef25SGreg Clayton         }
940481cef25SGreg Clayton 
941481cef25SGreg Clayton         if (step_over_until_addrs.empty())
942481cef25SGreg Clayton         {
9439b70ddb3SJim Ingham             if (all_in_function)
9449b70ddb3SJim Ingham             {
945481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
946fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
947481cef25SGreg Clayton             }
948481cef25SGreg Clayton             else
94986edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
9509b70ddb3SJim Ingham         }
9519b70ddb3SJim Ingham         else
952481cef25SGreg Clayton         {
9534d56e9c1SJim Ingham             ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
954481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
955481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
956481cef25SGreg Clayton                                                                         stop_other_threads,
9574d56e9c1SJim Ingham                                                                         frame_sp->GetFrameIndex()));
958481cef25SGreg Clayton 
9594d56e9c1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
960481cef25SGreg Clayton         }
961481cef25SGreg Clayton     }
962481cef25SGreg Clayton     else
963481cef25SGreg Clayton     {
964481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
965481cef25SGreg Clayton     }
966481cef25SGreg Clayton     return sb_error;
967481cef25SGreg Clayton }
968481cef25SGreg Clayton 
9694413758cSJim Ingham SBError
970f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line)
971f86248d9SRichard Mitton {
972f86248d9SRichard Mitton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
973f86248d9SRichard Mitton     SBError sb_error;
974f86248d9SRichard Mitton 
975f86248d9SRichard Mitton     Mutex::Locker api_locker;
976f86248d9SRichard Mitton     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
977f86248d9SRichard Mitton 
978f86248d9SRichard Mitton     if (log)
979324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)",
980324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
981324a1036SSaleem Abdulrasool                      file_spec->GetPath().c_str(), line);
982f86248d9SRichard Mitton 
983f86248d9SRichard Mitton     if (!exe_ctx.HasThreadScope())
984f86248d9SRichard Mitton     {
985f86248d9SRichard Mitton         sb_error.SetErrorString("this SBThread object is invalid");
986f86248d9SRichard Mitton         return sb_error;
987f86248d9SRichard Mitton     }
988f86248d9SRichard Mitton 
989f86248d9SRichard Mitton     Thread *thread = exe_ctx.GetThreadPtr();
990f86248d9SRichard Mitton 
991f86248d9SRichard Mitton     Error err = thread->JumpToLine (file_spec.get(), line, true);
992f86248d9SRichard Mitton     sb_error.SetError (err);
993f86248d9SRichard Mitton     return sb_error;
994f86248d9SRichard Mitton }
995f86248d9SRichard Mitton 
996f86248d9SRichard Mitton SBError
997cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
9984413758cSJim Ingham {
9994413758cSJim Ingham     SBError sb_error;
10004413758cSJim Ingham 
10015160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10024413758cSJim Ingham 
10034413758cSJim Ingham     Mutex::Locker api_locker;
10044413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10054413758cSJim Ingham 
10064413758cSJim Ingham 
10074413758cSJim Ingham     if (log)
1008324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)",
1009324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1010324a1036SSaleem Abdulrasool                      frame.GetFrameID());
10114413758cSJim Ingham 
10124413758cSJim Ingham     if (exe_ctx.HasThreadScope())
10134413758cSJim Ingham     {
10144413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
1015cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
10164413758cSJim Ingham     }
10174413758cSJim Ingham 
10184413758cSJim Ingham     return sb_error;
10194413758cSJim Ingham }
10204413758cSJim Ingham 
1021481cef25SGreg Clayton 
1022722a0cdcSGreg Clayton bool
1023722a0cdcSGreg Clayton SBThread::Suspend()
1024722a0cdcSGreg Clayton {
10255160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10267fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1027c9858e4dSGreg Clayton     bool result = false;
10281ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1029722a0cdcSGreg Clayton     {
1030c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1031c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1032c9858e4dSGreg Clayton         {
10331ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
1034c9858e4dSGreg Clayton             result = true;
1035722a0cdcSGreg Clayton         }
1036c9858e4dSGreg Clayton         else
1037c9858e4dSGreg Clayton         {
1038c9858e4dSGreg Clayton             if (log)
1039324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Suspend() => error: process is running",
1040324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1041c9858e4dSGreg Clayton         }
1042c9858e4dSGreg Clayton     }
1043c9858e4dSGreg Clayton     if (log)
1044324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Suspend() => %i",
1045324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1046c9858e4dSGreg Clayton     return result;
1047722a0cdcSGreg Clayton }
1048722a0cdcSGreg Clayton 
1049722a0cdcSGreg Clayton bool
1050722a0cdcSGreg Clayton SBThread::Resume ()
1051722a0cdcSGreg Clayton {
10525160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
10537fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1054c9858e4dSGreg Clayton     bool result = false;
10551ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1056722a0cdcSGreg Clayton     {
1057c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
1058c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1059c9858e4dSGreg Clayton         {
10606c9ed91cSJim Ingham             const bool override_suspend = true;
10616c9ed91cSJim Ingham             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend);
1062c9858e4dSGreg Clayton             result = true;
1063722a0cdcSGreg Clayton         }
1064c9858e4dSGreg Clayton         else
1065c9858e4dSGreg Clayton         {
1066c9858e4dSGreg Clayton             if (log)
1067324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::Resume() => error: process is running",
1068324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1069c9858e4dSGreg Clayton         }
1070c9858e4dSGreg Clayton     }
1071c9858e4dSGreg Clayton     if (log)
1072324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::Resume() => %i",
1073324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), result);
1074c9858e4dSGreg Clayton     return result;
1075722a0cdcSGreg Clayton }
1076722a0cdcSGreg Clayton 
1077722a0cdcSGreg Clayton bool
1078722a0cdcSGreg Clayton SBThread::IsSuspended()
1079722a0cdcSGreg Clayton {
10807fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10811ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
10821ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
1083722a0cdcSGreg Clayton     return false;
1084722a0cdcSGreg Clayton }
1085722a0cdcSGreg Clayton 
1086a75418dbSAndrew Kaylor bool
1087a75418dbSAndrew Kaylor SBThread::IsStopped()
1088a75418dbSAndrew Kaylor {
1089a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
1090a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1091a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1092a75418dbSAndrew Kaylor     return false;
1093a75418dbSAndrew Kaylor }
1094a75418dbSAndrew Kaylor 
109530fdc8d8SChris Lattner SBProcess
109630fdc8d8SChris Lattner SBThread::GetProcess ()
109730fdc8d8SChris Lattner {
1098b9556accSGreg Clayton     SBProcess sb_process;
10997fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
11001ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
110130fdc8d8SChris Lattner     {
110230fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
11031ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
110430fdc8d8SChris Lattner     }
1105ceb6b139SCaroline Tice 
11065160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1107ceb6b139SCaroline Tice     if (log)
1108ceb6b139SCaroline Tice     {
1109481cef25SGreg Clayton         SBStream frame_desc_strm;
1110b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
1111324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1112324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1113324a1036SSaleem Abdulrasool                      static_cast<void*>(sb_process.GetSP().get()),
1114324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1115ceb6b139SCaroline Tice     }
1116ceb6b139SCaroline Tice 
1117b9556accSGreg Clayton     return sb_process;
111830fdc8d8SChris Lattner }
111930fdc8d8SChris Lattner 
112030fdc8d8SChris Lattner uint32_t
112130fdc8d8SChris Lattner SBThread::GetNumFrames ()
112230fdc8d8SChris Lattner {
11235160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1124ceb6b139SCaroline Tice 
1125ceb6b139SCaroline Tice     uint32_t num_frames = 0;
11264fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11274fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11284fc6cb9cSJim Ingham 
11291ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1130af67cecdSGreg Clayton     {
11317fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11327fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11337fdf9ef1SGreg Clayton         {
11341ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1135af67cecdSGreg Clayton         }
1136c9858e4dSGreg Clayton         else
1137c9858e4dSGreg Clayton         {
1138c9858e4dSGreg Clayton             if (log)
1139324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running",
1140324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1141c9858e4dSGreg Clayton         }
11427fdf9ef1SGreg Clayton     }
1143ceb6b139SCaroline Tice 
1144ceb6b139SCaroline Tice     if (log)
1145324a1036SSaleem Abdulrasool         log->Printf ("SBThread(%p)::GetNumFrames () => %u",
1146324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames);
1147ceb6b139SCaroline Tice 
1148ceb6b139SCaroline Tice     return num_frames;
114930fdc8d8SChris Lattner }
115030fdc8d8SChris Lattner 
115130fdc8d8SChris Lattner SBFrame
115230fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
115330fdc8d8SChris Lattner {
11545160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1155ceb6b139SCaroline Tice 
115630fdc8d8SChris Lattner     SBFrame sb_frame;
1157b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11584fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11594fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11604fc6cb9cSJim Ingham 
11611ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1162af67cecdSGreg Clayton     {
11637fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11647fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11657fdf9ef1SGreg Clayton         {
11661ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1167b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1168af67cecdSGreg Clayton         }
1169c9858e4dSGreg Clayton         else
1170c9858e4dSGreg Clayton         {
1171c9858e4dSGreg Clayton             if (log)
1172324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running",
1173324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1174c9858e4dSGreg Clayton         }
11757fdf9ef1SGreg Clayton     }
1176ceb6b139SCaroline Tice 
1177ceb6b139SCaroline Tice     if (log)
1178ceb6b139SCaroline Tice     {
1179481cef25SGreg Clayton         SBStream frame_desc_strm;
1180481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
11814838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1182324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1183324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1184324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1185ceb6b139SCaroline Tice     }
1186ceb6b139SCaroline Tice 
118730fdc8d8SChris Lattner     return sb_frame;
118830fdc8d8SChris Lattner }
118930fdc8d8SChris Lattner 
1190f028a1fbSGreg Clayton lldb::SBFrame
1191f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1192f028a1fbSGreg Clayton {
11935160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1194f028a1fbSGreg Clayton 
1195f028a1fbSGreg Clayton     SBFrame sb_frame;
1196b57e4a1bSJason Molenda     StackFrameSP frame_sp;
11974fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11984fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11994fc6cb9cSJim Ingham 
12001ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1201af67cecdSGreg Clayton     {
12027fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12037fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12047fdf9ef1SGreg Clayton         {
12051ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1206b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1207af67cecdSGreg Clayton         }
1208c9858e4dSGreg Clayton         else
1209c9858e4dSGreg Clayton         {
1210c9858e4dSGreg Clayton             if (log)
1211324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running",
1212324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1213c9858e4dSGreg Clayton         }
12147fdf9ef1SGreg Clayton     }
1215f028a1fbSGreg Clayton 
1216f028a1fbSGreg Clayton     if (log)
1217f028a1fbSGreg Clayton     {
1218481cef25SGreg Clayton         SBStream frame_desc_strm;
1219481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1220f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1221324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()),
1222324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1223324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1224f028a1fbSGreg Clayton     }
1225f028a1fbSGreg Clayton 
1226f028a1fbSGreg Clayton     return sb_frame;
1227f028a1fbSGreg Clayton }
1228f028a1fbSGreg Clayton 
1229f028a1fbSGreg Clayton lldb::SBFrame
1230f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1231f028a1fbSGreg Clayton {
12325160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1233f028a1fbSGreg Clayton 
1234f028a1fbSGreg Clayton     SBFrame sb_frame;
1235b57e4a1bSJason Molenda     StackFrameSP frame_sp;
12364fc6cb9cSJim Ingham     Mutex::Locker api_locker;
12374fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
12384fc6cb9cSJim Ingham 
12391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1240f028a1fbSGreg Clayton     {
12417fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
12427fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
12437fdf9ef1SGreg Clayton         {
12441ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
12451ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1246f028a1fbSGreg Clayton             if (frame_sp)
1247f028a1fbSGreg Clayton             {
12481ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1249b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1250f028a1fbSGreg Clayton             }
1251f028a1fbSGreg Clayton         }
1252c9858e4dSGreg Clayton         else
1253c9858e4dSGreg Clayton         {
1254c9858e4dSGreg Clayton             if (log)
1255324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running",
1256324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
1257c9858e4dSGreg Clayton         }
12587fdf9ef1SGreg Clayton     }
1259f028a1fbSGreg Clayton 
1260f028a1fbSGreg Clayton     if (log)
1261f028a1fbSGreg Clayton     {
1262481cef25SGreg Clayton         SBStream frame_desc_strm;
1263481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1264f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1265324a1036SSaleem Abdulrasool                      static_cast<void*>(exe_ctx.GetThreadPtr()), idx,
1266324a1036SSaleem Abdulrasool                      static_cast<void*>(frame_sp.get()),
1267324a1036SSaleem Abdulrasool                      frame_desc_strm.GetData());
1268f028a1fbSGreg Clayton     }
1269f028a1fbSGreg Clayton     return sb_frame;
1270f028a1fbSGreg Clayton }
1271f028a1fbSGreg Clayton 
12724f465cffSJim Ingham bool
12734f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
12744f465cffSJim Ingham {
12754f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
12764f465cffSJim Ingham }
12774f465cffSJim Ingham 
12784f465cffSJim Ingham SBFrame
12794f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
12804f465cffSJim Ingham {
12814f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
12824f465cffSJim Ingham 
12834f465cffSJim Ingham }
12844f465cffSJim Ingham 
12854f465cffSJim Ingham SBThread
12864f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
12874f465cffSJim Ingham {
12884f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
12894f465cffSJim Ingham }
1290f028a1fbSGreg Clayton 
129130fdc8d8SChris Lattner bool
129230fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
129330fdc8d8SChris Lattner {
12947fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
129530fdc8d8SChris Lattner }
129630fdc8d8SChris Lattner 
129730fdc8d8SChris Lattner bool
129830fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
129930fdc8d8SChris Lattner {
13007fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
130130fdc8d8SChris Lattner }
1302dde9cff3SCaroline Tice 
1303dde9cff3SCaroline Tice bool
13044f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
13054f465cffSJim Ingham {
13064f465cffSJim Ingham     Stream &strm = status.ref();
13074f465cffSJim Ingham 
13084f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
13094f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
13104f465cffSJim Ingham     {
13114f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
13124f465cffSJim Ingham     }
13134f465cffSJim Ingham     else
13144f465cffSJim Ingham         strm.PutCString ("No status");
13154f465cffSJim Ingham 
13164f465cffSJim Ingham     return true;
13174f465cffSJim Ingham }
13184f465cffSJim Ingham 
13194f465cffSJim Ingham bool
1320ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1321ceb6b139SCaroline Tice {
1322da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1323da7bc7d0SGreg Clayton 
13247fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
13251ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1326ceb6b139SCaroline Tice     {
1327d01b2953SDaniel Malea         strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1328ceb6b139SCaroline Tice     }
1329ceb6b139SCaroline Tice     else
1330da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1331ceb6b139SCaroline Tice 
1332ceb6b139SCaroline Tice     return true;
1333ceb6b139SCaroline Tice }
13345dd4916fSJason Molenda 
13355dd4916fSJason Molenda SBThread
1336008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type)
13375dd4916fSJason Molenda {
13385dd4916fSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
13395dd4916fSJason Molenda     Mutex::Locker api_locker;
13405dd4916fSJason Molenda     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
13415dd4916fSJason Molenda     SBThread sb_origin_thread;
13425dd4916fSJason Molenda 
13435dd4916fSJason Molenda     if (exe_ctx.HasThreadScope())
13445dd4916fSJason Molenda     {
13455dd4916fSJason Molenda         Process::StopLocker stop_locker;
13465dd4916fSJason Molenda         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
13475dd4916fSJason Molenda         {
13487a2f7904SJason Molenda             ThreadSP real_thread(exe_ctx.GetThreadSP());
13495dd4916fSJason Molenda             if (real_thread)
13505dd4916fSJason Molenda             {
13515dd4916fSJason Molenda                 ConstString type_const (type);
13527a2f7904SJason Molenda                 Process *process = exe_ctx.GetProcessPtr();
13537a2f7904SJason Molenda                 if (process)
13547a2f7904SJason Molenda                 {
13557a2f7904SJason Molenda                     SystemRuntime *runtime = process->GetSystemRuntime();
13565dd4916fSJason Molenda                     if (runtime)
13575dd4916fSJason Molenda                     {
1358008c45f1SJason Molenda                         ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const));
1359a6e9130dSJason Molenda                         if (new_thread_sp)
1360a6e9130dSJason Molenda                         {
13617a2f7904SJason Molenda                             // Save this in the Process' ExtendedThreadList so a strong pointer retains the
13627a2f7904SJason Molenda                             // object.
13637a2f7904SJason Molenda                             process->GetExtendedThreadList().AddThread (new_thread_sp);
13647a2f7904SJason Molenda                             sb_origin_thread.SetThread (new_thread_sp);
1365a6e9130dSJason Molenda                             if (log)
1366a6e9130dSJason Molenda                             {
1367a6e9130dSJason Molenda                                 const char *queue_name = new_thread_sp->GetQueueName();
1368a6e9130dSJason Molenda                                 if (queue_name == NULL)
1369a6e9130dSJason Molenda                                     queue_name = "";
1370324a1036SSaleem Abdulrasool                                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'",
1371324a1036SSaleem Abdulrasool                                              static_cast<void*>(exe_ctx.GetThreadPtr()),
1372324a1036SSaleem Abdulrasool                                              static_cast<void*>(new_thread_sp.get()),
1373324a1036SSaleem Abdulrasool                                              new_thread_sp->GetQueueID(),
1374324a1036SSaleem Abdulrasool                                              queue_name);
1375a6e9130dSJason Molenda                             }
1376a6e9130dSJason Molenda                         }
13777a2f7904SJason Molenda                     }
13785dd4916fSJason Molenda                 }
13795dd4916fSJason Molenda             }
13805dd4916fSJason Molenda         }
13815dd4916fSJason Molenda         else
13825dd4916fSJason Molenda         {
13835dd4916fSJason Molenda             if (log)
1384324a1036SSaleem Abdulrasool                 log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running",
1385324a1036SSaleem Abdulrasool                              static_cast<void*>(exe_ctx.GetThreadPtr()));
13865dd4916fSJason Molenda         }
13875dd4916fSJason Molenda     }
13885dd4916fSJason Molenda 
1389ac605f4aSJason Molenda     if (log && sb_origin_thread.IsValid() == false)
1390324a1036SSaleem Abdulrasool         log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread",
1391324a1036SSaleem Abdulrasool                     static_cast<void*>(exe_ctx.GetThreadPtr()));
13925dd4916fSJason Molenda     return sb_origin_thread;
13935dd4916fSJason Molenda }
13948ee9cb58SJason Molenda 
13958ee9cb58SJason Molenda uint32_t
13968ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID ()
13978ee9cb58SJason Molenda {
13988ee9cb58SJason Molenda     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
13998ee9cb58SJason Molenda     if (thread_sp)
14008ee9cb58SJason Molenda         return thread_sp->GetExtendedBacktraceOriginatingIndexID();
14018ee9cb58SJason Molenda     return LLDB_INVALID_INDEX32;
14028ee9cb58SJason Molenda }
1403