130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1093a64300SDaniel Malea #include "lldb/lldb-python.h"
1193a64300SDaniel Malea 
124c5de699SEli Friedman #include "lldb/API/SBThread.h"
1330fdc8d8SChris Lattner 
1430fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
16dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
174e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
186611103cSGreg Clayton #include "lldb/Core/Debugger.h"
1930fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2030fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
216611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2230fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2430fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2530fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
26f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2730fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3330fdc8d8SChris Lattner 
3430fdc8d8SChris Lattner 
354c5de699SEli Friedman #include "lldb/API/SBAddress.h"
364c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
374f465cffSJim Ingham #include "lldb/API/SBEvent.h"
3873ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
394c5de699SEli Friedman #include "lldb/API/SBProcess.h"
4073ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4130fdc8d8SChris Lattner 
4230fdc8d8SChris Lattner using namespace lldb;
4330fdc8d8SChris Lattner using namespace lldb_private;
4430fdc8d8SChris Lattner 
454f465cffSJim Ingham const char *
464f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
474f465cffSJim Ingham {
484f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
494f465cffSJim Ingham }
504f465cffSJim Ingham 
51cfd1acedSGreg Clayton //----------------------------------------------------------------------
52cfd1acedSGreg Clayton // Constructors
53cfd1acedSGreg Clayton //----------------------------------------------------------------------
5430fdc8d8SChris Lattner SBThread::SBThread () :
557fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
5630fdc8d8SChris Lattner {
5730fdc8d8SChris Lattner }
5830fdc8d8SChris Lattner 
5930fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
607fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6130fdc8d8SChris Lattner {
6230fdc8d8SChris Lattner }
6330fdc8d8SChris Lattner 
6492ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
657fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
6630fdc8d8SChris Lattner {
677fdf9ef1SGreg Clayton 
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
7030fdc8d8SChris Lattner //----------------------------------------------------------------------
71cfd1acedSGreg Clayton // Assignment operator
72cfd1acedSGreg Clayton //----------------------------------------------------------------------
73cfd1acedSGreg Clayton 
74cfd1acedSGreg Clayton const lldb::SBThread &
75cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
76cfd1acedSGreg Clayton {
77cfd1acedSGreg Clayton     if (this != &rhs)
787fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
79cfd1acedSGreg Clayton     return *this;
80cfd1acedSGreg Clayton }
81cfd1acedSGreg Clayton 
82cfd1acedSGreg Clayton //----------------------------------------------------------------------
8330fdc8d8SChris Lattner // Destructor
8430fdc8d8SChris Lattner //----------------------------------------------------------------------
8530fdc8d8SChris Lattner SBThread::~SBThread()
8630fdc8d8SChris Lattner {
8730fdc8d8SChris Lattner }
8830fdc8d8SChris Lattner 
8930fdc8d8SChris Lattner bool
9030fdc8d8SChris Lattner SBThread::IsValid() const
9130fdc8d8SChris Lattner {
927fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
9330fdc8d8SChris Lattner }
9430fdc8d8SChris Lattner 
9548e42549SGreg Clayton void
9648e42549SGreg Clayton SBThread::Clear ()
9748e42549SGreg Clayton {
987fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
9948e42549SGreg Clayton }
10048e42549SGreg Clayton 
10148e42549SGreg Clayton 
10230fdc8d8SChris Lattner StopReason
10330fdc8d8SChris Lattner SBThread::GetStopReason()
10430fdc8d8SChris Lattner {
1052d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
106ceb6b139SCaroline Tice 
107ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1084fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1094fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1104fc6cb9cSJim Ingham 
1111ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
11230fdc8d8SChris Lattner     {
1137fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1147fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1157fdf9ef1SGreg Clayton         {
11697d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
11730fdc8d8SChris Lattner         }
118c9858e4dSGreg Clayton         else
119c9858e4dSGreg Clayton         {
120c9858e4dSGreg Clayton             if (log)
121c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
122c9858e4dSGreg Clayton         }
1237fdf9ef1SGreg Clayton     }
124ceb6b139SCaroline Tice 
125ceb6b139SCaroline Tice     if (log)
1261ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
127750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
128ceb6b139SCaroline Tice 
129ceb6b139SCaroline Tice     return reason;
13030fdc8d8SChris Lattner }
13130fdc8d8SChris Lattner 
13230fdc8d8SChris Lattner size_t
1334e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1344e78f606SGreg Clayton {
1354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1374fc6cb9cSJim Ingham 
1381ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1394e78f606SGreg Clayton     {
1407fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1417fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1427fdf9ef1SGreg Clayton         {
1431ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1444e78f606SGreg Clayton             if (stop_info_sp)
1454e78f606SGreg Clayton             {
1464e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1474e78f606SGreg Clayton                 switch (reason)
1484e78f606SGreg Clayton                 {
1494e78f606SGreg Clayton                 case eStopReasonInvalid:
1504e78f606SGreg Clayton                 case eStopReasonNone:
1514e78f606SGreg Clayton                 case eStopReasonTrace:
15290ba8115SGreg Clayton                 case eStopReasonExec:
1534e78f606SGreg Clayton                 case eStopReasonPlanComplete:
1544e78f606SGreg Clayton                     // There is no data for these stop reasons.
1554e78f606SGreg Clayton                     return 0;
1564e78f606SGreg Clayton 
1574e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1584e78f606SGreg Clayton                     {
1594e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1601ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1614e78f606SGreg Clayton                         if (bp_site_sp)
1624e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1634e78f606SGreg Clayton                         else
1644e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1654e78f606SGreg Clayton                     }
1664e78f606SGreg Clayton                     break;
1674e78f606SGreg Clayton 
1684e78f606SGreg Clayton                 case eStopReasonWatchpoint:
169290fa41bSJohnny Chen                     return 1;
1704e78f606SGreg Clayton 
1714e78f606SGreg Clayton                 case eStopReasonSignal:
1724e78f606SGreg Clayton                     return 1;
1734e78f606SGreg Clayton 
1744e78f606SGreg Clayton                 case eStopReasonException:
1754e78f606SGreg Clayton                     return 1;
1764e78f606SGreg Clayton                 }
1774e78f606SGreg Clayton             }
1784e78f606SGreg Clayton         }
179c9858e4dSGreg Clayton         else
180c9858e4dSGreg Clayton         {
181c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
182c9858e4dSGreg Clayton             if (log)
183c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
184c9858e4dSGreg Clayton         }
1857fdf9ef1SGreg Clayton     }
1864e78f606SGreg Clayton     return 0;
1874e78f606SGreg Clayton }
1884e78f606SGreg Clayton 
1894e78f606SGreg Clayton uint64_t
1904e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1914e78f606SGreg Clayton {
1924fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1934fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1944fc6cb9cSJim Ingham 
1951ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1964e78f606SGreg Clayton     {
1977fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1987fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1997fdf9ef1SGreg Clayton         {
2001ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2011ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2024e78f606SGreg Clayton             if (stop_info_sp)
2034e78f606SGreg Clayton             {
2044e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2054e78f606SGreg Clayton                 switch (reason)
2064e78f606SGreg Clayton                 {
2074e78f606SGreg Clayton                 case eStopReasonInvalid:
2084e78f606SGreg Clayton                 case eStopReasonNone:
2094e78f606SGreg Clayton                 case eStopReasonTrace:
21090ba8115SGreg Clayton                 case eStopReasonExec:
2114e78f606SGreg Clayton                 case eStopReasonPlanComplete:
2124e78f606SGreg Clayton                     // There is no data for these stop reasons.
2134e78f606SGreg Clayton                     return 0;
2144e78f606SGreg Clayton 
2154e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2164e78f606SGreg Clayton                     {
2174e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2181ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2194e78f606SGreg Clayton                         if (bp_site_sp)
2204e78f606SGreg Clayton                         {
2214e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2224e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2234e78f606SGreg Clayton                             if (bp_loc_sp)
2244e78f606SGreg Clayton                             {
2254e78f606SGreg Clayton                                 if (bp_index & 1)
2264e78f606SGreg Clayton                                 {
2274e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2284e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2294e78f606SGreg Clayton                                 }
2304e78f606SGreg Clayton                                 else
2314e78f606SGreg Clayton                                 {
2324e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2334e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2344e78f606SGreg Clayton                                 }
2354e78f606SGreg Clayton                             }
2364e78f606SGreg Clayton                         }
2374e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2384e78f606SGreg Clayton                     }
2394e78f606SGreg Clayton                     break;
2404e78f606SGreg Clayton 
2414e78f606SGreg Clayton                 case eStopReasonWatchpoint:
242290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2434e78f606SGreg Clayton 
2444e78f606SGreg Clayton                 case eStopReasonSignal:
2454e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2464e78f606SGreg Clayton 
2474e78f606SGreg Clayton                 case eStopReasonException:
2484e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2494e78f606SGreg Clayton                 }
2504e78f606SGreg Clayton             }
2514e78f606SGreg Clayton         }
252c9858e4dSGreg Clayton         else
253c9858e4dSGreg Clayton         {
254c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
255c9858e4dSGreg Clayton             if (log)
256c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
257c9858e4dSGreg Clayton         }
2587fdf9ef1SGreg Clayton     }
2594e78f606SGreg Clayton     return 0;
2604e78f606SGreg Clayton }
2614e78f606SGreg Clayton 
2624e78f606SGreg Clayton size_t
26330fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
26430fdc8d8SChris Lattner {
2652d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
266ceb6b139SCaroline Tice 
2674fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2684fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2694fc6cb9cSJim Ingham 
2701ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
27130fdc8d8SChris Lattner     {
2727fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2737fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2747fdf9ef1SGreg Clayton         {
2757fdf9ef1SGreg Clayton 
2761ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
277b15bfc75SJim Ingham             if (stop_info_sp)
27830fdc8d8SChris Lattner             {
279b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
28030fdc8d8SChris Lattner                 if (stop_desc)
28130fdc8d8SChris Lattner                 {
282ceb6b139SCaroline Tice                     if (log)
2834838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2841ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
28530fdc8d8SChris Lattner                     if (dst)
28630fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
28730fdc8d8SChris Lattner                     else
28830fdc8d8SChris Lattner                     {
28930fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
29030fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
29130fdc8d8SChris Lattner                     }
29230fdc8d8SChris Lattner                 }
29330fdc8d8SChris Lattner                 else
29430fdc8d8SChris Lattner                 {
29530fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
296b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
29730fdc8d8SChris Lattner                     {
29830fdc8d8SChris Lattner                     case eStopReasonTrace:
29930fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
30030fdc8d8SChris Lattner                         {
30130fdc8d8SChris Lattner                             static char trace_desc[] = "step";
30230fdc8d8SChris Lattner                             stop_desc = trace_desc;
30330fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
30430fdc8d8SChris Lattner                         }
30530fdc8d8SChris Lattner                         break;
30630fdc8d8SChris Lattner 
30730fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
30830fdc8d8SChris Lattner                         {
30930fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
31030fdc8d8SChris Lattner                             stop_desc = bp_desc;
31130fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
31230fdc8d8SChris Lattner                         }
31330fdc8d8SChris Lattner                         break;
31430fdc8d8SChris Lattner 
31530fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
31630fdc8d8SChris Lattner                         {
31730fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
31830fdc8d8SChris Lattner                             stop_desc = wp_desc;
31930fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
32030fdc8d8SChris Lattner                         }
32130fdc8d8SChris Lattner                         break;
32230fdc8d8SChris Lattner 
32330fdc8d8SChris Lattner                     case eStopReasonSignal:
32430fdc8d8SChris Lattner                         {
3251ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
32630fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
32730fdc8d8SChris Lattner                             {
32830fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
32930fdc8d8SChris Lattner                                 stop_desc = signal_desc;
33030fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
33130fdc8d8SChris Lattner                             }
33230fdc8d8SChris Lattner                         }
33330fdc8d8SChris Lattner                         break;
33430fdc8d8SChris Lattner 
33530fdc8d8SChris Lattner                     case eStopReasonException:
33630fdc8d8SChris Lattner                         {
33730fdc8d8SChris Lattner                             char exc_desc[] = "exception";
33830fdc8d8SChris Lattner                             stop_desc = exc_desc;
33930fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
34030fdc8d8SChris Lattner                         }
34130fdc8d8SChris Lattner                         break;
342c982c768SGreg Clayton 
34390ba8115SGreg Clayton                     case eStopReasonExec:
34490ba8115SGreg Clayton                         {
34590ba8115SGreg Clayton                             char exc_desc[] = "exec";
34690ba8115SGreg Clayton                             stop_desc = exc_desc;
34790ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
34890ba8115SGreg Clayton                         }
34990ba8115SGreg Clayton                         break;
35090ba8115SGreg Clayton 
351c982c768SGreg Clayton                     default:
352c982c768SGreg Clayton                         break;
35330fdc8d8SChris Lattner                     }
35430fdc8d8SChris Lattner 
35530fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
35630fdc8d8SChris Lattner                     {
357ceb6b139SCaroline Tice                         if (log)
35893aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3591ac04c30SGreg Clayton                                          exe_ctx.GetThreadPtr(), stop_desc);
360ceb6b139SCaroline Tice 
36130fdc8d8SChris Lattner                         if (dst)
36230fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
36330fdc8d8SChris Lattner 
36430fdc8d8SChris Lattner                         if (stop_desc_len == 0)
36530fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
36630fdc8d8SChris Lattner 
36730fdc8d8SChris Lattner                         return stop_desc_len;
36830fdc8d8SChris Lattner                     }
36930fdc8d8SChris Lattner                 }
37030fdc8d8SChris Lattner             }
37130fdc8d8SChris Lattner         }
372c9858e4dSGreg Clayton         else
373c9858e4dSGreg Clayton         {
374c9858e4dSGreg Clayton             LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
375c9858e4dSGreg Clayton             if (log)
376c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
377c9858e4dSGreg Clayton         }
3787fdf9ef1SGreg Clayton     }
37930fdc8d8SChris Lattner     if (dst)
38030fdc8d8SChris Lattner         *dst = 0;
38130fdc8d8SChris Lattner     return 0;
38230fdc8d8SChris Lattner }
38330fdc8d8SChris Lattner 
38473ca05a2SJim Ingham SBValue
38573ca05a2SJim Ingham SBThread::GetStopReturnValue ()
38673ca05a2SJim Ingham {
387c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
38873ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
3894fc6cb9cSJim Ingham     Mutex::Locker api_locker;
3904fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
3914fc6cb9cSJim Ingham 
3921ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
39373ca05a2SJim Ingham     {
3947fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
3957fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
3967fdf9ef1SGreg Clayton         {
3971ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
39873ca05a2SJim Ingham             if (stop_info_sp)
39973ca05a2SJim Ingham             {
40073ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
40173ca05a2SJim Ingham             }
40273ca05a2SJim Ingham         }
403c9858e4dSGreg Clayton         else
404c9858e4dSGreg Clayton         {
405c9858e4dSGreg Clayton             if (log)
406c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
407c9858e4dSGreg Clayton         }
4087fdf9ef1SGreg Clayton     }
40973ca05a2SJim Ingham 
41073ca05a2SJim Ingham     if (log)
4111ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
41273ca05a2SJim Ingham                                                                   return_valobj_sp.get()
41373ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
41473ca05a2SJim Ingham                                                                         : "<no return value>");
41573ca05a2SJim Ingham 
41673ca05a2SJim Ingham     return SBValue (return_valobj_sp);
41773ca05a2SJim Ingham }
41873ca05a2SJim Ingham 
41930fdc8d8SChris Lattner void
42030fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
42130fdc8d8SChris Lattner {
4227fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
42330fdc8d8SChris Lattner }
42430fdc8d8SChris Lattner 
42530fdc8d8SChris Lattner 
42630fdc8d8SChris Lattner lldb::tid_t
42730fdc8d8SChris Lattner SBThread::GetThreadID () const
42830fdc8d8SChris Lattner {
4297fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
43017a6ad05SGreg Clayton     if (thread_sp)
4311ac04c30SGreg Clayton         return thread_sp->GetID();
4321ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
43330fdc8d8SChris Lattner }
43430fdc8d8SChris Lattner 
43530fdc8d8SChris Lattner uint32_t
43630fdc8d8SChris Lattner SBThread::GetIndexID () const
43730fdc8d8SChris Lattner {
4387fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
43917a6ad05SGreg Clayton     if (thread_sp)
44017a6ad05SGreg Clayton         return thread_sp->GetIndexID();
44130fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
44230fdc8d8SChris Lattner }
4431ac04c30SGreg Clayton 
44430fdc8d8SChris Lattner const char *
44530fdc8d8SChris Lattner SBThread::GetName () const
44630fdc8d8SChris Lattner {
447c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4484838131bSGreg Clayton     const char *name = NULL;
4494fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4504fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4514fc6cb9cSJim Ingham 
4521ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
453af67cecdSGreg Clayton     {
4547fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4557fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4567fdf9ef1SGreg Clayton         {
4571ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
458af67cecdSGreg Clayton         }
459c9858e4dSGreg Clayton         else
460c9858e4dSGreg Clayton         {
461c9858e4dSGreg Clayton             if (log)
462c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
463c9858e4dSGreg Clayton         }
4647fdf9ef1SGreg Clayton     }
465ceb6b139SCaroline Tice 
466ceb6b139SCaroline Tice     if (log)
4671ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
468ceb6b139SCaroline Tice 
4694838131bSGreg Clayton     return name;
47030fdc8d8SChris Lattner }
47130fdc8d8SChris Lattner 
47230fdc8d8SChris Lattner const char *
47330fdc8d8SChris Lattner SBThread::GetQueueName () const
47430fdc8d8SChris Lattner {
4754838131bSGreg Clayton     const char *name = NULL;
4764fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4774fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4784fc6cb9cSJim Ingham 
479c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
481af67cecdSGreg Clayton     {
4827fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4837fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4847fdf9ef1SGreg Clayton         {
4851ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
486af67cecdSGreg Clayton         }
487c9858e4dSGreg Clayton         else
488c9858e4dSGreg Clayton         {
489c9858e4dSGreg Clayton             if (log)
490c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
491c9858e4dSGreg Clayton         }
4927fdf9ef1SGreg Clayton     }
493ceb6b139SCaroline Tice 
494ceb6b139SCaroline Tice     if (log)
4951ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
496ceb6b139SCaroline Tice 
4974838131bSGreg Clayton     return name;
49830fdc8d8SChris Lattner }
49930fdc8d8SChris Lattner 
50064e7ead1SJim Ingham SBError
50164e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
50264e7ead1SJim Ingham {
50364e7ead1SJim Ingham     SBError sb_error;
50464e7ead1SJim Ingham 
50564e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
50664e7ead1SJim Ingham     if (!process)
50764e7ead1SJim Ingham     {
50864e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
50964e7ead1SJim Ingham         return sb_error;
51064e7ead1SJim Ingham     }
51164e7ead1SJim Ingham 
51264e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
51364e7ead1SJim Ingham     if (!thread)
51464e7ead1SJim Ingham     {
51564e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
51664e7ead1SJim Ingham         return sb_error;
51764e7ead1SJim Ingham     }
51864e7ead1SJim Ingham 
51964e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
52064e7ead1SJim Ingham     // then a "continue" will resume the plan.
52164e7ead1SJim Ingham     if (new_plan != NULL)
52264e7ead1SJim Ingham     {
52364e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
52464e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
52564e7ead1SJim Ingham     }
52664e7ead1SJim Ingham 
52764e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
52864e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
52964e7ead1SJim Ingham     sb_error.ref() = process->Resume();
53064e7ead1SJim Ingham 
53164e7ead1SJim Ingham     if (sb_error.Success())
53264e7ead1SJim Ingham     {
53364e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
53464e7ead1SJim Ingham         // process to stop yet again!
53564e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
53664e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
53764e7ead1SJim Ingham     }
53864e7ead1SJim Ingham 
53964e7ead1SJim Ingham     return sb_error;
54064e7ead1SJim Ingham }
54130fdc8d8SChris Lattner 
54230fdc8d8SChris Lattner void
54330fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
54430fdc8d8SChris Lattner {
5452d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
546ceb6b139SCaroline Tice 
5474fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5484fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5494fc6cb9cSJim Ingham 
55017a6ad05SGreg Clayton 
551ceb6b139SCaroline Tice     if (log)
5521ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
553ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
554ceb6b139SCaroline Tice 
5551ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
55630fdc8d8SChris Lattner     {
5571ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5587ba6e991SJim Ingham         bool abort_other_plans = false;
5591ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
56064e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
56130fdc8d8SChris Lattner 
56230fdc8d8SChris Lattner         if (frame_sp)
56330fdc8d8SChris Lattner         {
56430fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
56530fdc8d8SChris Lattner             {
56630fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
567*c627682eSJim Ingham                 new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
56830fdc8d8SChris Lattner                                                                     sc.line_entry.range,
56930fdc8d8SChris Lattner                                                                     sc,
570*c627682eSJim Ingham                                                                     stop_other_threads);
57130fdc8d8SChris Lattner             }
57230fdc8d8SChris Lattner             else
57330fdc8d8SChris Lattner             {
57464e7ead1SJim Ingham                 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
57530fdc8d8SChris Lattner                                                                             abort_other_plans,
57630fdc8d8SChris Lattner                                                                             stop_other_threads);
57730fdc8d8SChris Lattner             }
57830fdc8d8SChris Lattner         }
57930fdc8d8SChris Lattner 
58064e7ead1SJim Ingham         // This returns an error, we should use it!
58164e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
58230fdc8d8SChris Lattner     }
58330fdc8d8SChris Lattner }
58430fdc8d8SChris Lattner 
58530fdc8d8SChris Lattner void
58630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
58730fdc8d8SChris Lattner {
588*c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
589*c627682eSJim Ingham }
590*c627682eSJim Ingham 
591*c627682eSJim Ingham void
592*c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
593*c627682eSJim Ingham {
5942d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
595ceb6b139SCaroline Tice 
5964fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5974fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
59817a6ad05SGreg Clayton 
59917a6ad05SGreg Clayton     if (log)
600*c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
601*c627682eSJim Ingham                      exe_ctx.GetThreadPtr(),
602*c627682eSJim Ingham                      target_name? target_name: "<NULL>",
60317a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
604*c627682eSJim Ingham 
6051ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
60630fdc8d8SChris Lattner     {
6077ba6e991SJim Ingham         bool abort_other_plans = false;
60830fdc8d8SChris Lattner 
6091ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6101ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
61164e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
61230fdc8d8SChris Lattner 
61330fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
61430fdc8d8SChris Lattner         {
615474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
61630fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
617*c627682eSJim Ingham             new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
61830fdc8d8SChris Lattner                                                               sc.line_entry.range,
61930fdc8d8SChris Lattner                                                               sc,
620*c627682eSJim Ingham                                                               target_name,
621474966a4SGreg Clayton                                                               stop_other_threads,
622474966a4SGreg Clayton                                                               avoid_code_without_debug_info);
62330fdc8d8SChris Lattner         }
62430fdc8d8SChris Lattner         else
62530fdc8d8SChris Lattner         {
62664e7ead1SJim Ingham             new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
62730fdc8d8SChris Lattner                                                                         abort_other_plans,
62830fdc8d8SChris Lattner                                                                         stop_other_threads);
62930fdc8d8SChris Lattner         }
63030fdc8d8SChris Lattner 
63164e7ead1SJim Ingham         // This returns an error, we should use it!
63264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
63330fdc8d8SChris Lattner     }
63430fdc8d8SChris Lattner }
63530fdc8d8SChris Lattner 
63630fdc8d8SChris Lattner void
63730fdc8d8SChris Lattner SBThread::StepOut ()
63830fdc8d8SChris Lattner {
6392d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
640ceb6b139SCaroline Tice 
6414fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6424fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6434fc6cb9cSJim Ingham 
644ceb6b139SCaroline Tice 
64517a6ad05SGreg Clayton     if (log)
6461ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
64717a6ad05SGreg Clayton 
6481ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
64930fdc8d8SChris Lattner     {
6507ba6e991SJim Ingham         bool abort_other_plans = false;
65194b09246SJim Ingham         bool stop_other_threads = false;
65230fdc8d8SChris Lattner 
6531ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6541ac04c30SGreg Clayton 
65564e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
656481cef25SGreg Clayton                                                                   NULL,
657481cef25SGreg Clayton                                                                   false,
658481cef25SGreg Clayton                                                                   stop_other_threads,
659481cef25SGreg Clayton                                                                   eVoteYes,
660481cef25SGreg Clayton                                                                   eVoteNoOpinion,
661481cef25SGreg Clayton                                                                   0);
662481cef25SGreg Clayton 
66364e7ead1SJim Ingham         // This returns an error, we should use it!
66464e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
665481cef25SGreg Clayton     }
666481cef25SGreg Clayton }
667481cef25SGreg Clayton 
668481cef25SGreg Clayton void
669481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
670481cef25SGreg Clayton {
671481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
672481cef25SGreg Clayton 
6734fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6744fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6754fc6cb9cSJim Ingham 
676b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
677481cef25SGreg Clayton     if (log)
678481cef25SGreg Clayton     {
679481cef25SGreg Clayton         SBStream frame_desc_strm;
680481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
6811ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
682481cef25SGreg Clayton     }
683481cef25SGreg Clayton 
6841ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
685481cef25SGreg Clayton     {
6867ba6e991SJim Ingham         bool abort_other_plans = false;
68794b09246SJim Ingham         bool stop_other_threads = false;
6881ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
689481cef25SGreg Clayton 
69064e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
691481cef25SGreg Clayton                                                                     NULL,
692481cef25SGreg Clayton                                                                     false,
693481cef25SGreg Clayton                                                                     stop_other_threads,
694481cef25SGreg Clayton                                                                     eVoteYes,
695481cef25SGreg Clayton                                                                     eVoteNoOpinion,
696b9556accSGreg Clayton                                                                     frame_sp->GetFrameIndex());
69730fdc8d8SChris Lattner 
69864e7ead1SJim Ingham         // This returns an error, we should use it!
69964e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
70030fdc8d8SChris Lattner     }
70130fdc8d8SChris Lattner }
70230fdc8d8SChris Lattner 
70330fdc8d8SChris Lattner void
70430fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
70530fdc8d8SChris Lattner {
7062d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
707ceb6b139SCaroline Tice 
7084fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7094fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7104fc6cb9cSJim Ingham 
7111ac04c30SGreg Clayton 
712ceb6b139SCaroline Tice 
71317a6ad05SGreg Clayton     if (log)
7141ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
71517a6ad05SGreg Clayton 
7161ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
71730fdc8d8SChris Lattner     {
7181ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
71964e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
72064e7ead1SJim Ingham 
72164e7ead1SJim Ingham         // This returns an error, we should use it!
72264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
72330fdc8d8SChris Lattner     }
72430fdc8d8SChris Lattner }
72530fdc8d8SChris Lattner 
72630fdc8d8SChris Lattner void
72730fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
72830fdc8d8SChris Lattner {
7292d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
730ceb6b139SCaroline Tice 
7314fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7324fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7334fc6cb9cSJim Ingham 
734ceb6b139SCaroline Tice 
73517a6ad05SGreg Clayton     if (log)
736d01b2953SDaniel Malea         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
73717a6ad05SGreg Clayton 
7381ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
73930fdc8d8SChris Lattner     {
7407ba6e991SJim Ingham         bool abort_other_plans = false;
74130fdc8d8SChris Lattner         bool stop_other_threads = true;
74230fdc8d8SChris Lattner 
743e72dfb32SGreg Clayton         Address target_addr (addr);
74430fdc8d8SChris Lattner 
7451ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7461ac04c30SGreg Clayton 
74764e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
74864e7ead1SJim Ingham 
74964e7ead1SJim Ingham         // This returns an error, we should use it!
75064e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
75130fdc8d8SChris Lattner     }
75230fdc8d8SChris Lattner }
75330fdc8d8SChris Lattner 
754481cef25SGreg Clayton SBError
755481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
756481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
757481cef25SGreg Clayton                          uint32_t line)
758481cef25SGreg Clayton {
759481cef25SGreg Clayton     SBError sb_error;
760481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
761481cef25SGreg Clayton     char path[PATH_MAX];
762481cef25SGreg Clayton 
7634fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7644fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7654fc6cb9cSJim Ingham 
766b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
76717a6ad05SGreg Clayton 
768481cef25SGreg Clayton     if (log)
769481cef25SGreg Clayton     {
770481cef25SGreg Clayton         SBStream frame_desc_strm;
771481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
772481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
773481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
7741ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
775b9556accSGreg Clayton                      frame_sp.get(),
776481cef25SGreg Clayton                      frame_desc_strm.GetData(),
777481cef25SGreg Clayton                      path, line);
778481cef25SGreg Clayton     }
779481cef25SGreg Clayton 
7801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
781481cef25SGreg Clayton     {
7821ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
7831ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
784481cef25SGreg Clayton 
785481cef25SGreg Clayton         if (line == 0)
786481cef25SGreg Clayton         {
787481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
788481cef25SGreg Clayton             return sb_error;
789481cef25SGreg Clayton         }
790481cef25SGreg Clayton 
791b9556accSGreg Clayton         if (!frame_sp)
792481cef25SGreg Clayton         {
7931ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
794481cef25SGreg Clayton             if (!frame_sp)
7951ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
796481cef25SGreg Clayton         }
797481cef25SGreg Clayton 
798481cef25SGreg Clayton         SymbolContext frame_sc;
799481cef25SGreg Clayton         if (!frame_sp)
800481cef25SGreg Clayton         {
801481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
802481cef25SGreg Clayton             return sb_error;
803481cef25SGreg Clayton         }
804481cef25SGreg Clayton 
805481cef25SGreg Clayton         // If we have a frame, get its line
806481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
807481cef25SGreg Clayton                                                eSymbolContextFunction  |
808481cef25SGreg Clayton                                                eSymbolContextLineEntry |
809481cef25SGreg Clayton                                                eSymbolContextSymbol    );
810481cef25SGreg Clayton 
811481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
812481cef25SGreg Clayton         {
813481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
814481cef25SGreg Clayton             return sb_error;
815481cef25SGreg Clayton         }
816481cef25SGreg Clayton 
817481cef25SGreg Clayton         FileSpec step_file_spec;
818481cef25SGreg Clayton         if (sb_file_spec.IsValid())
819481cef25SGreg Clayton         {
820481cef25SGreg Clayton             // The file spec passed in was valid, so use it
821481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
822481cef25SGreg Clayton         }
823481cef25SGreg Clayton         else
824481cef25SGreg Clayton         {
825481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
826481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
827481cef25SGreg Clayton             else
828481cef25SGreg Clayton             {
829481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
830481cef25SGreg Clayton                 return sb_error;
831481cef25SGreg Clayton             }
832481cef25SGreg Clayton         }
833481cef25SGreg Clayton 
8349b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
8359b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
8369b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
8379b70ddb3SJim Ingham         // error message.
8389b70ddb3SJim Ingham 
8399b70ddb3SJim Ingham         bool all_in_function = true;
8409b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
8419b70ddb3SJim Ingham 
842481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
8437ba6e991SJim Ingham         const bool abort_other_plans = false;
844c02e3344SJim Ingham         const bool stop_other_threads = false;
845481cef25SGreg Clayton         const bool check_inlines = true;
846481cef25SGreg Clayton         const bool exact = false;
847481cef25SGreg Clayton 
848481cef25SGreg Clayton         SymbolContextList sc_list;
8499b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
8509b70ddb3SJim Ingham                                                                                line,
8519b70ddb3SJim Ingham                                                                                check_inlines,
8529b70ddb3SJim Ingham                                                                                exact,
8539b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
8549b70ddb3SJim Ingham                                                                                sc_list);
855481cef25SGreg Clayton         if (num_matches > 0)
856481cef25SGreg Clayton         {
857481cef25SGreg Clayton             SymbolContext sc;
858481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
859481cef25SGreg Clayton             {
860481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
861481cef25SGreg Clayton                 {
8629b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
863481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
864481cef25SGreg Clayton                     {
8659b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
866481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
8679b70ddb3SJim Ingham                         else
8689b70ddb3SJim Ingham                             all_in_function = false;
869481cef25SGreg Clayton                     }
870481cef25SGreg Clayton                 }
871481cef25SGreg Clayton             }
872481cef25SGreg Clayton         }
873481cef25SGreg Clayton 
874481cef25SGreg Clayton         if (step_over_until_addrs.empty())
875481cef25SGreg Clayton         {
8769b70ddb3SJim Ingham             if (all_in_function)
8779b70ddb3SJim Ingham             {
878481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
879fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
880481cef25SGreg Clayton             }
881481cef25SGreg Clayton             else
88286edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
8839b70ddb3SJim Ingham         }
8849b70ddb3SJim Ingham         else
885481cef25SGreg Clayton         {
88664e7ead1SJim Ingham             ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
887481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
888481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
889481cef25SGreg Clayton                                                                         stop_other_threads,
890481cef25SGreg Clayton                                                                         frame_sp->GetFrameIndex());
891481cef25SGreg Clayton 
89264e7ead1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan);
893481cef25SGreg Clayton         }
894481cef25SGreg Clayton     }
895481cef25SGreg Clayton     else
896481cef25SGreg Clayton     {
897481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
898481cef25SGreg Clayton     }
899481cef25SGreg Clayton     return sb_error;
900481cef25SGreg Clayton }
901481cef25SGreg Clayton 
9024413758cSJim Ingham SBError
903cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
9044413758cSJim Ingham {
9054413758cSJim Ingham     SBError sb_error;
9064413758cSJim Ingham 
9074413758cSJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9084413758cSJim Ingham 
9094413758cSJim Ingham     Mutex::Locker api_locker;
9104413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9114413758cSJim Ingham 
9124413758cSJim Ingham 
9134413758cSJim Ingham     if (log)
914cb640dd8SJim Ingham         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
9154413758cSJim Ingham 
9164413758cSJim Ingham     if (exe_ctx.HasThreadScope())
9174413758cSJim Ingham     {
9184413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
919cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9204413758cSJim Ingham     }
9214413758cSJim Ingham 
9224413758cSJim Ingham     return sb_error;
9234413758cSJim Ingham }
9244413758cSJim Ingham 
925481cef25SGreg Clayton 
926722a0cdcSGreg Clayton bool
927722a0cdcSGreg Clayton SBThread::Suspend()
928722a0cdcSGreg Clayton {
929c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9307fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
931c9858e4dSGreg Clayton     bool result = false;
9321ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
933722a0cdcSGreg Clayton     {
934c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
935c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
936c9858e4dSGreg Clayton         {
9371ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
938c9858e4dSGreg Clayton             result = true;
939722a0cdcSGreg Clayton         }
940c9858e4dSGreg Clayton         else
941c9858e4dSGreg Clayton         {
942c9858e4dSGreg Clayton             if (log)
943c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
944c9858e4dSGreg Clayton         }
945c9858e4dSGreg Clayton     }
946c9858e4dSGreg Clayton     if (log)
947c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
948c9858e4dSGreg Clayton     return result;
949722a0cdcSGreg Clayton }
950722a0cdcSGreg Clayton 
951722a0cdcSGreg Clayton bool
952722a0cdcSGreg Clayton SBThread::Resume ()
953722a0cdcSGreg Clayton {
954c9858e4dSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9557fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
956c9858e4dSGreg Clayton     bool result = false;
9571ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
958722a0cdcSGreg Clayton     {
959c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
960c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
961c9858e4dSGreg Clayton         {
9621ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
963c9858e4dSGreg Clayton             result = true;
964722a0cdcSGreg Clayton         }
965c9858e4dSGreg Clayton         else
966c9858e4dSGreg Clayton         {
967c9858e4dSGreg Clayton             if (log)
968c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
969c9858e4dSGreg Clayton         }
970c9858e4dSGreg Clayton     }
971c9858e4dSGreg Clayton     if (log)
972c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
973c9858e4dSGreg Clayton     return result;
974722a0cdcSGreg Clayton }
975722a0cdcSGreg Clayton 
976722a0cdcSGreg Clayton bool
977722a0cdcSGreg Clayton SBThread::IsSuspended()
978722a0cdcSGreg Clayton {
9797fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
9811ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
982722a0cdcSGreg Clayton     return false;
983722a0cdcSGreg Clayton }
984722a0cdcSGreg Clayton 
98530fdc8d8SChris Lattner SBProcess
98630fdc8d8SChris Lattner SBThread::GetProcess ()
98730fdc8d8SChris Lattner {
988ceb6b139SCaroline Tice 
989b9556accSGreg Clayton     SBProcess sb_process;
990b9556accSGreg Clayton     ProcessSP process_sp;
9917fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9921ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
99330fdc8d8SChris Lattner     {
99430fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
9951ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
99630fdc8d8SChris Lattner     }
997ceb6b139SCaroline Tice 
9982d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
999ceb6b139SCaroline Tice     if (log)
1000ceb6b139SCaroline Tice     {
1001481cef25SGreg Clayton         SBStream frame_desc_strm;
1002b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
10031ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
1004b9556accSGreg Clayton                      process_sp.get(), frame_desc_strm.GetData());
1005ceb6b139SCaroline Tice     }
1006ceb6b139SCaroline Tice 
1007b9556accSGreg Clayton     return sb_process;
100830fdc8d8SChris Lattner }
100930fdc8d8SChris Lattner 
101030fdc8d8SChris Lattner uint32_t
101130fdc8d8SChris Lattner SBThread::GetNumFrames ()
101230fdc8d8SChris Lattner {
10132d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1014ceb6b139SCaroline Tice 
1015ceb6b139SCaroline Tice     uint32_t num_frames = 0;
10164fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10174fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10184fc6cb9cSJim Ingham 
10191ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1020af67cecdSGreg Clayton     {
10217fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10227fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10237fdf9ef1SGreg Clayton         {
10241ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1025af67cecdSGreg Clayton         }
1026c9858e4dSGreg Clayton         else
1027c9858e4dSGreg Clayton         {
1028c9858e4dSGreg Clayton             if (log)
1029c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1030c9858e4dSGreg Clayton         }
10317fdf9ef1SGreg Clayton     }
1032ceb6b139SCaroline Tice 
1033ceb6b139SCaroline Tice     if (log)
10341ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1035ceb6b139SCaroline Tice 
1036ceb6b139SCaroline Tice     return num_frames;
103730fdc8d8SChris Lattner }
103830fdc8d8SChris Lattner 
103930fdc8d8SChris Lattner SBFrame
104030fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
104130fdc8d8SChris Lattner {
10422d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1043ceb6b139SCaroline Tice 
104430fdc8d8SChris Lattner     SBFrame sb_frame;
1045b9556accSGreg Clayton     StackFrameSP frame_sp;
10464fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10474fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10484fc6cb9cSJim Ingham 
10491ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1050af67cecdSGreg Clayton     {
10517fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10527fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10537fdf9ef1SGreg Clayton         {
10541ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1055b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1056af67cecdSGreg Clayton         }
1057c9858e4dSGreg Clayton         else
1058c9858e4dSGreg Clayton         {
1059c9858e4dSGreg Clayton             if (log)
1060c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1061c9858e4dSGreg Clayton         }
10627fdf9ef1SGreg Clayton     }
1063ceb6b139SCaroline Tice 
1064ceb6b139SCaroline Tice     if (log)
1065ceb6b139SCaroline Tice     {
1066481cef25SGreg Clayton         SBStream frame_desc_strm;
1067481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
10684838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
10691ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1070ceb6b139SCaroline Tice     }
1071ceb6b139SCaroline Tice 
107230fdc8d8SChris Lattner     return sb_frame;
107330fdc8d8SChris Lattner }
107430fdc8d8SChris Lattner 
1075f028a1fbSGreg Clayton lldb::SBFrame
1076f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1077f028a1fbSGreg Clayton {
1078f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1079f028a1fbSGreg Clayton 
1080f028a1fbSGreg Clayton     SBFrame sb_frame;
1081b9556accSGreg Clayton     StackFrameSP frame_sp;
10824fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10834fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10844fc6cb9cSJim Ingham 
10851ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1086af67cecdSGreg Clayton     {
10877fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10887fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10897fdf9ef1SGreg Clayton         {
10901ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1091b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1092af67cecdSGreg Clayton         }
1093c9858e4dSGreg Clayton         else
1094c9858e4dSGreg Clayton         {
1095c9858e4dSGreg Clayton             if (log)
1096c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1097c9858e4dSGreg Clayton         }
10987fdf9ef1SGreg Clayton     }
1099f028a1fbSGreg Clayton 
1100f028a1fbSGreg Clayton     if (log)
1101f028a1fbSGreg Clayton     {
1102481cef25SGreg Clayton         SBStream frame_desc_strm;
1103481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1104f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
11051ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1106f028a1fbSGreg Clayton     }
1107f028a1fbSGreg Clayton 
1108f028a1fbSGreg Clayton     return sb_frame;
1109f028a1fbSGreg Clayton }
1110f028a1fbSGreg Clayton 
1111f028a1fbSGreg Clayton lldb::SBFrame
1112f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1113f028a1fbSGreg Clayton {
1114f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1115f028a1fbSGreg Clayton 
1116f028a1fbSGreg Clayton     SBFrame sb_frame;
1117b9556accSGreg Clayton     StackFrameSP frame_sp;
11184fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11194fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11204fc6cb9cSJim Ingham 
11211ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1122f028a1fbSGreg Clayton     {
11237fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11247fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11257fdf9ef1SGreg Clayton         {
11261ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
11271ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1128f028a1fbSGreg Clayton             if (frame_sp)
1129f028a1fbSGreg Clayton             {
11301ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1131b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1132f028a1fbSGreg Clayton             }
1133f028a1fbSGreg Clayton         }
1134c9858e4dSGreg Clayton         else
1135c9858e4dSGreg Clayton         {
1136c9858e4dSGreg Clayton             if (log)
1137c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1138c9858e4dSGreg Clayton         }
11397fdf9ef1SGreg Clayton     }
1140f028a1fbSGreg Clayton 
1141f028a1fbSGreg Clayton     if (log)
1142f028a1fbSGreg Clayton     {
1143481cef25SGreg Clayton         SBStream frame_desc_strm;
1144481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1145f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
11461ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1147f028a1fbSGreg Clayton     }
1148f028a1fbSGreg Clayton     return sb_frame;
1149f028a1fbSGreg Clayton }
1150f028a1fbSGreg Clayton 
11514f465cffSJim Ingham bool
11524f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
11534f465cffSJim Ingham {
11544f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
11554f465cffSJim Ingham }
11564f465cffSJim Ingham 
11574f465cffSJim Ingham SBFrame
11584f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
11594f465cffSJim Ingham {
11604f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
11614f465cffSJim Ingham 
11624f465cffSJim Ingham }
11634f465cffSJim Ingham 
11644f465cffSJim Ingham SBThread
11654f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
11664f465cffSJim Ingham {
11674f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
11684f465cffSJim Ingham }
1169f028a1fbSGreg Clayton 
117030fdc8d8SChris Lattner bool
117130fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
117230fdc8d8SChris Lattner {
11737fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
117430fdc8d8SChris Lattner }
117530fdc8d8SChris Lattner 
117630fdc8d8SChris Lattner bool
117730fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
117830fdc8d8SChris Lattner {
11797fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
118030fdc8d8SChris Lattner }
1181dde9cff3SCaroline Tice 
1182dde9cff3SCaroline Tice bool
11834f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
11844f465cffSJim Ingham {
11854f465cffSJim Ingham     Stream &strm = status.ref();
11864f465cffSJim Ingham 
11874f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
11884f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
11894f465cffSJim Ingham     {
11904f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
11914f465cffSJim Ingham     }
11924f465cffSJim Ingham     else
11934f465cffSJim Ingham         strm.PutCString ("No status");
11944f465cffSJim Ingham 
11954f465cffSJim Ingham     return true;
11964f465cffSJim Ingham }
11974f465cffSJim Ingham 
11984f465cffSJim Ingham bool
1199ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1200ceb6b139SCaroline Tice {
1201da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1202da7bc7d0SGreg Clayton 
12037fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
12041ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1205ceb6b139SCaroline Tice     {
1206d01b2953SDaniel Malea         strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1207ceb6b139SCaroline Tice     }
1208ceb6b139SCaroline Tice     else
1209da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1210ceb6b139SCaroline Tice 
1211ceb6b139SCaroline Tice     return true;
1212ceb6b139SCaroline Tice }
1213