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"
3573ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
364c5de699SEli Friedman #include "lldb/API/SBProcess.h"
3773ca05a2SJim Ingham #include "lldb/API/SBValue.h"
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner using namespace lldb;
4030fdc8d8SChris Lattner using namespace lldb_private;
4130fdc8d8SChris Lattner 
42cfd1acedSGreg Clayton //----------------------------------------------------------------------
43cfd1acedSGreg Clayton // Constructors
44cfd1acedSGreg Clayton //----------------------------------------------------------------------
4530fdc8d8SChris Lattner SBThread::SBThread () :
467fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner 
5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
517fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
5230fdc8d8SChris Lattner {
5330fdc8d8SChris Lattner }
5430fdc8d8SChris Lattner 
5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
567fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
5730fdc8d8SChris Lattner {
587fdf9ef1SGreg Clayton 
5930fdc8d8SChris Lattner }
6030fdc8d8SChris Lattner 
6130fdc8d8SChris Lattner //----------------------------------------------------------------------
62cfd1acedSGreg Clayton // Assignment operator
63cfd1acedSGreg Clayton //----------------------------------------------------------------------
64cfd1acedSGreg Clayton 
65cfd1acedSGreg Clayton const lldb::SBThread &
66cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
67cfd1acedSGreg Clayton {
68cfd1acedSGreg Clayton     if (this != &rhs)
697fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
70cfd1acedSGreg Clayton     return *this;
71cfd1acedSGreg Clayton }
72cfd1acedSGreg Clayton 
73cfd1acedSGreg Clayton //----------------------------------------------------------------------
7430fdc8d8SChris Lattner // Destructor
7530fdc8d8SChris Lattner //----------------------------------------------------------------------
7630fdc8d8SChris Lattner SBThread::~SBThread()
7730fdc8d8SChris Lattner {
7830fdc8d8SChris Lattner }
7930fdc8d8SChris Lattner 
8030fdc8d8SChris Lattner bool
8130fdc8d8SChris Lattner SBThread::IsValid() const
8230fdc8d8SChris Lattner {
837fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
8430fdc8d8SChris Lattner }
8530fdc8d8SChris Lattner 
8648e42549SGreg Clayton void
8748e42549SGreg Clayton SBThread::Clear ()
8848e42549SGreg Clayton {
897fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
9048e42549SGreg Clayton }
9148e42549SGreg Clayton 
9248e42549SGreg Clayton 
9330fdc8d8SChris Lattner StopReason
9430fdc8d8SChris Lattner SBThread::GetStopReason()
9530fdc8d8SChris Lattner {
962d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
97ceb6b139SCaroline Tice 
98ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
997fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1001ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
10130fdc8d8SChris Lattner     {
1027fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1037fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1047fdf9ef1SGreg Clayton         {
1051ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1061ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
107b15bfc75SJim Ingham             if (stop_info_sp)
108ceb6b139SCaroline Tice                 reason =  stop_info_sp->GetStopReason();
10930fdc8d8SChris Lattner         }
110*c9858e4dSGreg Clayton         else
111*c9858e4dSGreg Clayton         {
112*c9858e4dSGreg Clayton             if (log)
113*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
114*c9858e4dSGreg Clayton         }
1157fdf9ef1SGreg Clayton     }
116ceb6b139SCaroline Tice 
117ceb6b139SCaroline Tice     if (log)
1181ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
119750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
120ceb6b139SCaroline Tice 
121ceb6b139SCaroline Tice     return reason;
12230fdc8d8SChris Lattner }
12330fdc8d8SChris Lattner 
12430fdc8d8SChris Lattner size_t
1254e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1264e78f606SGreg Clayton {
1277fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1281ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1294e78f606SGreg Clayton     {
1307fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1317fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1327fdf9ef1SGreg Clayton         {
1331ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1341ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1354e78f606SGreg Clayton             if (stop_info_sp)
1364e78f606SGreg Clayton             {
1374e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1384e78f606SGreg Clayton                 switch (reason)
1394e78f606SGreg Clayton                 {
1404e78f606SGreg Clayton                 case eStopReasonInvalid:
1414e78f606SGreg Clayton                 case eStopReasonNone:
1424e78f606SGreg Clayton                 case eStopReasonTrace:
1434e78f606SGreg Clayton                 case eStopReasonPlanComplete:
1444e78f606SGreg Clayton                     // There is no data for these stop reasons.
1454e78f606SGreg Clayton                     return 0;
1464e78f606SGreg Clayton 
1474e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1484e78f606SGreg Clayton                     {
1494e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1501ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1514e78f606SGreg Clayton                         if (bp_site_sp)
1524e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1534e78f606SGreg Clayton                         else
1544e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1554e78f606SGreg Clayton                     }
1564e78f606SGreg Clayton                     break;
1574e78f606SGreg Clayton 
1584e78f606SGreg Clayton                 case eStopReasonWatchpoint:
159290fa41bSJohnny Chen                     return 1;
1604e78f606SGreg Clayton 
1614e78f606SGreg Clayton                 case eStopReasonSignal:
1624e78f606SGreg Clayton                     return 1;
1634e78f606SGreg Clayton 
1644e78f606SGreg Clayton                 case eStopReasonException:
1654e78f606SGreg Clayton                     return 1;
1664e78f606SGreg Clayton                 }
1674e78f606SGreg Clayton             }
1684e78f606SGreg Clayton         }
169*c9858e4dSGreg Clayton         else
170*c9858e4dSGreg Clayton         {
171*c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
172*c9858e4dSGreg Clayton             if (log)
173*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
174*c9858e4dSGreg Clayton         }
1757fdf9ef1SGreg Clayton     }
1764e78f606SGreg Clayton     return 0;
1774e78f606SGreg Clayton }
1784e78f606SGreg Clayton 
1794e78f606SGreg Clayton uint64_t
1804e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1814e78f606SGreg Clayton {
1827fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
1831ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1844e78f606SGreg Clayton     {
1857fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1867fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1877fdf9ef1SGreg Clayton         {
1887fdf9ef1SGreg Clayton 
1891ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1901ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
1911ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
1924e78f606SGreg Clayton             if (stop_info_sp)
1934e78f606SGreg Clayton             {
1944e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1954e78f606SGreg Clayton                 switch (reason)
1964e78f606SGreg Clayton                 {
1974e78f606SGreg Clayton                 case eStopReasonInvalid:
1984e78f606SGreg Clayton                 case eStopReasonNone:
1994e78f606SGreg Clayton                 case eStopReasonTrace:
2004e78f606SGreg Clayton                 case eStopReasonPlanComplete:
2014e78f606SGreg Clayton                     // There is no data for these stop reasons.
2024e78f606SGreg Clayton                     return 0;
2034e78f606SGreg Clayton 
2044e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2054e78f606SGreg Clayton                     {
2064e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2071ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2084e78f606SGreg Clayton                         if (bp_site_sp)
2094e78f606SGreg Clayton                         {
2104e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2114e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2124e78f606SGreg Clayton                             if (bp_loc_sp)
2134e78f606SGreg Clayton                             {
2144e78f606SGreg Clayton                                 if (bp_index & 1)
2154e78f606SGreg Clayton                                 {
2164e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2174e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2184e78f606SGreg Clayton                                 }
2194e78f606SGreg Clayton                                 else
2204e78f606SGreg Clayton                                 {
2214e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2224e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2234e78f606SGreg Clayton                                 }
2244e78f606SGreg Clayton                             }
2254e78f606SGreg Clayton                         }
2264e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2274e78f606SGreg Clayton                     }
2284e78f606SGreg Clayton                     break;
2294e78f606SGreg Clayton 
2304e78f606SGreg Clayton                 case eStopReasonWatchpoint:
231290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2324e78f606SGreg Clayton 
2334e78f606SGreg Clayton                 case eStopReasonSignal:
2344e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2354e78f606SGreg Clayton 
2364e78f606SGreg Clayton                 case eStopReasonException:
2374e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2384e78f606SGreg Clayton                 }
2394e78f606SGreg Clayton             }
2404e78f606SGreg Clayton         }
241*c9858e4dSGreg Clayton         else
242*c9858e4dSGreg Clayton         {
243*c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
244*c9858e4dSGreg Clayton             if (log)
245*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
246*c9858e4dSGreg Clayton         }
2477fdf9ef1SGreg Clayton     }
2484e78f606SGreg Clayton     return 0;
2494e78f606SGreg Clayton }
2504e78f606SGreg Clayton 
2514e78f606SGreg Clayton size_t
25230fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
25330fdc8d8SChris Lattner {
2542d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
255ceb6b139SCaroline Tice 
2567fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
2571ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
25830fdc8d8SChris Lattner     {
2597fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2607fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2617fdf9ef1SGreg Clayton         {
2627fdf9ef1SGreg Clayton 
2631ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
2641ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
265b15bfc75SJim Ingham             if (stop_info_sp)
26630fdc8d8SChris Lattner             {
267b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
26830fdc8d8SChris Lattner                 if (stop_desc)
26930fdc8d8SChris Lattner                 {
270ceb6b139SCaroline Tice                     if (log)
2714838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2721ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
27330fdc8d8SChris Lattner                     if (dst)
27430fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
27530fdc8d8SChris Lattner                     else
27630fdc8d8SChris Lattner                     {
27730fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
27830fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
27930fdc8d8SChris Lattner                     }
28030fdc8d8SChris Lattner                 }
28130fdc8d8SChris Lattner                 else
28230fdc8d8SChris Lattner                 {
28330fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
284b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
28530fdc8d8SChris Lattner                     {
28630fdc8d8SChris Lattner                     case eStopReasonTrace:
28730fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
28830fdc8d8SChris Lattner                         {
28930fdc8d8SChris Lattner                             static char trace_desc[] = "step";
29030fdc8d8SChris Lattner                             stop_desc = trace_desc;
29130fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
29230fdc8d8SChris Lattner                         }
29330fdc8d8SChris Lattner                         break;
29430fdc8d8SChris Lattner 
29530fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
29630fdc8d8SChris Lattner                         {
29730fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
29830fdc8d8SChris Lattner                             stop_desc = bp_desc;
29930fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
30030fdc8d8SChris Lattner                         }
30130fdc8d8SChris Lattner                         break;
30230fdc8d8SChris Lattner 
30330fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
30430fdc8d8SChris Lattner                         {
30530fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
30630fdc8d8SChris Lattner                             stop_desc = wp_desc;
30730fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
30830fdc8d8SChris Lattner                         }
30930fdc8d8SChris Lattner                         break;
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner                     case eStopReasonSignal:
31230fdc8d8SChris Lattner                         {
3131ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
31430fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
31530fdc8d8SChris Lattner                             {
31630fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
31730fdc8d8SChris Lattner                                 stop_desc = signal_desc;
31830fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
31930fdc8d8SChris Lattner                             }
32030fdc8d8SChris Lattner                         }
32130fdc8d8SChris Lattner                         break;
32230fdc8d8SChris Lattner 
32330fdc8d8SChris Lattner                     case eStopReasonException:
32430fdc8d8SChris Lattner                         {
32530fdc8d8SChris Lattner                             char exc_desc[] = "exception";
32630fdc8d8SChris Lattner                             stop_desc = exc_desc;
32730fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
32830fdc8d8SChris Lattner                         }
32930fdc8d8SChris Lattner                         break;
330c982c768SGreg Clayton 
331c982c768SGreg Clayton                     default:
332c982c768SGreg Clayton                         break;
33330fdc8d8SChris Lattner                     }
33430fdc8d8SChris Lattner 
33530fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
33630fdc8d8SChris Lattner                     {
337ceb6b139SCaroline Tice                         if (log)
33893aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3391ac04c30SGreg Clayton                                          exe_ctx.GetThreadPtr(), stop_desc);
340ceb6b139SCaroline Tice 
34130fdc8d8SChris Lattner                         if (dst)
34230fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
34330fdc8d8SChris Lattner 
34430fdc8d8SChris Lattner                         if (stop_desc_len == 0)
34530fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
34630fdc8d8SChris Lattner 
34730fdc8d8SChris Lattner                         return stop_desc_len;
34830fdc8d8SChris Lattner                     }
34930fdc8d8SChris Lattner                 }
35030fdc8d8SChris Lattner             }
35130fdc8d8SChris Lattner         }
352*c9858e4dSGreg Clayton         else
353*c9858e4dSGreg Clayton         {
354*c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
355*c9858e4dSGreg Clayton             if (log)
356*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
357*c9858e4dSGreg Clayton         }
3587fdf9ef1SGreg Clayton     }
35930fdc8d8SChris Lattner     if (dst)
36030fdc8d8SChris Lattner         *dst = 0;
36130fdc8d8SChris Lattner     return 0;
36230fdc8d8SChris Lattner }
36330fdc8d8SChris Lattner 
36473ca05a2SJim Ingham SBValue
36573ca05a2SJim Ingham SBThread::GetStopReturnValue ()
36673ca05a2SJim Ingham {
367*c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
36873ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
3697fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
3701ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
37173ca05a2SJim Ingham     {
3727fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3737fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3747fdf9ef1SGreg Clayton         {
3751ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
3761ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
37773ca05a2SJim Ingham             if (stop_info_sp)
37873ca05a2SJim Ingham             {
37973ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
38073ca05a2SJim Ingham             }
38173ca05a2SJim Ingham         }
382*c9858e4dSGreg Clayton         else
383*c9858e4dSGreg Clayton         {
384*c9858e4dSGreg Clayton             if (log)
385*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
386*c9858e4dSGreg Clayton         }
3877fdf9ef1SGreg Clayton     }
38873ca05a2SJim Ingham 
38973ca05a2SJim Ingham     if (log)
3901ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
39173ca05a2SJim Ingham                                                                   return_valobj_sp.get()
39273ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
39373ca05a2SJim Ingham                                                                         : "<no return value>");
39473ca05a2SJim Ingham 
39573ca05a2SJim Ingham     return SBValue (return_valobj_sp);
39673ca05a2SJim Ingham }
39773ca05a2SJim Ingham 
39830fdc8d8SChris Lattner void
39930fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
40030fdc8d8SChris Lattner {
4017fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
40230fdc8d8SChris Lattner }
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner lldb::tid_t
40630fdc8d8SChris Lattner SBThread::GetThreadID () const
40730fdc8d8SChris Lattner {
4087fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
40917a6ad05SGreg Clayton     if (thread_sp)
4101ac04c30SGreg Clayton         return thread_sp->GetID();
4111ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
41230fdc8d8SChris Lattner }
41330fdc8d8SChris Lattner 
41430fdc8d8SChris Lattner uint32_t
41530fdc8d8SChris Lattner SBThread::GetIndexID () const
41630fdc8d8SChris Lattner {
4177fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
41817a6ad05SGreg Clayton     if (thread_sp)
41917a6ad05SGreg Clayton         return thread_sp->GetIndexID();
42030fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
42130fdc8d8SChris Lattner }
4221ac04c30SGreg Clayton 
42330fdc8d8SChris Lattner const char *
42430fdc8d8SChris Lattner SBThread::GetName () const
42530fdc8d8SChris Lattner {
426*c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4274838131bSGreg Clayton     const char *name = NULL;
4287fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
4291ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
430af67cecdSGreg Clayton     {
4317fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4327fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4337fdf9ef1SGreg Clayton         {
4341ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
4351ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
436af67cecdSGreg Clayton         }
437*c9858e4dSGreg Clayton         else
438*c9858e4dSGreg Clayton         {
439*c9858e4dSGreg Clayton             if (log)
440*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
441*c9858e4dSGreg Clayton         }
4427fdf9ef1SGreg Clayton     }
443ceb6b139SCaroline Tice 
444ceb6b139SCaroline Tice     if (log)
4451ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
446ceb6b139SCaroline Tice 
4474838131bSGreg Clayton     return name;
44830fdc8d8SChris Lattner }
44930fdc8d8SChris Lattner 
45030fdc8d8SChris Lattner const char *
45130fdc8d8SChris Lattner SBThread::GetQueueName () const
45230fdc8d8SChris Lattner {
4534838131bSGreg Clayton     const char *name = NULL;
4547fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
455*c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4561ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
457af67cecdSGreg Clayton     {
4587fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4597fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4607fdf9ef1SGreg Clayton         {
4611ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
4621ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
463af67cecdSGreg Clayton         }
464*c9858e4dSGreg Clayton         else
465*c9858e4dSGreg Clayton         {
466*c9858e4dSGreg Clayton             if (log)
467*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
468*c9858e4dSGreg Clayton         }
4697fdf9ef1SGreg Clayton     }
470ceb6b139SCaroline Tice 
471ceb6b139SCaroline Tice     if (log)
4721ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
473ceb6b139SCaroline Tice 
4744838131bSGreg Clayton     return name;
47530fdc8d8SChris Lattner }
47630fdc8d8SChris Lattner 
47730fdc8d8SChris Lattner 
47830fdc8d8SChris Lattner void
47930fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
48030fdc8d8SChris Lattner {
4812d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
482ceb6b139SCaroline Tice 
4837fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
48417a6ad05SGreg Clayton 
485ceb6b139SCaroline Tice     if (log)
4861ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
487ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
488ceb6b139SCaroline Tice 
4891ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
49030fdc8d8SChris Lattner     {
4911ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
4921ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
49330fdc8d8SChris Lattner         bool abort_other_plans = true;
4941ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
49530fdc8d8SChris Lattner 
49630fdc8d8SChris Lattner         if (frame_sp)
49730fdc8d8SChris Lattner         {
49830fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
49930fdc8d8SChris Lattner             {
50030fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
5011ac04c30SGreg Clayton                 thread->QueueThreadPlanForStepRange (abort_other_plans,
50230fdc8d8SChris Lattner                                                      eStepTypeOver,
50330fdc8d8SChris Lattner                                                      sc.line_entry.range,
50430fdc8d8SChris Lattner                                                      sc,
505474966a4SGreg Clayton                                                      stop_other_threads,
506474966a4SGreg Clayton                                                      false);
50730fdc8d8SChris Lattner 
50830fdc8d8SChris Lattner             }
50930fdc8d8SChris Lattner             else
51030fdc8d8SChris Lattner             {
5111ac04c30SGreg Clayton                 thread->QueueThreadPlanForStepSingleInstruction (true,
51230fdc8d8SChris Lattner                                                                  abort_other_plans,
51330fdc8d8SChris Lattner                                                                  stop_other_threads);
51430fdc8d8SChris Lattner             }
51530fdc8d8SChris Lattner         }
51630fdc8d8SChris Lattner 
5171ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
51830fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
5191ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
5201ac04c30SGreg Clayton         Error error (process->Resume());
5215d5028b5SGreg Clayton         if (error.Success())
5225d5028b5SGreg Clayton         {
5235d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5245d5028b5SGreg Clayton             // process to stop yet again!
5251ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
5261ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
5275d5028b5SGreg Clayton         }
52830fdc8d8SChris Lattner     }
52930fdc8d8SChris Lattner }
53030fdc8d8SChris Lattner 
53130fdc8d8SChris Lattner void
53230fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
53330fdc8d8SChris Lattner {
5342d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
535ceb6b139SCaroline Tice 
5367fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
53717a6ad05SGreg Clayton 
53817a6ad05SGreg Clayton     if (log)
5391ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
54017a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
5411ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
54230fdc8d8SChris Lattner     {
5431ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
54430fdc8d8SChris Lattner         bool abort_other_plans = true;
54530fdc8d8SChris Lattner 
5461ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5471ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
54830fdc8d8SChris Lattner 
54930fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
55030fdc8d8SChris Lattner         {
551474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
55230fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
5531ac04c30SGreg Clayton             thread->QueueThreadPlanForStepRange (abort_other_plans,
55430fdc8d8SChris Lattner                                                  eStepTypeInto,
55530fdc8d8SChris Lattner                                                  sc.line_entry.range,
55630fdc8d8SChris Lattner                                                  sc,
557474966a4SGreg Clayton                                                  stop_other_threads,
558474966a4SGreg Clayton                                                  avoid_code_without_debug_info);
55930fdc8d8SChris Lattner         }
56030fdc8d8SChris Lattner         else
56130fdc8d8SChris Lattner         {
5621ac04c30SGreg Clayton             thread->QueueThreadPlanForStepSingleInstruction (false,
56330fdc8d8SChris Lattner                                                              abort_other_plans,
56430fdc8d8SChris Lattner                                                              stop_other_threads);
56530fdc8d8SChris Lattner         }
56630fdc8d8SChris Lattner 
5671ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
56830fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
5691ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
5701ac04c30SGreg Clayton         Error error (process->Resume());
5715d5028b5SGreg Clayton         if (error.Success())
5725d5028b5SGreg Clayton         {
5735d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5745d5028b5SGreg Clayton             // process to stop yet again!
5751ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
5761ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
5775d5028b5SGreg Clayton         }
57830fdc8d8SChris Lattner     }
57930fdc8d8SChris Lattner }
58030fdc8d8SChris Lattner 
58130fdc8d8SChris Lattner void
58230fdc8d8SChris Lattner SBThread::StepOut ()
58330fdc8d8SChris Lattner {
5842d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
585ceb6b139SCaroline Tice 
5867fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
587ceb6b139SCaroline Tice 
58817a6ad05SGreg Clayton     if (log)
5891ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
59017a6ad05SGreg Clayton 
5911ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
59230fdc8d8SChris Lattner     {
5931ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
59430fdc8d8SChris Lattner         bool abort_other_plans = true;
59530fdc8d8SChris Lattner         bool stop_other_threads = true;
59630fdc8d8SChris Lattner 
5971ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5981ac04c30SGreg Clayton 
5991ac04c30SGreg Clayton         thread->QueueThreadPlanForStepOut (abort_other_plans,
600481cef25SGreg Clayton                                               NULL,
601481cef25SGreg Clayton                                               false,
602481cef25SGreg Clayton                                               stop_other_threads,
603481cef25SGreg Clayton                                               eVoteYes,
604481cef25SGreg Clayton                                               eVoteNoOpinion,
605481cef25SGreg Clayton                                               0);
606481cef25SGreg Clayton 
6071ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
6081ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
6091ac04c30SGreg Clayton         Error error (process->Resume());
610481cef25SGreg Clayton         if (error.Success())
611481cef25SGreg Clayton         {
612481cef25SGreg Clayton             // If we are doing synchronous mode, then wait for the
613481cef25SGreg Clayton             // process to stop yet again!
6141ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
6151ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
616481cef25SGreg Clayton         }
617481cef25SGreg Clayton     }
618481cef25SGreg Clayton }
619481cef25SGreg Clayton 
620481cef25SGreg Clayton void
621481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
622481cef25SGreg Clayton {
623481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
624481cef25SGreg Clayton 
6257fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
626b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
627481cef25SGreg Clayton     if (log)
628481cef25SGreg Clayton     {
629481cef25SGreg Clayton         SBStream frame_desc_strm;
630481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
6311ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
632481cef25SGreg Clayton     }
633481cef25SGreg Clayton 
6341ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
635481cef25SGreg Clayton     {
6361ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
637481cef25SGreg Clayton         bool abort_other_plans = true;
638481cef25SGreg Clayton         bool stop_other_threads = true;
6391ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
640481cef25SGreg Clayton 
6411ac04c30SGreg Clayton         thread->QueueThreadPlanForStepOut (abort_other_plans,
642481cef25SGreg Clayton                                               NULL,
643481cef25SGreg Clayton                                               false,
644481cef25SGreg Clayton                                               stop_other_threads,
645481cef25SGreg Clayton                                               eVoteYes,
646481cef25SGreg Clayton                                               eVoteNoOpinion,
647b9556accSGreg Clayton                                               frame_sp->GetFrameIndex());
64830fdc8d8SChris Lattner 
6491ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
6501ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
6511ac04c30SGreg Clayton         Error error (process->Resume());
6525d5028b5SGreg Clayton         if (error.Success())
6535d5028b5SGreg Clayton         {
6545d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6555d5028b5SGreg Clayton             // process to stop yet again!
6561ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
6571ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
6585d5028b5SGreg Clayton         }
65930fdc8d8SChris Lattner     }
66030fdc8d8SChris Lattner }
66130fdc8d8SChris Lattner 
66230fdc8d8SChris Lattner void
66330fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
66430fdc8d8SChris Lattner {
6652d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
666ceb6b139SCaroline Tice 
6677fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
6681ac04c30SGreg Clayton 
669ceb6b139SCaroline Tice 
67017a6ad05SGreg Clayton     if (log)
6711ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
67217a6ad05SGreg Clayton 
6731ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
67430fdc8d8SChris Lattner     {
6751ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
6761ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6771ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
6781ac04c30SGreg Clayton         thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
6791ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
6801ac04c30SGreg Clayton         Error error (process->Resume());
6815d5028b5SGreg Clayton         if (error.Success())
6825d5028b5SGreg Clayton         {
6835d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6845d5028b5SGreg Clayton             // process to stop yet again!
6851ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
6861ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
6875d5028b5SGreg Clayton         }
68830fdc8d8SChris Lattner     }
68930fdc8d8SChris Lattner }
69030fdc8d8SChris Lattner 
69130fdc8d8SChris Lattner void
69230fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
69330fdc8d8SChris Lattner {
6942d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
695ceb6b139SCaroline Tice 
6967fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
697ceb6b139SCaroline Tice 
69817a6ad05SGreg Clayton     if (log)
6991ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
70017a6ad05SGreg Clayton 
7011ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
70230fdc8d8SChris Lattner     {
7031ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
70430fdc8d8SChris Lattner         bool abort_other_plans = true;
70530fdc8d8SChris Lattner         bool stop_other_threads = true;
70630fdc8d8SChris Lattner 
707e72dfb32SGreg Clayton         Address target_addr (addr);
70830fdc8d8SChris Lattner 
7091ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7101ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
7111ac04c30SGreg Clayton 
7121ac04c30SGreg Clayton         thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
7131ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
7141ac04c30SGreg Clayton         Error error (process->Resume());
7155d5028b5SGreg Clayton         if (error.Success())
7165d5028b5SGreg Clayton         {
7175d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
7185d5028b5SGreg Clayton             // process to stop yet again!
7191ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
7201ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
7215d5028b5SGreg Clayton         }
72230fdc8d8SChris Lattner     }
72330fdc8d8SChris Lattner }
72430fdc8d8SChris Lattner 
725481cef25SGreg Clayton SBError
726481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
727481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
728481cef25SGreg Clayton                          uint32_t line)
729481cef25SGreg Clayton {
730481cef25SGreg Clayton     SBError sb_error;
731481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
732481cef25SGreg Clayton     char path[PATH_MAX];
733481cef25SGreg Clayton 
7347fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
735b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
73617a6ad05SGreg Clayton 
737481cef25SGreg Clayton     if (log)
738481cef25SGreg Clayton     {
739481cef25SGreg Clayton         SBStream frame_desc_strm;
740481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
741481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
742481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
7431ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
744b9556accSGreg Clayton                      frame_sp.get(),
745481cef25SGreg Clayton                      frame_desc_strm.GetData(),
746481cef25SGreg Clayton                      path, line);
747481cef25SGreg Clayton     }
748481cef25SGreg Clayton 
7491ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
750481cef25SGreg Clayton     {
7511ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
7521ac04c30SGreg Clayton         Mutex::Locker api_locker (target->GetAPIMutex());
7531ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
754481cef25SGreg Clayton 
755481cef25SGreg Clayton         if (line == 0)
756481cef25SGreg Clayton         {
757481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
758481cef25SGreg Clayton             return sb_error;
759481cef25SGreg Clayton         }
760481cef25SGreg Clayton 
761481cef25SGreg Clayton         StackFrameSP frame_sp;
762b9556accSGreg Clayton         if (!frame_sp)
763481cef25SGreg Clayton         {
7641ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
765481cef25SGreg Clayton             if (!frame_sp)
7661ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
767481cef25SGreg Clayton         }
768481cef25SGreg Clayton 
769481cef25SGreg Clayton         SymbolContext frame_sc;
770481cef25SGreg Clayton         if (!frame_sp)
771481cef25SGreg Clayton         {
772481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
773481cef25SGreg Clayton             return sb_error;
774481cef25SGreg Clayton         }
775481cef25SGreg Clayton 
776481cef25SGreg Clayton         // If we have a frame, get its line
777481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
778481cef25SGreg Clayton                                                eSymbolContextFunction  |
779481cef25SGreg Clayton                                                eSymbolContextLineEntry |
780481cef25SGreg Clayton                                                eSymbolContextSymbol    );
781481cef25SGreg Clayton 
782481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
783481cef25SGreg Clayton         {
784481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
785481cef25SGreg Clayton             return sb_error;
786481cef25SGreg Clayton         }
787481cef25SGreg Clayton 
788481cef25SGreg Clayton         FileSpec step_file_spec;
789481cef25SGreg Clayton         if (sb_file_spec.IsValid())
790481cef25SGreg Clayton         {
791481cef25SGreg Clayton             // The file spec passed in was valid, so use it
792481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
793481cef25SGreg Clayton         }
794481cef25SGreg Clayton         else
795481cef25SGreg Clayton         {
796481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
797481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
798481cef25SGreg Clayton             else
799481cef25SGreg Clayton             {
800481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
801481cef25SGreg Clayton                 return sb_error;
802481cef25SGreg Clayton             }
803481cef25SGreg Clayton         }
804481cef25SGreg Clayton 
8059b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
8069b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
8079b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
8089b70ddb3SJim Ingham         // error message.
8099b70ddb3SJim Ingham 
8109b70ddb3SJim Ingham         bool all_in_function = true;
8119b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
8129b70ddb3SJim Ingham 
813481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
814481cef25SGreg Clayton         const bool abort_other_plans = true;
815481cef25SGreg Clayton         const bool stop_other_threads = true;
816481cef25SGreg Clayton         const bool check_inlines = true;
817481cef25SGreg Clayton         const bool exact = false;
818481cef25SGreg Clayton 
819481cef25SGreg Clayton         SymbolContextList sc_list;
8209b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
8219b70ddb3SJim Ingham                                                                                line,
8229b70ddb3SJim Ingham                                                                                check_inlines,
8239b70ddb3SJim Ingham                                                                                exact,
8249b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
8259b70ddb3SJim Ingham                                                                                sc_list);
826481cef25SGreg Clayton         if (num_matches > 0)
827481cef25SGreg Clayton         {
828481cef25SGreg Clayton             SymbolContext sc;
829481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
830481cef25SGreg Clayton             {
831481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
832481cef25SGreg Clayton                 {
8339b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
834481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
835481cef25SGreg Clayton                     {
8369b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
837481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
8389b70ddb3SJim Ingham                         else
8399b70ddb3SJim Ingham                             all_in_function = false;
840481cef25SGreg Clayton                     }
841481cef25SGreg Clayton                 }
842481cef25SGreg Clayton             }
843481cef25SGreg Clayton         }
844481cef25SGreg Clayton 
845481cef25SGreg Clayton         if (step_over_until_addrs.empty())
846481cef25SGreg Clayton         {
8479b70ddb3SJim Ingham             if (all_in_function)
8489b70ddb3SJim Ingham             {
849481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
850fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
851481cef25SGreg Clayton             }
852481cef25SGreg Clayton             else
85386edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
8549b70ddb3SJim Ingham         }
8559b70ddb3SJim Ingham         else
856481cef25SGreg Clayton         {
8571ac04c30SGreg Clayton             thread->QueueThreadPlanForStepUntil (abort_other_plans,
858481cef25SGreg Clayton                                                  &step_over_until_addrs[0],
859481cef25SGreg Clayton                                                  step_over_until_addrs.size(),
860481cef25SGreg Clayton                                                  stop_other_threads,
861481cef25SGreg Clayton                                                  frame_sp->GetFrameIndex());
862481cef25SGreg Clayton 
8631ac04c30SGreg Clayton             Process *process = exe_ctx.GetProcessPtr();
8641ac04c30SGreg Clayton 
8651ac04c30SGreg Clayton             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
8661ac04c30SGreg Clayton             sb_error.ref() = process->Resume();
867481cef25SGreg Clayton             if (sb_error->Success())
868481cef25SGreg Clayton             {
869481cef25SGreg Clayton                 // If we are doing synchronous mode, then wait for the
870481cef25SGreg Clayton                 // process to stop yet again!
8711ac04c30SGreg Clayton                 if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
8721ac04c30SGreg Clayton                     process->WaitForProcessToStop (NULL);
873481cef25SGreg Clayton             }
874481cef25SGreg Clayton         }
875481cef25SGreg Clayton     }
876481cef25SGreg Clayton     else
877481cef25SGreg Clayton     {
878481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
879481cef25SGreg Clayton     }
880481cef25SGreg Clayton     return sb_error;
881481cef25SGreg Clayton }
882481cef25SGreg Clayton 
883481cef25SGreg Clayton 
884722a0cdcSGreg Clayton bool
885722a0cdcSGreg Clayton SBThread::Suspend()
886722a0cdcSGreg Clayton {
887*c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
8887fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
889*c9858e4dSGreg Clayton     bool result = false;
8901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
891722a0cdcSGreg Clayton     {
892*c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
893*c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
894*c9858e4dSGreg Clayton         {
8951ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
896*c9858e4dSGreg Clayton             result = true;
897722a0cdcSGreg Clayton         }
898*c9858e4dSGreg Clayton         else
899*c9858e4dSGreg Clayton         {
900*c9858e4dSGreg Clayton             if (log)
901*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
902*c9858e4dSGreg Clayton         }
903*c9858e4dSGreg Clayton     }
904*c9858e4dSGreg Clayton     if (log)
905*c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
906*c9858e4dSGreg Clayton     return result;
907722a0cdcSGreg Clayton }
908722a0cdcSGreg Clayton 
909722a0cdcSGreg Clayton bool
910722a0cdcSGreg Clayton SBThread::Resume ()
911722a0cdcSGreg Clayton {
912*c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9137fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
914*c9858e4dSGreg Clayton     bool result = false;
9151ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
916722a0cdcSGreg Clayton     {
917*c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
918*c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
919*c9858e4dSGreg Clayton         {
9201ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
921*c9858e4dSGreg Clayton             result = true;
922722a0cdcSGreg Clayton         }
923*c9858e4dSGreg Clayton         else
924*c9858e4dSGreg Clayton         {
925*c9858e4dSGreg Clayton             if (log)
926*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
927*c9858e4dSGreg Clayton         }
928*c9858e4dSGreg Clayton     }
929*c9858e4dSGreg Clayton     if (log)
930*c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
931*c9858e4dSGreg Clayton     return result;
932722a0cdcSGreg Clayton }
933722a0cdcSGreg Clayton 
934722a0cdcSGreg Clayton bool
935722a0cdcSGreg Clayton SBThread::IsSuspended()
936722a0cdcSGreg Clayton {
9377fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9381ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
9391ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
940722a0cdcSGreg Clayton     return false;
941722a0cdcSGreg Clayton }
942722a0cdcSGreg Clayton 
94330fdc8d8SChris Lattner SBProcess
94430fdc8d8SChris Lattner SBThread::GetProcess ()
94530fdc8d8SChris Lattner {
946ceb6b139SCaroline Tice 
947b9556accSGreg Clayton     SBProcess sb_process;
948b9556accSGreg Clayton     ProcessSP process_sp;
9497fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9501ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
95130fdc8d8SChris Lattner     {
95230fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
9531ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
95430fdc8d8SChris Lattner     }
955ceb6b139SCaroline Tice 
9562d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
957ceb6b139SCaroline Tice     if (log)
958ceb6b139SCaroline Tice     {
959481cef25SGreg Clayton         SBStream frame_desc_strm;
960b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
9611ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
962b9556accSGreg Clayton                      process_sp.get(), frame_desc_strm.GetData());
963ceb6b139SCaroline Tice     }
964ceb6b139SCaroline Tice 
965b9556accSGreg Clayton     return sb_process;
96630fdc8d8SChris Lattner }
96730fdc8d8SChris Lattner 
96830fdc8d8SChris Lattner uint32_t
96930fdc8d8SChris Lattner SBThread::GetNumFrames ()
97030fdc8d8SChris Lattner {
9712d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
972ceb6b139SCaroline Tice 
973ceb6b139SCaroline Tice     uint32_t num_frames = 0;
9747fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9751ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
976af67cecdSGreg Clayton     {
9777fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
9787fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
9797fdf9ef1SGreg Clayton         {
9801ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
9811ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
982af67cecdSGreg Clayton         }
983*c9858e4dSGreg Clayton         else
984*c9858e4dSGreg Clayton         {
985*c9858e4dSGreg Clayton             if (log)
986*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
987*c9858e4dSGreg Clayton         }
9887fdf9ef1SGreg Clayton     }
989ceb6b139SCaroline Tice 
990ceb6b139SCaroline Tice     if (log)
9911ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
992ceb6b139SCaroline Tice 
993ceb6b139SCaroline Tice     return num_frames;
99430fdc8d8SChris Lattner }
99530fdc8d8SChris Lattner 
99630fdc8d8SChris Lattner SBFrame
99730fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
99830fdc8d8SChris Lattner {
9992d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1000ceb6b139SCaroline Tice 
100130fdc8d8SChris Lattner     SBFrame sb_frame;
1002b9556accSGreg Clayton     StackFrameSP frame_sp;
10037fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10041ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1005af67cecdSGreg Clayton     {
10067fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10077fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10087fdf9ef1SGreg Clayton         {
10091ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
10101ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1011b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1012af67cecdSGreg Clayton         }
1013*c9858e4dSGreg Clayton         else
1014*c9858e4dSGreg Clayton         {
1015*c9858e4dSGreg Clayton             if (log)
1016*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1017*c9858e4dSGreg Clayton         }
10187fdf9ef1SGreg Clayton     }
1019ceb6b139SCaroline Tice 
1020ceb6b139SCaroline Tice     if (log)
1021ceb6b139SCaroline Tice     {
1022481cef25SGreg Clayton         SBStream frame_desc_strm;
1023481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
10244838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
10251ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1026ceb6b139SCaroline Tice     }
1027ceb6b139SCaroline Tice 
102830fdc8d8SChris Lattner     return sb_frame;
102930fdc8d8SChris Lattner }
103030fdc8d8SChris Lattner 
1031f028a1fbSGreg Clayton lldb::SBFrame
1032f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1033f028a1fbSGreg Clayton {
1034f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1035f028a1fbSGreg Clayton 
1036f028a1fbSGreg Clayton     SBFrame sb_frame;
1037b9556accSGreg Clayton     StackFrameSP frame_sp;
10387fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1040af67cecdSGreg Clayton     {
10417fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10427fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10437fdf9ef1SGreg Clayton         {
10441ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
10451ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1046b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1047af67cecdSGreg Clayton         }
1048*c9858e4dSGreg Clayton         else
1049*c9858e4dSGreg Clayton         {
1050*c9858e4dSGreg Clayton             if (log)
1051*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1052*c9858e4dSGreg Clayton         }
10537fdf9ef1SGreg Clayton     }
1054f028a1fbSGreg Clayton 
1055f028a1fbSGreg Clayton     if (log)
1056f028a1fbSGreg Clayton     {
1057481cef25SGreg Clayton         SBStream frame_desc_strm;
1058481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1059f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
10601ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1061f028a1fbSGreg Clayton     }
1062f028a1fbSGreg Clayton 
1063f028a1fbSGreg Clayton     return sb_frame;
1064f028a1fbSGreg Clayton }
1065f028a1fbSGreg Clayton 
1066f028a1fbSGreg Clayton lldb::SBFrame
1067f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1068f028a1fbSGreg Clayton {
1069f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1070f028a1fbSGreg Clayton 
1071f028a1fbSGreg Clayton     SBFrame sb_frame;
1072b9556accSGreg Clayton     StackFrameSP frame_sp;
10737fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10741ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1075f028a1fbSGreg Clayton     {
10767fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10777fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10787fdf9ef1SGreg Clayton         {
10791ac04c30SGreg Clayton             Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
10801ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
10811ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1082f028a1fbSGreg Clayton             if (frame_sp)
1083f028a1fbSGreg Clayton             {
10841ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1085b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1086f028a1fbSGreg Clayton             }
1087f028a1fbSGreg Clayton         }
1088*c9858e4dSGreg Clayton         else
1089*c9858e4dSGreg Clayton         {
1090*c9858e4dSGreg Clayton             if (log)
1091*c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1092*c9858e4dSGreg Clayton         }
10937fdf9ef1SGreg Clayton     }
1094f028a1fbSGreg Clayton 
1095f028a1fbSGreg Clayton     if (log)
1096f028a1fbSGreg Clayton     {
1097481cef25SGreg Clayton         SBStream frame_desc_strm;
1098481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1099f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
11001ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1101f028a1fbSGreg Clayton     }
1102f028a1fbSGreg Clayton     return sb_frame;
1103f028a1fbSGreg Clayton }
1104f028a1fbSGreg Clayton 
1105f028a1fbSGreg Clayton 
110630fdc8d8SChris Lattner bool
110730fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
110830fdc8d8SChris Lattner {
11097fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
111030fdc8d8SChris Lattner }
111130fdc8d8SChris Lattner 
111230fdc8d8SChris Lattner bool
111330fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
111430fdc8d8SChris Lattner {
11157fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
111630fdc8d8SChris Lattner }
1117dde9cff3SCaroline Tice 
1118dde9cff3SCaroline Tice bool
1119ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1120ceb6b139SCaroline Tice {
1121da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1122da7bc7d0SGreg Clayton 
11237fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
11241ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1125ceb6b139SCaroline Tice     {
11261ac04c30SGreg Clayton         strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
1127ceb6b139SCaroline Tice     }
1128ceb6b139SCaroline Tice     else
1129da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1130ceb6b139SCaroline Tice 
1131ceb6b139SCaroline Tice     return true;
1132ceb6b139SCaroline Tice }
1133