130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
104c5de699SEli Friedman #include "lldb/API/SBThread.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
166611103cSGreg Clayton #include "lldb/Core/Debugger.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
1830fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
196611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2030fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2230fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2330fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
24f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
2730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
2830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner 
334c5de699SEli Friedman #include "lldb/API/SBAddress.h"
344c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
35*4f465cffSJim Ingham #include "lldb/API/SBEvent.h"
3673ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
374c5de699SEli Friedman #include "lldb/API/SBProcess.h"
3873ca05a2SJim Ingham #include "lldb/API/SBValue.h"
3930fdc8d8SChris Lattner 
4030fdc8d8SChris Lattner using namespace lldb;
4130fdc8d8SChris Lattner using namespace lldb_private;
4230fdc8d8SChris Lattner 
43*4f465cffSJim Ingham const char *
44*4f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
45*4f465cffSJim Ingham {
46*4f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
47*4f465cffSJim Ingham }
48*4f465cffSJim Ingham 
49cfd1acedSGreg Clayton //----------------------------------------------------------------------
50cfd1acedSGreg Clayton // Constructors
51cfd1acedSGreg Clayton //----------------------------------------------------------------------
5230fdc8d8SChris Lattner SBThread::SBThread () :
537fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
5430fdc8d8SChris Lattner {
5530fdc8d8SChris Lattner }
5630fdc8d8SChris Lattner 
5730fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
587fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
5930fdc8d8SChris Lattner {
6030fdc8d8SChris Lattner }
6130fdc8d8SChris Lattner 
6292ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
637fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
6430fdc8d8SChris Lattner {
657fdf9ef1SGreg Clayton 
6630fdc8d8SChris Lattner }
6730fdc8d8SChris Lattner 
6830fdc8d8SChris Lattner //----------------------------------------------------------------------
69cfd1acedSGreg Clayton // Assignment operator
70cfd1acedSGreg Clayton //----------------------------------------------------------------------
71cfd1acedSGreg Clayton 
72cfd1acedSGreg Clayton const lldb::SBThread &
73cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
74cfd1acedSGreg Clayton {
75cfd1acedSGreg Clayton     if (this != &rhs)
767fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
77cfd1acedSGreg Clayton     return *this;
78cfd1acedSGreg Clayton }
79cfd1acedSGreg Clayton 
80cfd1acedSGreg Clayton //----------------------------------------------------------------------
8130fdc8d8SChris Lattner // Destructor
8230fdc8d8SChris Lattner //----------------------------------------------------------------------
8330fdc8d8SChris Lattner SBThread::~SBThread()
8430fdc8d8SChris Lattner {
8530fdc8d8SChris Lattner }
8630fdc8d8SChris Lattner 
8730fdc8d8SChris Lattner bool
8830fdc8d8SChris Lattner SBThread::IsValid() const
8930fdc8d8SChris Lattner {
907fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
9130fdc8d8SChris Lattner }
9230fdc8d8SChris Lattner 
9348e42549SGreg Clayton void
9448e42549SGreg Clayton SBThread::Clear ()
9548e42549SGreg Clayton {
967fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
9748e42549SGreg Clayton }
9848e42549SGreg Clayton 
9948e42549SGreg Clayton 
10030fdc8d8SChris Lattner StopReason
10130fdc8d8SChris Lattner SBThread::GetStopReason()
10230fdc8d8SChris Lattner {
1032d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
104ceb6b139SCaroline Tice 
105ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1064fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1074fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1084fc6cb9cSJim Ingham 
1091ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
11030fdc8d8SChris Lattner     {
1117fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1127fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1137fdf9ef1SGreg Clayton         {
11497d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
11530fdc8d8SChris Lattner         }
116c9858e4dSGreg Clayton         else
117c9858e4dSGreg Clayton         {
118c9858e4dSGreg Clayton             if (log)
119c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
120c9858e4dSGreg Clayton         }
1217fdf9ef1SGreg Clayton     }
122ceb6b139SCaroline Tice 
123ceb6b139SCaroline Tice     if (log)
1241ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
125750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
126ceb6b139SCaroline Tice 
127ceb6b139SCaroline Tice     return reason;
12830fdc8d8SChris Lattner }
12930fdc8d8SChris Lattner 
13030fdc8d8SChris Lattner size_t
1314e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1324e78f606SGreg Clayton {
1334fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1344fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1354fc6cb9cSJim Ingham 
1361ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1374e78f606SGreg Clayton     {
1387fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1397fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1407fdf9ef1SGreg Clayton         {
1411ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1424e78f606SGreg Clayton             if (stop_info_sp)
1434e78f606SGreg Clayton             {
1444e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1454e78f606SGreg Clayton                 switch (reason)
1464e78f606SGreg Clayton                 {
1474e78f606SGreg Clayton                 case eStopReasonInvalid:
1484e78f606SGreg Clayton                 case eStopReasonNone:
1494e78f606SGreg Clayton                 case eStopReasonTrace:
1504e78f606SGreg Clayton                 case eStopReasonPlanComplete:
1514e78f606SGreg Clayton                     // There is no data for these stop reasons.
1524e78f606SGreg Clayton                     return 0;
1534e78f606SGreg Clayton 
1544e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1554e78f606SGreg Clayton                     {
1564e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1571ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1584e78f606SGreg Clayton                         if (bp_site_sp)
1594e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1604e78f606SGreg Clayton                         else
1614e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1624e78f606SGreg Clayton                     }
1634e78f606SGreg Clayton                     break;
1644e78f606SGreg Clayton 
1654e78f606SGreg Clayton                 case eStopReasonWatchpoint:
166290fa41bSJohnny Chen                     return 1;
1674e78f606SGreg Clayton 
1684e78f606SGreg Clayton                 case eStopReasonSignal:
1694e78f606SGreg Clayton                     return 1;
1704e78f606SGreg Clayton 
1714e78f606SGreg Clayton                 case eStopReasonException:
1724e78f606SGreg Clayton                     return 1;
1734e78f606SGreg Clayton                 }
1744e78f606SGreg Clayton             }
1754e78f606SGreg Clayton         }
176c9858e4dSGreg Clayton         else
177c9858e4dSGreg Clayton         {
178c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
179c9858e4dSGreg Clayton             if (log)
180c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
181c9858e4dSGreg Clayton         }
1827fdf9ef1SGreg Clayton     }
1834e78f606SGreg Clayton     return 0;
1844e78f606SGreg Clayton }
1854e78f606SGreg Clayton 
1864e78f606SGreg Clayton uint64_t
1874e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1884e78f606SGreg Clayton {
1894fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1904fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1914fc6cb9cSJim Ingham 
1921ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1934e78f606SGreg Clayton     {
1947fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1957fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1967fdf9ef1SGreg Clayton         {
1971ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
1981ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1994e78f606SGreg Clayton             if (stop_info_sp)
2004e78f606SGreg Clayton             {
2014e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2024e78f606SGreg Clayton                 switch (reason)
2034e78f606SGreg Clayton                 {
2044e78f606SGreg Clayton                 case eStopReasonInvalid:
2054e78f606SGreg Clayton                 case eStopReasonNone:
2064e78f606SGreg Clayton                 case eStopReasonTrace:
2074e78f606SGreg Clayton                 case eStopReasonPlanComplete:
2084e78f606SGreg Clayton                     // There is no data for these stop reasons.
2094e78f606SGreg Clayton                     return 0;
2104e78f606SGreg Clayton 
2114e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2124e78f606SGreg Clayton                     {
2134e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2141ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2154e78f606SGreg Clayton                         if (bp_site_sp)
2164e78f606SGreg Clayton                         {
2174e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2184e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2194e78f606SGreg Clayton                             if (bp_loc_sp)
2204e78f606SGreg Clayton                             {
2214e78f606SGreg Clayton                                 if (bp_index & 1)
2224e78f606SGreg Clayton                                 {
2234e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2244e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2254e78f606SGreg Clayton                                 }
2264e78f606SGreg Clayton                                 else
2274e78f606SGreg Clayton                                 {
2284e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2294e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2304e78f606SGreg Clayton                                 }
2314e78f606SGreg Clayton                             }
2324e78f606SGreg Clayton                         }
2334e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2344e78f606SGreg Clayton                     }
2354e78f606SGreg Clayton                     break;
2364e78f606SGreg Clayton 
2374e78f606SGreg Clayton                 case eStopReasonWatchpoint:
238290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2394e78f606SGreg Clayton 
2404e78f606SGreg Clayton                 case eStopReasonSignal:
2414e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2424e78f606SGreg Clayton 
2434e78f606SGreg Clayton                 case eStopReasonException:
2444e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2454e78f606SGreg Clayton                 }
2464e78f606SGreg Clayton             }
2474e78f606SGreg Clayton         }
248c9858e4dSGreg Clayton         else
249c9858e4dSGreg Clayton         {
250c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
251c9858e4dSGreg Clayton             if (log)
252c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
253c9858e4dSGreg Clayton         }
2547fdf9ef1SGreg Clayton     }
2554e78f606SGreg Clayton     return 0;
2564e78f606SGreg Clayton }
2574e78f606SGreg Clayton 
2584e78f606SGreg Clayton size_t
25930fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
26030fdc8d8SChris Lattner {
2612d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
262ceb6b139SCaroline Tice 
2634fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2644fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2654fc6cb9cSJim Ingham 
2661ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
26730fdc8d8SChris Lattner     {
2687fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2697fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2707fdf9ef1SGreg Clayton         {
2717fdf9ef1SGreg Clayton 
2721ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
273b15bfc75SJim Ingham             if (stop_info_sp)
27430fdc8d8SChris Lattner             {
275b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
27630fdc8d8SChris Lattner                 if (stop_desc)
27730fdc8d8SChris Lattner                 {
278ceb6b139SCaroline Tice                     if (log)
2794838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2801ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
28130fdc8d8SChris Lattner                     if (dst)
28230fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
28330fdc8d8SChris Lattner                     else
28430fdc8d8SChris Lattner                     {
28530fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
28630fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
28730fdc8d8SChris Lattner                     }
28830fdc8d8SChris Lattner                 }
28930fdc8d8SChris Lattner                 else
29030fdc8d8SChris Lattner                 {
29130fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
292b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
29330fdc8d8SChris Lattner                     {
29430fdc8d8SChris Lattner                     case eStopReasonTrace:
29530fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
29630fdc8d8SChris Lattner                         {
29730fdc8d8SChris Lattner                             static char trace_desc[] = "step";
29830fdc8d8SChris Lattner                             stop_desc = trace_desc;
29930fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
30030fdc8d8SChris Lattner                         }
30130fdc8d8SChris Lattner                         break;
30230fdc8d8SChris Lattner 
30330fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
30430fdc8d8SChris Lattner                         {
30530fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
30630fdc8d8SChris Lattner                             stop_desc = bp_desc;
30730fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
30830fdc8d8SChris Lattner                         }
30930fdc8d8SChris Lattner                         break;
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
31230fdc8d8SChris Lattner                         {
31330fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
31430fdc8d8SChris Lattner                             stop_desc = wp_desc;
31530fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
31630fdc8d8SChris Lattner                         }
31730fdc8d8SChris Lattner                         break;
31830fdc8d8SChris Lattner 
31930fdc8d8SChris Lattner                     case eStopReasonSignal:
32030fdc8d8SChris Lattner                         {
3211ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
32230fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
32330fdc8d8SChris Lattner                             {
32430fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
32530fdc8d8SChris Lattner                                 stop_desc = signal_desc;
32630fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
32730fdc8d8SChris Lattner                             }
32830fdc8d8SChris Lattner                         }
32930fdc8d8SChris Lattner                         break;
33030fdc8d8SChris Lattner 
33130fdc8d8SChris Lattner                     case eStopReasonException:
33230fdc8d8SChris Lattner                         {
33330fdc8d8SChris Lattner                             char exc_desc[] = "exception";
33430fdc8d8SChris Lattner                             stop_desc = exc_desc;
33530fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
33630fdc8d8SChris Lattner                         }
33730fdc8d8SChris Lattner                         break;
338c982c768SGreg Clayton 
339c982c768SGreg Clayton                     default:
340c982c768SGreg Clayton                         break;
34130fdc8d8SChris Lattner                     }
34230fdc8d8SChris Lattner 
34330fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
34430fdc8d8SChris Lattner                     {
345ceb6b139SCaroline Tice                         if (log)
34693aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3471ac04c30SGreg Clayton                                          exe_ctx.GetThreadPtr(), stop_desc);
348ceb6b139SCaroline Tice 
34930fdc8d8SChris Lattner                         if (dst)
35030fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
35130fdc8d8SChris Lattner 
35230fdc8d8SChris Lattner                         if (stop_desc_len == 0)
35330fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
35430fdc8d8SChris Lattner 
35530fdc8d8SChris Lattner                         return stop_desc_len;
35630fdc8d8SChris Lattner                     }
35730fdc8d8SChris Lattner                 }
35830fdc8d8SChris Lattner             }
35930fdc8d8SChris Lattner         }
360c9858e4dSGreg Clayton         else
361c9858e4dSGreg Clayton         {
362c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
363c9858e4dSGreg Clayton             if (log)
364c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
365c9858e4dSGreg Clayton         }
3667fdf9ef1SGreg Clayton     }
36730fdc8d8SChris Lattner     if (dst)
36830fdc8d8SChris Lattner         *dst = 0;
36930fdc8d8SChris Lattner     return 0;
37030fdc8d8SChris Lattner }
37130fdc8d8SChris Lattner 
37273ca05a2SJim Ingham SBValue
37373ca05a2SJim Ingham SBThread::GetStopReturnValue ()
37473ca05a2SJim Ingham {
375c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
37673ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
3774fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3784fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3794fc6cb9cSJim Ingham 
3801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
38173ca05a2SJim Ingham     {
3827fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3837fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3847fdf9ef1SGreg Clayton         {
3851ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
38673ca05a2SJim Ingham             if (stop_info_sp)
38773ca05a2SJim Ingham             {
38873ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
38973ca05a2SJim Ingham             }
39073ca05a2SJim Ingham         }
391c9858e4dSGreg Clayton         else
392c9858e4dSGreg Clayton         {
393c9858e4dSGreg Clayton             if (log)
394c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
395c9858e4dSGreg Clayton         }
3967fdf9ef1SGreg Clayton     }
39773ca05a2SJim Ingham 
39873ca05a2SJim Ingham     if (log)
3991ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
40073ca05a2SJim Ingham                                                                   return_valobj_sp.get()
40173ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
40273ca05a2SJim Ingham                                                                         : "<no return value>");
40373ca05a2SJim Ingham 
40473ca05a2SJim Ingham     return SBValue (return_valobj_sp);
40573ca05a2SJim Ingham }
40673ca05a2SJim Ingham 
40730fdc8d8SChris Lattner void
40830fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
40930fdc8d8SChris Lattner {
4107fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
41130fdc8d8SChris Lattner }
41230fdc8d8SChris Lattner 
41330fdc8d8SChris Lattner 
41430fdc8d8SChris Lattner lldb::tid_t
41530fdc8d8SChris Lattner SBThread::GetThreadID () const
41630fdc8d8SChris Lattner {
4177fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
41817a6ad05SGreg Clayton     if (thread_sp)
4191ac04c30SGreg Clayton         return thread_sp->GetID();
4201ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
42130fdc8d8SChris Lattner }
42230fdc8d8SChris Lattner 
42330fdc8d8SChris Lattner uint32_t
42430fdc8d8SChris Lattner SBThread::GetIndexID () const
42530fdc8d8SChris Lattner {
4267fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
42717a6ad05SGreg Clayton     if (thread_sp)
42817a6ad05SGreg Clayton         return thread_sp->GetIndexID();
42930fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
43030fdc8d8SChris Lattner }
4311ac04c30SGreg Clayton 
43230fdc8d8SChris Lattner const char *
43330fdc8d8SChris Lattner SBThread::GetName () const
43430fdc8d8SChris Lattner {
435c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4364838131bSGreg Clayton     const char *name = NULL;
4374fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4384fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4394fc6cb9cSJim Ingham 
4401ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
441af67cecdSGreg Clayton     {
4427fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4437fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4447fdf9ef1SGreg Clayton         {
4451ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
446af67cecdSGreg Clayton         }
447c9858e4dSGreg Clayton         else
448c9858e4dSGreg Clayton         {
449c9858e4dSGreg Clayton             if (log)
450c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
451c9858e4dSGreg Clayton         }
4527fdf9ef1SGreg Clayton     }
453ceb6b139SCaroline Tice 
454ceb6b139SCaroline Tice     if (log)
4551ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
456ceb6b139SCaroline Tice 
4574838131bSGreg Clayton     return name;
45830fdc8d8SChris Lattner }
45930fdc8d8SChris Lattner 
46030fdc8d8SChris Lattner const char *
46130fdc8d8SChris Lattner SBThread::GetQueueName () const
46230fdc8d8SChris Lattner {
4634838131bSGreg Clayton     const char *name = NULL;
4644fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4654fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4664fc6cb9cSJim Ingham 
467c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4681ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
469af67cecdSGreg Clayton     {
4707fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4717fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4727fdf9ef1SGreg Clayton         {
4731ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
474af67cecdSGreg Clayton         }
475c9858e4dSGreg Clayton         else
476c9858e4dSGreg Clayton         {
477c9858e4dSGreg Clayton             if (log)
478c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
479c9858e4dSGreg Clayton         }
4807fdf9ef1SGreg Clayton     }
481ceb6b139SCaroline Tice 
482ceb6b139SCaroline Tice     if (log)
4831ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
484ceb6b139SCaroline Tice 
4854838131bSGreg Clayton     return name;
48630fdc8d8SChris Lattner }
48730fdc8d8SChris Lattner 
48864e7ead1SJim Ingham SBError
48964e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
49064e7ead1SJim Ingham {
49164e7ead1SJim Ingham     SBError sb_error;
49264e7ead1SJim Ingham 
49364e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
49464e7ead1SJim Ingham     if (!process)
49564e7ead1SJim Ingham     {
49664e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
49764e7ead1SJim Ingham         return sb_error;
49864e7ead1SJim Ingham     }
49964e7ead1SJim Ingham 
50064e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
50164e7ead1SJim Ingham     if (!thread)
50264e7ead1SJim Ingham     {
50364e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
50464e7ead1SJim Ingham         return sb_error;
50564e7ead1SJim Ingham     }
50664e7ead1SJim Ingham 
50764e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
50864e7ead1SJim Ingham     // then a "continue" will resume the plan.
50964e7ead1SJim Ingham     if (new_plan != NULL)
51064e7ead1SJim Ingham     {
51164e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
51264e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
51364e7ead1SJim Ingham     }
51464e7ead1SJim Ingham 
51564e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
51664e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
51764e7ead1SJim Ingham     sb_error.ref() = process->Resume();
51864e7ead1SJim Ingham 
51964e7ead1SJim Ingham     if (sb_error.Success())
52064e7ead1SJim Ingham     {
52164e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
52264e7ead1SJim Ingham         // process to stop yet again!
52364e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
52464e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
52564e7ead1SJim Ingham     }
52664e7ead1SJim Ingham 
52764e7ead1SJim Ingham     return sb_error;
52864e7ead1SJim Ingham }
52930fdc8d8SChris Lattner 
53030fdc8d8SChris Lattner void
53130fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
53230fdc8d8SChris Lattner {
5332d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
534ceb6b139SCaroline Tice 
5354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5374fc6cb9cSJim Ingham 
53817a6ad05SGreg Clayton 
539ceb6b139SCaroline Tice     if (log)
5401ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
541ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
542ceb6b139SCaroline Tice 
5431ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
54430fdc8d8SChris Lattner     {
5451ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5467ba6e991SJim Ingham         bool abort_other_plans = false;
5471ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
54864e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
54930fdc8d8SChris Lattner 
55030fdc8d8SChris Lattner         if (frame_sp)
55130fdc8d8SChris Lattner         {
55230fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
55330fdc8d8SChris Lattner             {
55430fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
55564e7ead1SJim Ingham                 new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
55630fdc8d8SChris Lattner                                                                 eStepTypeOver,
55730fdc8d8SChris Lattner                                                                 sc.line_entry.range,
55830fdc8d8SChris Lattner                                                                 sc,
559474966a4SGreg Clayton                                                                 stop_other_threads,
560474966a4SGreg Clayton                                                                 false);
56130fdc8d8SChris Lattner 
56230fdc8d8SChris Lattner             }
56330fdc8d8SChris Lattner             else
56430fdc8d8SChris Lattner             {
56564e7ead1SJim Ingham                 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
56630fdc8d8SChris Lattner                                                                             abort_other_plans,
56730fdc8d8SChris Lattner                                                                             stop_other_threads);
56830fdc8d8SChris Lattner             }
56930fdc8d8SChris Lattner         }
57030fdc8d8SChris Lattner 
57164e7ead1SJim Ingham         // This returns an error, we should use it!
57264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
57330fdc8d8SChris Lattner     }
57430fdc8d8SChris Lattner }
57530fdc8d8SChris Lattner 
57630fdc8d8SChris Lattner void
57730fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
57830fdc8d8SChris Lattner {
5792d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
580ceb6b139SCaroline Tice 
5814fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5824fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
58317a6ad05SGreg Clayton 
58417a6ad05SGreg Clayton     if (log)
5851ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
58617a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
5871ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
58830fdc8d8SChris Lattner     {
5897ba6e991SJim Ingham         bool abort_other_plans = false;
59030fdc8d8SChris Lattner 
5911ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5921ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
59364e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
59430fdc8d8SChris Lattner 
59530fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
59630fdc8d8SChris Lattner         {
597474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
59830fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
59964e7ead1SJim Ingham             new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans,
60030fdc8d8SChris Lattner                                                             eStepTypeInto,
60130fdc8d8SChris Lattner                                                             sc.line_entry.range,
60230fdc8d8SChris Lattner                                                             sc,
603474966a4SGreg Clayton                                                             stop_other_threads,
604474966a4SGreg Clayton                                                             avoid_code_without_debug_info);
60530fdc8d8SChris Lattner         }
60630fdc8d8SChris Lattner         else
60730fdc8d8SChris Lattner         {
60864e7ead1SJim Ingham             new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
60930fdc8d8SChris Lattner                                                                         abort_other_plans,
61030fdc8d8SChris Lattner                                                                         stop_other_threads);
61130fdc8d8SChris Lattner         }
61230fdc8d8SChris Lattner 
61364e7ead1SJim Ingham         // This returns an error, we should use it!
61464e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
61530fdc8d8SChris Lattner     }
61630fdc8d8SChris Lattner }
61730fdc8d8SChris Lattner 
61830fdc8d8SChris Lattner void
61930fdc8d8SChris Lattner SBThread::StepOut ()
62030fdc8d8SChris Lattner {
6212d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
622ceb6b139SCaroline Tice 
6234fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6244fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6254fc6cb9cSJim Ingham 
626ceb6b139SCaroline Tice 
62717a6ad05SGreg Clayton     if (log)
6281ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
62917a6ad05SGreg Clayton 
6301ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
63130fdc8d8SChris Lattner     {
6327ba6e991SJim Ingham         bool abort_other_plans = false;
63394b09246SJim Ingham         bool stop_other_threads = false;
63430fdc8d8SChris Lattner 
6351ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6361ac04c30SGreg Clayton 
63764e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
638481cef25SGreg Clayton                                                                   NULL,
639481cef25SGreg Clayton                                                                   false,
640481cef25SGreg Clayton                                                                   stop_other_threads,
641481cef25SGreg Clayton                                                                   eVoteYes,
642481cef25SGreg Clayton                                                                   eVoteNoOpinion,
643481cef25SGreg Clayton                                                                   0);
644481cef25SGreg Clayton 
64564e7ead1SJim Ingham         // This returns an error, we should use it!
64664e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
647481cef25SGreg Clayton     }
648481cef25SGreg Clayton }
649481cef25SGreg Clayton 
650481cef25SGreg Clayton void
651481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
652481cef25SGreg Clayton {
653481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
654481cef25SGreg Clayton 
6554fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6564fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6574fc6cb9cSJim Ingham 
658b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
659481cef25SGreg Clayton     if (log)
660481cef25SGreg Clayton     {
661481cef25SGreg Clayton         SBStream frame_desc_strm;
662481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
6631ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
664481cef25SGreg Clayton     }
665481cef25SGreg Clayton 
6661ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
667481cef25SGreg Clayton     {
6687ba6e991SJim Ingham         bool abort_other_plans = false;
66994b09246SJim Ingham         bool stop_other_threads = false;
6701ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
671481cef25SGreg Clayton 
67264e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
673481cef25SGreg Clayton                                                                     NULL,
674481cef25SGreg Clayton                                                                     false,
675481cef25SGreg Clayton                                                                     stop_other_threads,
676481cef25SGreg Clayton                                                                     eVoteYes,
677481cef25SGreg Clayton                                                                     eVoteNoOpinion,
678b9556accSGreg Clayton                                                                     frame_sp->GetFrameIndex());
67930fdc8d8SChris Lattner 
68064e7ead1SJim Ingham         // This returns an error, we should use it!
68164e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
68230fdc8d8SChris Lattner     }
68330fdc8d8SChris Lattner }
68430fdc8d8SChris Lattner 
68530fdc8d8SChris Lattner void
68630fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
68730fdc8d8SChris Lattner {
6882d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
689ceb6b139SCaroline Tice 
6904fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6914fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6924fc6cb9cSJim Ingham 
6931ac04c30SGreg Clayton 
694ceb6b139SCaroline Tice 
69517a6ad05SGreg Clayton     if (log)
6961ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
69717a6ad05SGreg Clayton 
6981ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
69930fdc8d8SChris Lattner     {
7001ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
70164e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
70264e7ead1SJim Ingham 
70364e7ead1SJim Ingham         // This returns an error, we should use it!
70464e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
70530fdc8d8SChris Lattner     }
70630fdc8d8SChris Lattner }
70730fdc8d8SChris Lattner 
70830fdc8d8SChris Lattner void
70930fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
71030fdc8d8SChris Lattner {
7112d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
712ceb6b139SCaroline Tice 
7134fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7144fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7154fc6cb9cSJim Ingham 
716ceb6b139SCaroline Tice 
71717a6ad05SGreg Clayton     if (log)
7181ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
71917a6ad05SGreg Clayton 
7201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
72130fdc8d8SChris Lattner     {
7227ba6e991SJim Ingham         bool abort_other_plans = false;
72330fdc8d8SChris Lattner         bool stop_other_threads = true;
72430fdc8d8SChris Lattner 
725e72dfb32SGreg Clayton         Address target_addr (addr);
72630fdc8d8SChris Lattner 
7271ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7281ac04c30SGreg Clayton 
72964e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
73064e7ead1SJim Ingham 
73164e7ead1SJim Ingham         // This returns an error, we should use it!
73264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
73330fdc8d8SChris Lattner     }
73430fdc8d8SChris Lattner }
73530fdc8d8SChris Lattner 
736481cef25SGreg Clayton SBError
737481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
738481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
739481cef25SGreg Clayton                          uint32_t line)
740481cef25SGreg Clayton {
741481cef25SGreg Clayton     SBError sb_error;
742481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
743481cef25SGreg Clayton     char path[PATH_MAX];
744481cef25SGreg Clayton 
7454fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7464fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7474fc6cb9cSJim Ingham 
748b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
74917a6ad05SGreg Clayton 
750481cef25SGreg Clayton     if (log)
751481cef25SGreg Clayton     {
752481cef25SGreg Clayton         SBStream frame_desc_strm;
753481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
754481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
755481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
7561ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
757b9556accSGreg Clayton                      frame_sp.get(),
758481cef25SGreg Clayton                      frame_desc_strm.GetData(),
759481cef25SGreg Clayton                      path, line);
760481cef25SGreg Clayton     }
761481cef25SGreg Clayton 
7621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
763481cef25SGreg Clayton     {
7641ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
7651ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
766481cef25SGreg Clayton 
767481cef25SGreg Clayton         if (line == 0)
768481cef25SGreg Clayton         {
769481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
770481cef25SGreg Clayton             return sb_error;
771481cef25SGreg Clayton         }
772481cef25SGreg Clayton 
773b9556accSGreg Clayton         if (!frame_sp)
774481cef25SGreg Clayton         {
7751ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
776481cef25SGreg Clayton             if (!frame_sp)
7771ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
778481cef25SGreg Clayton         }
779481cef25SGreg Clayton 
780481cef25SGreg Clayton         SymbolContext frame_sc;
781481cef25SGreg Clayton         if (!frame_sp)
782481cef25SGreg Clayton         {
783481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
784481cef25SGreg Clayton             return sb_error;
785481cef25SGreg Clayton         }
786481cef25SGreg Clayton 
787481cef25SGreg Clayton         // If we have a frame, get its line
788481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
789481cef25SGreg Clayton                                                eSymbolContextFunction  |
790481cef25SGreg Clayton                                                eSymbolContextLineEntry |
791481cef25SGreg Clayton                                                eSymbolContextSymbol    );
792481cef25SGreg Clayton 
793481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
794481cef25SGreg Clayton         {
795481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
796481cef25SGreg Clayton             return sb_error;
797481cef25SGreg Clayton         }
798481cef25SGreg Clayton 
799481cef25SGreg Clayton         FileSpec step_file_spec;
800481cef25SGreg Clayton         if (sb_file_spec.IsValid())
801481cef25SGreg Clayton         {
802481cef25SGreg Clayton             // The file spec passed in was valid, so use it
803481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
804481cef25SGreg Clayton         }
805481cef25SGreg Clayton         else
806481cef25SGreg Clayton         {
807481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
808481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
809481cef25SGreg Clayton             else
810481cef25SGreg Clayton             {
811481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
812481cef25SGreg Clayton                 return sb_error;
813481cef25SGreg Clayton             }
814481cef25SGreg Clayton         }
815481cef25SGreg Clayton 
8169b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
8179b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
8189b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
8199b70ddb3SJim Ingham         // error message.
8209b70ddb3SJim Ingham 
8219b70ddb3SJim Ingham         bool all_in_function = true;
8229b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
8239b70ddb3SJim Ingham 
824481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
8257ba6e991SJim Ingham         const bool abort_other_plans = false;
826c02e3344SJim Ingham         const bool stop_other_threads = false;
827481cef25SGreg Clayton         const bool check_inlines = true;
828481cef25SGreg Clayton         const bool exact = false;
829481cef25SGreg Clayton 
830481cef25SGreg Clayton         SymbolContextList sc_list;
8319b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
8329b70ddb3SJim Ingham                                                                                line,
8339b70ddb3SJim Ingham                                                                                check_inlines,
8349b70ddb3SJim Ingham                                                                                exact,
8359b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
8369b70ddb3SJim Ingham                                                                                sc_list);
837481cef25SGreg Clayton         if (num_matches > 0)
838481cef25SGreg Clayton         {
839481cef25SGreg Clayton             SymbolContext sc;
840481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
841481cef25SGreg Clayton             {
842481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
843481cef25SGreg Clayton                 {
8449b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
845481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
846481cef25SGreg Clayton                     {
8479b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
848481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
8499b70ddb3SJim Ingham                         else
8509b70ddb3SJim Ingham                             all_in_function = false;
851481cef25SGreg Clayton                     }
852481cef25SGreg Clayton                 }
853481cef25SGreg Clayton             }
854481cef25SGreg Clayton         }
855481cef25SGreg Clayton 
856481cef25SGreg Clayton         if (step_over_until_addrs.empty())
857481cef25SGreg Clayton         {
8589b70ddb3SJim Ingham             if (all_in_function)
8599b70ddb3SJim Ingham             {
860481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
861fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
862481cef25SGreg Clayton             }
863481cef25SGreg Clayton             else
86486edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
8659b70ddb3SJim Ingham         }
8669b70ddb3SJim Ingham         else
867481cef25SGreg Clayton         {
86864e7ead1SJim Ingham             ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
869481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
870481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
871481cef25SGreg Clayton                                                                         stop_other_threads,
872481cef25SGreg Clayton                                                                         frame_sp->GetFrameIndex());
873481cef25SGreg Clayton 
87464e7ead1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan);
875481cef25SGreg Clayton         }
876481cef25SGreg Clayton     }
877481cef25SGreg Clayton     else
878481cef25SGreg Clayton     {
879481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
880481cef25SGreg Clayton     }
881481cef25SGreg Clayton     return sb_error;
882481cef25SGreg Clayton }
883481cef25SGreg Clayton 
8844413758cSJim Ingham SBError
885cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
8864413758cSJim Ingham {
8874413758cSJim Ingham     SBError sb_error;
8884413758cSJim Ingham 
8894413758cSJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
8904413758cSJim Ingham 
8914413758cSJim Ingham     Mutex::Locker api_locker;
8924413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
8934413758cSJim Ingham 
8944413758cSJim Ingham 
8954413758cSJim Ingham     if (log)
896cb640dd8SJim Ingham         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
8974413758cSJim Ingham 
8984413758cSJim Ingham     if (exe_ctx.HasThreadScope())
8994413758cSJim Ingham     {
9004413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
901cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9024413758cSJim Ingham     }
9034413758cSJim Ingham 
9044413758cSJim Ingham     return sb_error;
9054413758cSJim Ingham }
9064413758cSJim Ingham 
907481cef25SGreg Clayton 
908722a0cdcSGreg Clayton bool
909722a0cdcSGreg Clayton SBThread::Suspend()
910722a0cdcSGreg Clayton {
911c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9127fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
913c9858e4dSGreg Clayton     bool result = false;
9141ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
915722a0cdcSGreg Clayton     {
916c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
917c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
918c9858e4dSGreg Clayton         {
9191ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
920c9858e4dSGreg Clayton             result = true;
921722a0cdcSGreg Clayton         }
922c9858e4dSGreg Clayton         else
923c9858e4dSGreg Clayton         {
924c9858e4dSGreg Clayton             if (log)
925c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
926c9858e4dSGreg Clayton         }
927c9858e4dSGreg Clayton     }
928c9858e4dSGreg Clayton     if (log)
929c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
930c9858e4dSGreg Clayton     return result;
931722a0cdcSGreg Clayton }
932722a0cdcSGreg Clayton 
933722a0cdcSGreg Clayton bool
934722a0cdcSGreg Clayton SBThread::Resume ()
935722a0cdcSGreg Clayton {
936c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9377fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
938c9858e4dSGreg Clayton     bool result = false;
9391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
940722a0cdcSGreg Clayton     {
941c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
942c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
943c9858e4dSGreg Clayton         {
9441ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
945c9858e4dSGreg Clayton             result = true;
946722a0cdcSGreg Clayton         }
947c9858e4dSGreg Clayton         else
948c9858e4dSGreg Clayton         {
949c9858e4dSGreg Clayton             if (log)
950c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
951c9858e4dSGreg Clayton         }
952c9858e4dSGreg Clayton     }
953c9858e4dSGreg Clayton     if (log)
954c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
955c9858e4dSGreg Clayton     return result;
956722a0cdcSGreg Clayton }
957722a0cdcSGreg Clayton 
958722a0cdcSGreg Clayton bool
959722a0cdcSGreg Clayton SBThread::IsSuspended()
960722a0cdcSGreg Clayton {
9617fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
9631ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
964722a0cdcSGreg Clayton     return false;
965722a0cdcSGreg Clayton }
966722a0cdcSGreg Clayton 
96730fdc8d8SChris Lattner SBProcess
96830fdc8d8SChris Lattner SBThread::GetProcess ()
96930fdc8d8SChris Lattner {
970ceb6b139SCaroline Tice 
971b9556accSGreg Clayton     SBProcess sb_process;
972b9556accSGreg Clayton     ProcessSP process_sp;
9737fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9741ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
97530fdc8d8SChris Lattner     {
97630fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
9771ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
97830fdc8d8SChris Lattner     }
979ceb6b139SCaroline Tice 
9802d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
981ceb6b139SCaroline Tice     if (log)
982ceb6b139SCaroline Tice     {
983481cef25SGreg Clayton         SBStream frame_desc_strm;
984b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
9851ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
986b9556accSGreg Clayton                      process_sp.get(), frame_desc_strm.GetData());
987ceb6b139SCaroline Tice     }
988ceb6b139SCaroline Tice 
989b9556accSGreg Clayton     return sb_process;
99030fdc8d8SChris Lattner }
99130fdc8d8SChris Lattner 
99230fdc8d8SChris Lattner uint32_t
99330fdc8d8SChris Lattner SBThread::GetNumFrames ()
99430fdc8d8SChris Lattner {
9952d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
996ceb6b139SCaroline Tice 
997ceb6b139SCaroline Tice     uint32_t num_frames = 0;
9984fc6cb9cSJim Ingham     Mutex::Locker api_locker;
9994fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10004fc6cb9cSJim Ingham 
10011ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1002af67cecdSGreg Clayton     {
10037fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10047fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10057fdf9ef1SGreg Clayton         {
10061ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1007af67cecdSGreg Clayton         }
1008c9858e4dSGreg Clayton         else
1009c9858e4dSGreg Clayton         {
1010c9858e4dSGreg Clayton             if (log)
1011c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1012c9858e4dSGreg Clayton         }
10137fdf9ef1SGreg Clayton     }
1014ceb6b139SCaroline Tice 
1015ceb6b139SCaroline Tice     if (log)
10161ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1017ceb6b139SCaroline Tice 
1018ceb6b139SCaroline Tice     return num_frames;
101930fdc8d8SChris Lattner }
102030fdc8d8SChris Lattner 
102130fdc8d8SChris Lattner SBFrame
102230fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
102330fdc8d8SChris Lattner {
10242d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1025ceb6b139SCaroline Tice 
102630fdc8d8SChris Lattner     SBFrame sb_frame;
1027b9556accSGreg Clayton     StackFrameSP frame_sp;
10284fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10294fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10304fc6cb9cSJim Ingham 
10311ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1032af67cecdSGreg Clayton     {
10337fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10347fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10357fdf9ef1SGreg Clayton         {
10361ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1037b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1038af67cecdSGreg Clayton         }
1039c9858e4dSGreg Clayton         else
1040c9858e4dSGreg Clayton         {
1041c9858e4dSGreg Clayton             if (log)
1042c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1043c9858e4dSGreg Clayton         }
10447fdf9ef1SGreg Clayton     }
1045ceb6b139SCaroline Tice 
1046ceb6b139SCaroline Tice     if (log)
1047ceb6b139SCaroline Tice     {
1048481cef25SGreg Clayton         SBStream frame_desc_strm;
1049481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
10504838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
10511ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1052ceb6b139SCaroline Tice     }
1053ceb6b139SCaroline Tice 
105430fdc8d8SChris Lattner     return sb_frame;
105530fdc8d8SChris Lattner }
105630fdc8d8SChris Lattner 
1057f028a1fbSGreg Clayton lldb::SBFrame
1058f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1059f028a1fbSGreg Clayton {
1060f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1061f028a1fbSGreg Clayton 
1062f028a1fbSGreg Clayton     SBFrame sb_frame;
1063b9556accSGreg Clayton     StackFrameSP frame_sp;
10644fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10654fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10664fc6cb9cSJim Ingham 
10671ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1068af67cecdSGreg Clayton     {
10697fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10707fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10717fdf9ef1SGreg Clayton         {
10721ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1073b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1074af67cecdSGreg Clayton         }
1075c9858e4dSGreg Clayton         else
1076c9858e4dSGreg Clayton         {
1077c9858e4dSGreg Clayton             if (log)
1078c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1079c9858e4dSGreg Clayton         }
10807fdf9ef1SGreg Clayton     }
1081f028a1fbSGreg Clayton 
1082f028a1fbSGreg Clayton     if (log)
1083f028a1fbSGreg Clayton     {
1084481cef25SGreg Clayton         SBStream frame_desc_strm;
1085481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1086f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
10871ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1088f028a1fbSGreg Clayton     }
1089f028a1fbSGreg Clayton 
1090f028a1fbSGreg Clayton     return sb_frame;
1091f028a1fbSGreg Clayton }
1092f028a1fbSGreg Clayton 
1093f028a1fbSGreg Clayton lldb::SBFrame
1094f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1095f028a1fbSGreg Clayton {
1096f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1097f028a1fbSGreg Clayton 
1098f028a1fbSGreg Clayton     SBFrame sb_frame;
1099b9556accSGreg Clayton     StackFrameSP frame_sp;
11004fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11014fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11024fc6cb9cSJim Ingham 
11031ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1104f028a1fbSGreg Clayton     {
11057fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11067fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11077fdf9ef1SGreg Clayton         {
11081ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
11091ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1110f028a1fbSGreg Clayton             if (frame_sp)
1111f028a1fbSGreg Clayton             {
11121ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1113b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1114f028a1fbSGreg Clayton             }
1115f028a1fbSGreg Clayton         }
1116c9858e4dSGreg Clayton         else
1117c9858e4dSGreg Clayton         {
1118c9858e4dSGreg Clayton             if (log)
1119c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1120c9858e4dSGreg Clayton         }
11217fdf9ef1SGreg Clayton     }
1122f028a1fbSGreg Clayton 
1123f028a1fbSGreg Clayton     if (log)
1124f028a1fbSGreg Clayton     {
1125481cef25SGreg Clayton         SBStream frame_desc_strm;
1126481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1127f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
11281ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1129f028a1fbSGreg Clayton     }
1130f028a1fbSGreg Clayton     return sb_frame;
1131f028a1fbSGreg Clayton }
1132f028a1fbSGreg Clayton 
1133*4f465cffSJim Ingham bool
1134*4f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
1135*4f465cffSJim Ingham {
1136*4f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1137*4f465cffSJim Ingham }
1138*4f465cffSJim Ingham 
1139*4f465cffSJim Ingham SBFrame
1140*4f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
1141*4f465cffSJim Ingham {
1142*4f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1143*4f465cffSJim Ingham 
1144*4f465cffSJim Ingham }
1145*4f465cffSJim Ingham 
1146*4f465cffSJim Ingham SBThread
1147*4f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
1148*4f465cffSJim Ingham {
1149*4f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1150*4f465cffSJim Ingham }
1151f028a1fbSGreg Clayton 
115230fdc8d8SChris Lattner bool
115330fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
115430fdc8d8SChris Lattner {
11557fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
115630fdc8d8SChris Lattner }
115730fdc8d8SChris Lattner 
115830fdc8d8SChris Lattner bool
115930fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
116030fdc8d8SChris Lattner {
11617fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
116230fdc8d8SChris Lattner }
1163dde9cff3SCaroline Tice 
1164dde9cff3SCaroline Tice bool
1165*4f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
1166*4f465cffSJim Ingham {
1167*4f465cffSJim Ingham     Stream &strm = status.ref();
1168*4f465cffSJim Ingham 
1169*4f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
1170*4f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
1171*4f465cffSJim Ingham     {
1172*4f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1173*4f465cffSJim Ingham     }
1174*4f465cffSJim Ingham     else
1175*4f465cffSJim Ingham         strm.PutCString ("No status");
1176*4f465cffSJim Ingham 
1177*4f465cffSJim Ingham     return true;
1178*4f465cffSJim Ingham }
1179*4f465cffSJim Ingham 
1180*4f465cffSJim Ingham bool
1181ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1182ceb6b139SCaroline Tice {
1183da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1184da7bc7d0SGreg Clayton 
11857fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
11861ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1187ceb6b139SCaroline Tice     {
11881ac04c30SGreg Clayton         strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
1189ceb6b139SCaroline Tice     }
1190ceb6b139SCaroline Tice     else
1191da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1192ceb6b139SCaroline Tice 
1193ceb6b139SCaroline Tice     return true;
1194ceb6b139SCaroline Tice }
1195