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"
19*a75418dbSAndrew Kaylor #include "lldb/Core/State.h"
2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
2130fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2430fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2530fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2630fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
27f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2830fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner 
364c5de699SEli Friedman #include "lldb/API/SBAddress.h"
374c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
384f465cffSJim Ingham #include "lldb/API/SBEvent.h"
3973ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
404c5de699SEli Friedman #include "lldb/API/SBProcess.h"
4173ca05a2SJim Ingham #include "lldb/API/SBValue.h"
4230fdc8d8SChris Lattner 
4330fdc8d8SChris Lattner using namespace lldb;
4430fdc8d8SChris Lattner using namespace lldb_private;
4530fdc8d8SChris Lattner 
464f465cffSJim Ingham const char *
474f465cffSJim Ingham SBThread::GetBroadcasterClassName ()
484f465cffSJim Ingham {
494f465cffSJim Ingham     return Thread::GetStaticBroadcasterClass().AsCString();
504f465cffSJim Ingham }
514f465cffSJim Ingham 
52cfd1acedSGreg Clayton //----------------------------------------------------------------------
53cfd1acedSGreg Clayton // Constructors
54cfd1acedSGreg Clayton //----------------------------------------------------------------------
5530fdc8d8SChris Lattner SBThread::SBThread () :
567fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef())
5730fdc8d8SChris Lattner {
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
617fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
6230fdc8d8SChris Lattner {
6330fdc8d8SChris Lattner }
6430fdc8d8SChris Lattner 
6592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
667fdf9ef1SGreg Clayton     m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
6730fdc8d8SChris Lattner {
687fdf9ef1SGreg Clayton 
6930fdc8d8SChris Lattner }
7030fdc8d8SChris Lattner 
7130fdc8d8SChris Lattner //----------------------------------------------------------------------
72cfd1acedSGreg Clayton // Assignment operator
73cfd1acedSGreg Clayton //----------------------------------------------------------------------
74cfd1acedSGreg Clayton 
75cfd1acedSGreg Clayton const lldb::SBThread &
76cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
77cfd1acedSGreg Clayton {
78cfd1acedSGreg Clayton     if (this != &rhs)
797fdf9ef1SGreg Clayton         *m_opaque_sp = *rhs.m_opaque_sp;
80cfd1acedSGreg Clayton     return *this;
81cfd1acedSGreg Clayton }
82cfd1acedSGreg Clayton 
83cfd1acedSGreg Clayton //----------------------------------------------------------------------
8430fdc8d8SChris Lattner // Destructor
8530fdc8d8SChris Lattner //----------------------------------------------------------------------
8630fdc8d8SChris Lattner SBThread::~SBThread()
8730fdc8d8SChris Lattner {
8830fdc8d8SChris Lattner }
8930fdc8d8SChris Lattner 
9030fdc8d8SChris Lattner bool
9130fdc8d8SChris Lattner SBThread::IsValid() const
9230fdc8d8SChris Lattner {
937fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != NULL;
9430fdc8d8SChris Lattner }
9530fdc8d8SChris Lattner 
9648e42549SGreg Clayton void
9748e42549SGreg Clayton SBThread::Clear ()
9848e42549SGreg Clayton {
997fdf9ef1SGreg Clayton     m_opaque_sp->Clear();
10048e42549SGreg Clayton }
10148e42549SGreg Clayton 
10248e42549SGreg Clayton 
10330fdc8d8SChris Lattner StopReason
10430fdc8d8SChris Lattner SBThread::GetStopReason()
10530fdc8d8SChris Lattner {
1065160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
107ceb6b139SCaroline Tice 
108ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
1094fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1104fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1114fc6cb9cSJim Ingham 
1121ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
11330fdc8d8SChris Lattner     {
1147fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1157fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1167fdf9ef1SGreg Clayton         {
11797d5cf05SGreg Clayton             return exe_ctx.GetThreadPtr()->GetStopReason();
11830fdc8d8SChris Lattner         }
119c9858e4dSGreg Clayton         else
120c9858e4dSGreg Clayton         {
121c9858e4dSGreg Clayton             if (log)
122c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
123c9858e4dSGreg Clayton         }
1247fdf9ef1SGreg Clayton     }
125ceb6b139SCaroline Tice 
126ceb6b139SCaroline Tice     if (log)
1271ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
128750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
129ceb6b139SCaroline Tice 
130ceb6b139SCaroline Tice     return reason;
13130fdc8d8SChris Lattner }
13230fdc8d8SChris Lattner 
13330fdc8d8SChris Lattner size_t
1344e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1354e78f606SGreg Clayton {
1364fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1374fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1384fc6cb9cSJim Ingham 
1391ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1404e78f606SGreg Clayton     {
1417fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
1427fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1437fdf9ef1SGreg Clayton         {
1441ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1454e78f606SGreg Clayton             if (stop_info_sp)
1464e78f606SGreg Clayton             {
1474e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
1484e78f606SGreg Clayton                 switch (reason)
1494e78f606SGreg Clayton                 {
1504e78f606SGreg Clayton                 case eStopReasonInvalid:
1514e78f606SGreg Clayton                 case eStopReasonNone:
1524e78f606SGreg Clayton                 case eStopReasonTrace:
15390ba8115SGreg Clayton                 case eStopReasonExec:
1544e78f606SGreg Clayton                 case eStopReasonPlanComplete:
155f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
1564e78f606SGreg Clayton                     // There is no data for these stop reasons.
1574e78f606SGreg Clayton                     return 0;
1584e78f606SGreg Clayton 
1594e78f606SGreg Clayton                 case eStopReasonBreakpoint:
1604e78f606SGreg Clayton                     {
1614e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
1621ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1634e78f606SGreg Clayton                         if (bp_site_sp)
1644e78f606SGreg Clayton                             return bp_site_sp->GetNumberOfOwners () * 2;
1654e78f606SGreg Clayton                         else
1664e78f606SGreg Clayton                             return 0; // Breakpoint must have cleared itself...
1674e78f606SGreg Clayton                     }
1684e78f606SGreg Clayton                     break;
1694e78f606SGreg Clayton 
1704e78f606SGreg Clayton                 case eStopReasonWatchpoint:
171290fa41bSJohnny Chen                     return 1;
1724e78f606SGreg Clayton 
1734e78f606SGreg Clayton                 case eStopReasonSignal:
1744e78f606SGreg Clayton                     return 1;
1754e78f606SGreg Clayton 
1764e78f606SGreg Clayton                 case eStopReasonException:
1774e78f606SGreg Clayton                     return 1;
1784e78f606SGreg Clayton                 }
1794e78f606SGreg Clayton             }
1804e78f606SGreg Clayton         }
181c9858e4dSGreg Clayton         else
182c9858e4dSGreg Clayton         {
1835160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
184c9858e4dSGreg Clayton             if (log)
185c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
186c9858e4dSGreg Clayton         }
1877fdf9ef1SGreg Clayton     }
1884e78f606SGreg Clayton     return 0;
1894e78f606SGreg Clayton }
1904e78f606SGreg Clayton 
1914e78f606SGreg Clayton uint64_t
1924e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1934e78f606SGreg Clayton {
1944fc6cb9cSJim Ingham     Mutex::Locker api_locker;
1954fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1964fc6cb9cSJim Ingham 
1971ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1984e78f606SGreg Clayton     {
1997fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2007fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2017fdf9ef1SGreg Clayton         {
2021ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
2031ac04c30SGreg Clayton             StopInfoSP stop_info_sp = thread->GetStopInfo ();
2044e78f606SGreg Clayton             if (stop_info_sp)
2054e78f606SGreg Clayton             {
2064e78f606SGreg Clayton                 StopReason reason = stop_info_sp->GetStopReason();
2074e78f606SGreg Clayton                 switch (reason)
2084e78f606SGreg Clayton                 {
2094e78f606SGreg Clayton                 case eStopReasonInvalid:
2104e78f606SGreg Clayton                 case eStopReasonNone:
2114e78f606SGreg Clayton                 case eStopReasonTrace:
21290ba8115SGreg Clayton                 case eStopReasonExec:
2134e78f606SGreg Clayton                 case eStopReasonPlanComplete:
214f85defaeSAndrew Kaylor                 case eStopReasonThreadExiting:
2154e78f606SGreg Clayton                     // There is no data for these stop reasons.
2164e78f606SGreg Clayton                     return 0;
2174e78f606SGreg Clayton 
2184e78f606SGreg Clayton                 case eStopReasonBreakpoint:
2194e78f606SGreg Clayton                     {
2204e78f606SGreg Clayton                         break_id_t site_id = stop_info_sp->GetValue();
2211ac04c30SGreg Clayton                         lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
2224e78f606SGreg Clayton                         if (bp_site_sp)
2234e78f606SGreg Clayton                         {
2244e78f606SGreg Clayton                             uint32_t bp_index = idx / 2;
2254e78f606SGreg Clayton                             BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
2264e78f606SGreg Clayton                             if (bp_loc_sp)
2274e78f606SGreg Clayton                             {
2284e78f606SGreg Clayton                                 if (bp_index & 1)
2294e78f606SGreg Clayton                                 {
2304e78f606SGreg Clayton                                     // Odd idx, return the breakpoint location ID
2314e78f606SGreg Clayton                                     return bp_loc_sp->GetID();
2324e78f606SGreg Clayton                                 }
2334e78f606SGreg Clayton                                 else
2344e78f606SGreg Clayton                                 {
2354e78f606SGreg Clayton                                     // Even idx, return the breakpoint ID
2364e78f606SGreg Clayton                                     return bp_loc_sp->GetBreakpoint().GetID();
2374e78f606SGreg Clayton                                 }
2384e78f606SGreg Clayton                             }
2394e78f606SGreg Clayton                         }
2404e78f606SGreg Clayton                         return LLDB_INVALID_BREAK_ID;
2414e78f606SGreg Clayton                     }
2424e78f606SGreg Clayton                     break;
2434e78f606SGreg Clayton 
2444e78f606SGreg Clayton                 case eStopReasonWatchpoint:
245290fa41bSJohnny Chen                     return stop_info_sp->GetValue();
2464e78f606SGreg Clayton 
2474e78f606SGreg Clayton                 case eStopReasonSignal:
2484e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2494e78f606SGreg Clayton 
2504e78f606SGreg Clayton                 case eStopReasonException:
2514e78f606SGreg Clayton                     return stop_info_sp->GetValue();
2524e78f606SGreg Clayton                 }
2534e78f606SGreg Clayton             }
2544e78f606SGreg Clayton         }
255c9858e4dSGreg Clayton         else
256c9858e4dSGreg Clayton         {
2575160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
258c9858e4dSGreg Clayton             if (log)
259c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
260c9858e4dSGreg Clayton         }
2617fdf9ef1SGreg Clayton     }
2624e78f606SGreg Clayton     return 0;
2634e78f606SGreg Clayton }
2644e78f606SGreg Clayton 
2654e78f606SGreg Clayton size_t
26630fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
26730fdc8d8SChris Lattner {
2685160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
269ceb6b139SCaroline Tice 
2704fc6cb9cSJim Ingham     Mutex::Locker api_locker;
2714fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
2724fc6cb9cSJim Ingham 
2731ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
27430fdc8d8SChris Lattner     {
2757fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
2767fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
2777fdf9ef1SGreg Clayton         {
2787fdf9ef1SGreg Clayton 
2791ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
280b15bfc75SJim Ingham             if (stop_info_sp)
28130fdc8d8SChris Lattner             {
282b15bfc75SJim Ingham                 const char *stop_desc = stop_info_sp->GetDescription();
28330fdc8d8SChris Lattner                 if (stop_desc)
28430fdc8d8SChris Lattner                 {
285ceb6b139SCaroline Tice                     if (log)
2864838131bSGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2871ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
28830fdc8d8SChris Lattner                     if (dst)
28930fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc);
29030fdc8d8SChris Lattner                     else
29130fdc8d8SChris Lattner                     {
29230fdc8d8SChris Lattner                         // NULL dst passed in, return the length needed to contain the description
29330fdc8d8SChris Lattner                         return ::strlen (stop_desc) + 1; // Include the NULL byte for size
29430fdc8d8SChris Lattner                     }
29530fdc8d8SChris Lattner                 }
29630fdc8d8SChris Lattner                 else
29730fdc8d8SChris Lattner                 {
29830fdc8d8SChris Lattner                     size_t stop_desc_len = 0;
299b15bfc75SJim Ingham                     switch (stop_info_sp->GetStopReason())
30030fdc8d8SChris Lattner                     {
30130fdc8d8SChris Lattner                     case eStopReasonTrace:
30230fdc8d8SChris Lattner                     case eStopReasonPlanComplete:
30330fdc8d8SChris Lattner                         {
30430fdc8d8SChris Lattner                             static char trace_desc[] = "step";
30530fdc8d8SChris Lattner                             stop_desc = trace_desc;
30630fdc8d8SChris Lattner                             stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
30730fdc8d8SChris Lattner                         }
30830fdc8d8SChris Lattner                         break;
30930fdc8d8SChris Lattner 
31030fdc8d8SChris Lattner                     case eStopReasonBreakpoint:
31130fdc8d8SChris Lattner                         {
31230fdc8d8SChris Lattner                             static char bp_desc[] = "breakpoint hit";
31330fdc8d8SChris Lattner                             stop_desc = bp_desc;
31430fdc8d8SChris Lattner                             stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
31530fdc8d8SChris Lattner                         }
31630fdc8d8SChris Lattner                         break;
31730fdc8d8SChris Lattner 
31830fdc8d8SChris Lattner                     case eStopReasonWatchpoint:
31930fdc8d8SChris Lattner                         {
32030fdc8d8SChris Lattner                             static char wp_desc[] = "watchpoint hit";
32130fdc8d8SChris Lattner                             stop_desc = wp_desc;
32230fdc8d8SChris Lattner                             stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
32330fdc8d8SChris Lattner                         }
32430fdc8d8SChris Lattner                         break;
32530fdc8d8SChris Lattner 
32630fdc8d8SChris Lattner                     case eStopReasonSignal:
32730fdc8d8SChris Lattner                         {
3281ac04c30SGreg Clayton                             stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
32930fdc8d8SChris Lattner                             if (stop_desc == NULL || stop_desc[0] == '\0')
33030fdc8d8SChris Lattner                             {
33130fdc8d8SChris Lattner                                 static char signal_desc[] = "signal";
33230fdc8d8SChris Lattner                                 stop_desc = signal_desc;
33330fdc8d8SChris Lattner                                 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
33430fdc8d8SChris Lattner                             }
33530fdc8d8SChris Lattner                         }
33630fdc8d8SChris Lattner                         break;
33730fdc8d8SChris Lattner 
33830fdc8d8SChris Lattner                     case eStopReasonException:
33930fdc8d8SChris Lattner                         {
34030fdc8d8SChris Lattner                             char exc_desc[] = "exception";
34130fdc8d8SChris Lattner                             stop_desc = exc_desc;
34230fdc8d8SChris Lattner                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
34330fdc8d8SChris Lattner                         }
34430fdc8d8SChris Lattner                         break;
345c982c768SGreg Clayton 
34690ba8115SGreg Clayton                     case eStopReasonExec:
34790ba8115SGreg Clayton                         {
34890ba8115SGreg Clayton                             char exc_desc[] = "exec";
34990ba8115SGreg Clayton                             stop_desc = exc_desc;
35090ba8115SGreg Clayton                             stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
35190ba8115SGreg Clayton                         }
35290ba8115SGreg Clayton                         break;
35390ba8115SGreg Clayton 
354f85defaeSAndrew Kaylor                     case eStopReasonThreadExiting:
355f85defaeSAndrew Kaylor                         {
356f85defaeSAndrew Kaylor                             char limbo_desc[] = "thread exiting";
357f85defaeSAndrew Kaylor                             stop_desc = limbo_desc;
358f85defaeSAndrew Kaylor                             stop_desc_len = sizeof(limbo_desc);
359f85defaeSAndrew Kaylor                         }
360f85defaeSAndrew Kaylor                         break;
361c982c768SGreg Clayton                     default:
362c982c768SGreg Clayton                         break;
36330fdc8d8SChris Lattner                     }
36430fdc8d8SChris Lattner 
36530fdc8d8SChris Lattner                     if (stop_desc && stop_desc[0])
36630fdc8d8SChris Lattner                     {
367ceb6b139SCaroline Tice                         if (log)
36893aa84e8SGreg Clayton                             log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3691ac04c30SGreg Clayton                                          exe_ctx.GetThreadPtr(), stop_desc);
370ceb6b139SCaroline Tice 
37130fdc8d8SChris Lattner                         if (dst)
37230fdc8d8SChris Lattner                             return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
37330fdc8d8SChris Lattner 
37430fdc8d8SChris Lattner                         if (stop_desc_len == 0)
37530fdc8d8SChris Lattner                             stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
37630fdc8d8SChris Lattner 
37730fdc8d8SChris Lattner                         return stop_desc_len;
37830fdc8d8SChris Lattner                     }
37930fdc8d8SChris Lattner                 }
38030fdc8d8SChris Lattner             }
38130fdc8d8SChris Lattner         }
382c9858e4dSGreg Clayton         else
383c9858e4dSGreg Clayton         {
3845160ce5cSGreg Clayton             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
385c9858e4dSGreg Clayton             if (log)
386c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
387c9858e4dSGreg Clayton         }
3887fdf9ef1SGreg Clayton     }
38930fdc8d8SChris Lattner     if (dst)
39030fdc8d8SChris Lattner         *dst = 0;
39130fdc8d8SChris Lattner     return 0;
39230fdc8d8SChris Lattner }
39330fdc8d8SChris Lattner 
39473ca05a2SJim Ingham SBValue
39573ca05a2SJim Ingham SBThread::GetStopReturnValue ()
39673ca05a2SJim Ingham {
3975160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
39873ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
3994fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4004fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4014fc6cb9cSJim Ingham 
4021ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
40373ca05a2SJim Ingham     {
4047fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4057fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4067fdf9ef1SGreg Clayton         {
4071ac04c30SGreg Clayton             StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
40873ca05a2SJim Ingham             if (stop_info_sp)
40973ca05a2SJim Ingham             {
41073ca05a2SJim Ingham                 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
41173ca05a2SJim Ingham             }
41273ca05a2SJim Ingham         }
413c9858e4dSGreg Clayton         else
414c9858e4dSGreg Clayton         {
415c9858e4dSGreg Clayton             if (log)
416c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
417c9858e4dSGreg Clayton         }
4187fdf9ef1SGreg Clayton     }
41973ca05a2SJim Ingham 
42073ca05a2SJim Ingham     if (log)
4211ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
42273ca05a2SJim Ingham                                                                   return_valobj_sp.get()
42373ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
42473ca05a2SJim Ingham                                                                         : "<no return value>");
42573ca05a2SJim Ingham 
42673ca05a2SJim Ingham     return SBValue (return_valobj_sp);
42773ca05a2SJim Ingham }
42873ca05a2SJim Ingham 
42930fdc8d8SChris Lattner void
43030fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
43130fdc8d8SChris Lattner {
4327fdf9ef1SGreg Clayton     m_opaque_sp->SetThreadSP (lldb_object_sp);
43330fdc8d8SChris Lattner }
43430fdc8d8SChris Lattner 
43530fdc8d8SChris Lattner 
43630fdc8d8SChris Lattner lldb::tid_t
43730fdc8d8SChris Lattner SBThread::GetThreadID () const
43830fdc8d8SChris Lattner {
4397fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44017a6ad05SGreg Clayton     if (thread_sp)
4411ac04c30SGreg Clayton         return thread_sp->GetID();
4421ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
44330fdc8d8SChris Lattner }
44430fdc8d8SChris Lattner 
44530fdc8d8SChris Lattner uint32_t
44630fdc8d8SChris Lattner SBThread::GetIndexID () const
44730fdc8d8SChris Lattner {
4487fdf9ef1SGreg Clayton     ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
44917a6ad05SGreg Clayton     if (thread_sp)
45017a6ad05SGreg Clayton         return thread_sp->GetIndexID();
45130fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
45230fdc8d8SChris Lattner }
4531ac04c30SGreg Clayton 
45430fdc8d8SChris Lattner const char *
45530fdc8d8SChris Lattner SBThread::GetName () const
45630fdc8d8SChris Lattner {
4575160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4584838131bSGreg Clayton     const char *name = NULL;
4594fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4604fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4614fc6cb9cSJim Ingham 
4621ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
463af67cecdSGreg Clayton     {
4647fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4657fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4667fdf9ef1SGreg Clayton         {
4671ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetName();
468af67cecdSGreg Clayton         }
469c9858e4dSGreg Clayton         else
470c9858e4dSGreg Clayton         {
471c9858e4dSGreg Clayton             if (log)
472c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
473c9858e4dSGreg Clayton         }
4747fdf9ef1SGreg Clayton     }
475ceb6b139SCaroline Tice 
476ceb6b139SCaroline Tice     if (log)
4771ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
478ceb6b139SCaroline Tice 
4794838131bSGreg Clayton     return name;
48030fdc8d8SChris Lattner }
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner const char *
48330fdc8d8SChris Lattner SBThread::GetQueueName () const
48430fdc8d8SChris Lattner {
4854838131bSGreg Clayton     const char *name = NULL;
4864fc6cb9cSJim Ingham     Mutex::Locker api_locker;
4874fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
4884fc6cb9cSJim Ingham 
4895160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
4901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
491af67cecdSGreg Clayton     {
4927fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
4937fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
4947fdf9ef1SGreg Clayton         {
4951ac04c30SGreg Clayton             name = exe_ctx.GetThreadPtr()->GetQueueName();
496af67cecdSGreg Clayton         }
497c9858e4dSGreg Clayton         else
498c9858e4dSGreg Clayton         {
499c9858e4dSGreg Clayton             if (log)
500c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
501c9858e4dSGreg Clayton         }
5027fdf9ef1SGreg Clayton     }
503ceb6b139SCaroline Tice 
504ceb6b139SCaroline Tice     if (log)
5051ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
506ceb6b139SCaroline Tice 
5074838131bSGreg Clayton     return name;
50830fdc8d8SChris Lattner }
50930fdc8d8SChris Lattner 
51064e7ead1SJim Ingham SBError
51164e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
51264e7ead1SJim Ingham {
51364e7ead1SJim Ingham     SBError sb_error;
51464e7ead1SJim Ingham 
51564e7ead1SJim Ingham     Process *process = exe_ctx.GetProcessPtr();
51664e7ead1SJim Ingham     if (!process)
51764e7ead1SJim Ingham     {
51864e7ead1SJim Ingham         sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
51964e7ead1SJim Ingham         return sb_error;
52064e7ead1SJim Ingham     }
52164e7ead1SJim Ingham 
52264e7ead1SJim Ingham     Thread *thread = exe_ctx.GetThreadPtr();
52364e7ead1SJim Ingham     if (!thread)
52464e7ead1SJim Ingham     {
52564e7ead1SJim Ingham         sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
52664e7ead1SJim Ingham         return sb_error;
52764e7ead1SJim Ingham     }
52864e7ead1SJim Ingham 
52964e7ead1SJim Ingham     // User level plans should be Master Plans so they can be interrupted, other plans executed, and
53064e7ead1SJim Ingham     // then a "continue" will resume the plan.
53164e7ead1SJim Ingham     if (new_plan != NULL)
53264e7ead1SJim Ingham     {
53364e7ead1SJim Ingham         new_plan->SetIsMasterPlan(true);
53464e7ead1SJim Ingham         new_plan->SetOkayToDiscard(false);
53564e7ead1SJim Ingham     }
53664e7ead1SJim Ingham 
53764e7ead1SJim Ingham     // Why do we need to set the current thread by ID here???
53864e7ead1SJim Ingham     process->GetThreadList().SetSelectedThreadByID (thread->GetID());
53964e7ead1SJim Ingham     sb_error.ref() = process->Resume();
54064e7ead1SJim Ingham 
54164e7ead1SJim Ingham     if (sb_error.Success())
54264e7ead1SJim Ingham     {
54364e7ead1SJim Ingham         // If we are doing synchronous mode, then wait for the
54464e7ead1SJim Ingham         // process to stop yet again!
54564e7ead1SJim Ingham         if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
54664e7ead1SJim Ingham             process->WaitForProcessToStop (NULL);
54764e7ead1SJim Ingham     }
54864e7ead1SJim Ingham 
54964e7ead1SJim Ingham     return sb_error;
55064e7ead1SJim Ingham }
55130fdc8d8SChris Lattner 
55230fdc8d8SChris Lattner void
55330fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
55430fdc8d8SChris Lattner {
5555160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
556ceb6b139SCaroline Tice 
5574fc6cb9cSJim Ingham     Mutex::Locker api_locker;
5584fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
5594fc6cb9cSJim Ingham 
56017a6ad05SGreg Clayton 
561ceb6b139SCaroline Tice     if (log)
5621ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
563ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
564ceb6b139SCaroline Tice 
5651ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
56630fdc8d8SChris Lattner     {
5671ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5687ba6e991SJim Ingham         bool abort_other_plans = false;
5691ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
57064e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
57130fdc8d8SChris Lattner 
57230fdc8d8SChris Lattner         if (frame_sp)
57330fdc8d8SChris Lattner         {
57430fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
57530fdc8d8SChris Lattner             {
57630fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
577c627682eSJim Ingham                 new_plan = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
57830fdc8d8SChris Lattner                                                                     sc.line_entry.range,
57930fdc8d8SChris Lattner                                                                     sc,
580c627682eSJim Ingham                                                                     stop_other_threads);
58130fdc8d8SChris Lattner             }
58230fdc8d8SChris Lattner             else
58330fdc8d8SChris Lattner             {
58464e7ead1SJim Ingham                 new_plan = thread->QueueThreadPlanForStepSingleInstruction (true,
58530fdc8d8SChris Lattner                                                                             abort_other_plans,
58630fdc8d8SChris Lattner                                                                             stop_other_threads);
58730fdc8d8SChris Lattner             }
58830fdc8d8SChris Lattner         }
58930fdc8d8SChris Lattner 
59064e7ead1SJim Ingham         // This returns an error, we should use it!
59164e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
59230fdc8d8SChris Lattner     }
59330fdc8d8SChris Lattner }
59430fdc8d8SChris Lattner 
59530fdc8d8SChris Lattner void
59630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
59730fdc8d8SChris Lattner {
598c627682eSJim Ingham     StepInto (NULL, stop_other_threads);
599c627682eSJim Ingham }
600c627682eSJim Ingham 
601c627682eSJim Ingham void
602c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
603c627682eSJim Ingham {
6045160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
605ceb6b139SCaroline Tice 
6064fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6074fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
60817a6ad05SGreg Clayton 
60917a6ad05SGreg Clayton     if (log)
610c627682eSJim Ingham         log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
611c627682eSJim Ingham                      exe_ctx.GetThreadPtr(),
612c627682eSJim Ingham                      target_name? target_name: "<NULL>",
61317a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
614c627682eSJim Ingham 
6151ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
61630fdc8d8SChris Lattner     {
6177ba6e991SJim Ingham         bool abort_other_plans = false;
61830fdc8d8SChris Lattner 
6191ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6201ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
62164e7ead1SJim Ingham         ThreadPlan *new_plan = NULL;
62230fdc8d8SChris Lattner 
62330fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
62430fdc8d8SChris Lattner         {
625474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
62630fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
627c627682eSJim Ingham             new_plan = thread->QueueThreadPlanForStepInRange (abort_other_plans,
62830fdc8d8SChris Lattner                                                               sc.line_entry.range,
62930fdc8d8SChris Lattner                                                               sc,
630c627682eSJim Ingham                                                               target_name,
631474966a4SGreg Clayton                                                               stop_other_threads,
632474966a4SGreg Clayton                                                               avoid_code_without_debug_info);
63330fdc8d8SChris Lattner         }
63430fdc8d8SChris Lattner         else
63530fdc8d8SChris Lattner         {
63664e7ead1SJim Ingham             new_plan = thread->QueueThreadPlanForStepSingleInstruction (false,
63730fdc8d8SChris Lattner                                                                         abort_other_plans,
63830fdc8d8SChris Lattner                                                                         stop_other_threads);
63930fdc8d8SChris Lattner         }
64030fdc8d8SChris Lattner 
64164e7ead1SJim Ingham         // This returns an error, we should use it!
64264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
64330fdc8d8SChris Lattner     }
64430fdc8d8SChris Lattner }
64530fdc8d8SChris Lattner 
64630fdc8d8SChris Lattner void
64730fdc8d8SChris Lattner SBThread::StepOut ()
64830fdc8d8SChris Lattner {
6495160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
650ceb6b139SCaroline Tice 
6514fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6524fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6534fc6cb9cSJim Ingham 
654ceb6b139SCaroline Tice 
65517a6ad05SGreg Clayton     if (log)
6561ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
65717a6ad05SGreg Clayton 
6581ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
65930fdc8d8SChris Lattner     {
6607ba6e991SJim Ingham         bool abort_other_plans = false;
66194b09246SJim Ingham         bool stop_other_threads = false;
66230fdc8d8SChris Lattner 
6631ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6641ac04c30SGreg Clayton 
66564e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
666481cef25SGreg Clayton                                                                   NULL,
667481cef25SGreg Clayton                                                                   false,
668481cef25SGreg Clayton                                                                   stop_other_threads,
669481cef25SGreg Clayton                                                                   eVoteYes,
670481cef25SGreg Clayton                                                                   eVoteNoOpinion,
671481cef25SGreg Clayton                                                                   0);
672481cef25SGreg Clayton 
67364e7ead1SJim Ingham         // This returns an error, we should use it!
67464e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
675481cef25SGreg Clayton     }
676481cef25SGreg Clayton }
677481cef25SGreg Clayton 
678481cef25SGreg Clayton void
679481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
680481cef25SGreg Clayton {
6815160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
682481cef25SGreg Clayton 
6834fc6cb9cSJim Ingham     Mutex::Locker api_locker;
6844fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
6854fc6cb9cSJim Ingham 
686b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
687481cef25SGreg Clayton     if (log)
688481cef25SGreg Clayton     {
689481cef25SGreg Clayton         SBStream frame_desc_strm;
690481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
6911ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
692481cef25SGreg Clayton     }
693481cef25SGreg Clayton 
6941ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
695481cef25SGreg Clayton     {
6967ba6e991SJim Ingham         bool abort_other_plans = false;
69794b09246SJim Ingham         bool stop_other_threads = false;
6981ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
699481cef25SGreg Clayton 
70064e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans,
701481cef25SGreg Clayton                                                                     NULL,
702481cef25SGreg Clayton                                                                     false,
703481cef25SGreg Clayton                                                                     stop_other_threads,
704481cef25SGreg Clayton                                                                     eVoteYes,
705481cef25SGreg Clayton                                                                     eVoteNoOpinion,
706b9556accSGreg Clayton                                                                     frame_sp->GetFrameIndex());
70730fdc8d8SChris Lattner 
70864e7ead1SJim Ingham         // This returns an error, we should use it!
70964e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
71030fdc8d8SChris Lattner     }
71130fdc8d8SChris Lattner }
71230fdc8d8SChris Lattner 
71330fdc8d8SChris Lattner void
71430fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
71530fdc8d8SChris Lattner {
7165160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
717ceb6b139SCaroline Tice 
7184fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7194fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7204fc6cb9cSJim Ingham 
7211ac04c30SGreg Clayton 
722ceb6b139SCaroline Tice 
72317a6ad05SGreg Clayton     if (log)
7241ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
72517a6ad05SGreg Clayton 
7261ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
72730fdc8d8SChris Lattner     {
7281ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
72964e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
73064e7ead1SJim Ingham 
73164e7ead1SJim Ingham         // This returns an error, we should use it!
73264e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
73330fdc8d8SChris Lattner     }
73430fdc8d8SChris Lattner }
73530fdc8d8SChris Lattner 
73630fdc8d8SChris Lattner void
73730fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
73830fdc8d8SChris Lattner {
7395160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
740ceb6b139SCaroline Tice 
7414fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7424fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7434fc6cb9cSJim Ingham 
744ceb6b139SCaroline Tice 
74517a6ad05SGreg Clayton     if (log)
746d01b2953SDaniel Malea         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
74717a6ad05SGreg Clayton 
7481ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
74930fdc8d8SChris Lattner     {
7507ba6e991SJim Ingham         bool abort_other_plans = false;
75130fdc8d8SChris Lattner         bool stop_other_threads = true;
75230fdc8d8SChris Lattner 
753e72dfb32SGreg Clayton         Address target_addr (addr);
75430fdc8d8SChris Lattner 
7551ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
7561ac04c30SGreg Clayton 
75764e7ead1SJim Ingham         ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
75864e7ead1SJim Ingham 
75964e7ead1SJim Ingham         // This returns an error, we should use it!
76064e7ead1SJim Ingham         ResumeNewPlan (exe_ctx, new_plan);
76130fdc8d8SChris Lattner     }
76230fdc8d8SChris Lattner }
76330fdc8d8SChris Lattner 
764481cef25SGreg Clayton SBError
765481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
766481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
767481cef25SGreg Clayton                          uint32_t line)
768481cef25SGreg Clayton {
769481cef25SGreg Clayton     SBError sb_error;
7705160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
771481cef25SGreg Clayton     char path[PATH_MAX];
772481cef25SGreg Clayton 
7734fc6cb9cSJim Ingham     Mutex::Locker api_locker;
7744fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
7754fc6cb9cSJim Ingham 
776b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
77717a6ad05SGreg Clayton 
778481cef25SGreg Clayton     if (log)
779481cef25SGreg Clayton     {
780481cef25SGreg Clayton         SBStream frame_desc_strm;
781481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
782481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
783481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
7841ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
785b9556accSGreg Clayton                      frame_sp.get(),
786481cef25SGreg Clayton                      frame_desc_strm.GetData(),
787481cef25SGreg Clayton                      path, line);
788481cef25SGreg Clayton     }
789481cef25SGreg Clayton 
7901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
791481cef25SGreg Clayton     {
7921ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
7931ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
794481cef25SGreg Clayton 
795481cef25SGreg Clayton         if (line == 0)
796481cef25SGreg Clayton         {
797481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
798481cef25SGreg Clayton             return sb_error;
799481cef25SGreg Clayton         }
800481cef25SGreg Clayton 
801b9556accSGreg Clayton         if (!frame_sp)
802481cef25SGreg Clayton         {
8031ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
804481cef25SGreg Clayton             if (!frame_sp)
8051ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
806481cef25SGreg Clayton         }
807481cef25SGreg Clayton 
808481cef25SGreg Clayton         SymbolContext frame_sc;
809481cef25SGreg Clayton         if (!frame_sp)
810481cef25SGreg Clayton         {
811481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
812481cef25SGreg Clayton             return sb_error;
813481cef25SGreg Clayton         }
814481cef25SGreg Clayton 
815481cef25SGreg Clayton         // If we have a frame, get its line
816481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
817481cef25SGreg Clayton                                                eSymbolContextFunction  |
818481cef25SGreg Clayton                                                eSymbolContextLineEntry |
819481cef25SGreg Clayton                                                eSymbolContextSymbol    );
820481cef25SGreg Clayton 
821481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
822481cef25SGreg Clayton         {
823481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
824481cef25SGreg Clayton             return sb_error;
825481cef25SGreg Clayton         }
826481cef25SGreg Clayton 
827481cef25SGreg Clayton         FileSpec step_file_spec;
828481cef25SGreg Clayton         if (sb_file_spec.IsValid())
829481cef25SGreg Clayton         {
830481cef25SGreg Clayton             // The file spec passed in was valid, so use it
831481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
832481cef25SGreg Clayton         }
833481cef25SGreg Clayton         else
834481cef25SGreg Clayton         {
835481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
836481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
837481cef25SGreg Clayton             else
838481cef25SGreg Clayton             {
839481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
840481cef25SGreg Clayton                 return sb_error;
841481cef25SGreg Clayton             }
842481cef25SGreg Clayton         }
843481cef25SGreg Clayton 
8449b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
8459b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
8469b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
8479b70ddb3SJim Ingham         // error message.
8489b70ddb3SJim Ingham 
8499b70ddb3SJim Ingham         bool all_in_function = true;
8509b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
8519b70ddb3SJim Ingham 
852481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
8537ba6e991SJim Ingham         const bool abort_other_plans = false;
854c02e3344SJim Ingham         const bool stop_other_threads = false;
855481cef25SGreg Clayton         const bool check_inlines = true;
856481cef25SGreg Clayton         const bool exact = false;
857481cef25SGreg Clayton 
858481cef25SGreg Clayton         SymbolContextList sc_list;
8599b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
8609b70ddb3SJim Ingham                                                                                line,
8619b70ddb3SJim Ingham                                                                                check_inlines,
8629b70ddb3SJim Ingham                                                                                exact,
8639b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
8649b70ddb3SJim Ingham                                                                                sc_list);
865481cef25SGreg Clayton         if (num_matches > 0)
866481cef25SGreg Clayton         {
867481cef25SGreg Clayton             SymbolContext sc;
868481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
869481cef25SGreg Clayton             {
870481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
871481cef25SGreg Clayton                 {
8729b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
873481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
874481cef25SGreg Clayton                     {
8759b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
876481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
8779b70ddb3SJim Ingham                         else
8789b70ddb3SJim Ingham                             all_in_function = false;
879481cef25SGreg Clayton                     }
880481cef25SGreg Clayton                 }
881481cef25SGreg Clayton             }
882481cef25SGreg Clayton         }
883481cef25SGreg Clayton 
884481cef25SGreg Clayton         if (step_over_until_addrs.empty())
885481cef25SGreg Clayton         {
8869b70ddb3SJim Ingham             if (all_in_function)
8879b70ddb3SJim Ingham             {
888481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
889fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
890481cef25SGreg Clayton             }
891481cef25SGreg Clayton             else
89286edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
8939b70ddb3SJim Ingham         }
8949b70ddb3SJim Ingham         else
895481cef25SGreg Clayton         {
89664e7ead1SJim Ingham             ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans,
897481cef25SGreg Clayton                                                                         &step_over_until_addrs[0],
898481cef25SGreg Clayton                                                                         step_over_until_addrs.size(),
899481cef25SGreg Clayton                                                                         stop_other_threads,
900481cef25SGreg Clayton                                                                         frame_sp->GetFrameIndex());
901481cef25SGreg Clayton 
90264e7ead1SJim Ingham             sb_error = ResumeNewPlan (exe_ctx, new_plan);
903481cef25SGreg Clayton         }
904481cef25SGreg Clayton     }
905481cef25SGreg Clayton     else
906481cef25SGreg Clayton     {
907481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
908481cef25SGreg Clayton     }
909481cef25SGreg Clayton     return sb_error;
910481cef25SGreg Clayton }
911481cef25SGreg Clayton 
9124413758cSJim Ingham SBError
913cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
9144413758cSJim Ingham {
9154413758cSJim Ingham     SBError sb_error;
9164413758cSJim Ingham 
9175160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9184413758cSJim Ingham 
9194413758cSJim Ingham     Mutex::Locker api_locker;
9204413758cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
9214413758cSJim Ingham 
9224413758cSJim Ingham 
9234413758cSJim Ingham     if (log)
924cb640dd8SJim Ingham         log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
9254413758cSJim Ingham 
9264413758cSJim Ingham     if (exe_ctx.HasThreadScope())
9274413758cSJim Ingham     {
9284413758cSJim Ingham         Thread *thread = exe_ctx.GetThreadPtr();
929cb640dd8SJim Ingham         sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
9304413758cSJim Ingham     }
9314413758cSJim Ingham 
9324413758cSJim Ingham     return sb_error;
9334413758cSJim Ingham }
9344413758cSJim Ingham 
935481cef25SGreg Clayton 
936722a0cdcSGreg Clayton bool
937722a0cdcSGreg Clayton SBThread::Suspend()
938722a0cdcSGreg Clayton {
9395160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9407fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
941c9858e4dSGreg Clayton     bool result = false;
9421ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
943722a0cdcSGreg Clayton     {
944c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
945c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
946c9858e4dSGreg Clayton         {
9471ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
948c9858e4dSGreg Clayton             result = true;
949722a0cdcSGreg Clayton         }
950c9858e4dSGreg Clayton         else
951c9858e4dSGreg Clayton         {
952c9858e4dSGreg Clayton             if (log)
953c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
954c9858e4dSGreg Clayton         }
955c9858e4dSGreg Clayton     }
956c9858e4dSGreg Clayton     if (log)
957c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
958c9858e4dSGreg Clayton     return result;
959722a0cdcSGreg Clayton }
960722a0cdcSGreg Clayton 
961722a0cdcSGreg Clayton bool
962722a0cdcSGreg Clayton SBThread::Resume ()
963722a0cdcSGreg Clayton {
9645160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
9657fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
966c9858e4dSGreg Clayton     bool result = false;
9671ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
968722a0cdcSGreg Clayton     {
969c9858e4dSGreg Clayton         Process::StopLocker stop_locker;
970c9858e4dSGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
971c9858e4dSGreg Clayton         {
9721ac04c30SGreg Clayton             exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
973c9858e4dSGreg Clayton             result = true;
974722a0cdcSGreg Clayton         }
975c9858e4dSGreg Clayton         else
976c9858e4dSGreg Clayton         {
977c9858e4dSGreg Clayton             if (log)
978c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
979c9858e4dSGreg Clayton         }
980c9858e4dSGreg Clayton     }
981c9858e4dSGreg Clayton     if (log)
982c9858e4dSGreg Clayton         log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
983c9858e4dSGreg Clayton     return result;
984722a0cdcSGreg Clayton }
985722a0cdcSGreg Clayton 
986722a0cdcSGreg Clayton bool
987722a0cdcSGreg Clayton SBThread::IsSuspended()
988722a0cdcSGreg Clayton {
9897fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
9901ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
9911ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
992722a0cdcSGreg Clayton     return false;
993722a0cdcSGreg Clayton }
994722a0cdcSGreg Clayton 
995*a75418dbSAndrew Kaylor bool
996*a75418dbSAndrew Kaylor SBThread::IsStopped()
997*a75418dbSAndrew Kaylor {
998*a75418dbSAndrew Kaylor     ExecutionContext exe_ctx (m_opaque_sp.get());
999*a75418dbSAndrew Kaylor     if (exe_ctx.HasThreadScope())
1000*a75418dbSAndrew Kaylor         return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1001*a75418dbSAndrew Kaylor     return false;
1002*a75418dbSAndrew Kaylor }
1003*a75418dbSAndrew Kaylor 
100430fdc8d8SChris Lattner SBProcess
100530fdc8d8SChris Lattner SBThread::GetProcess ()
100630fdc8d8SChris Lattner {
1007b9556accSGreg Clayton     SBProcess sb_process;
10087fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
10091ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
101030fdc8d8SChris Lattner     {
101130fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
10121ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
101330fdc8d8SChris Lattner     }
1014ceb6b139SCaroline Tice 
10155160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1016ceb6b139SCaroline Tice     if (log)
1017ceb6b139SCaroline Tice     {
1018481cef25SGreg Clayton         SBStream frame_desc_strm;
1019b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
10201ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
10210a2df227SEnrico Granata                      sb_process.GetSP().get(), frame_desc_strm.GetData());
1022ceb6b139SCaroline Tice     }
1023ceb6b139SCaroline Tice 
1024b9556accSGreg Clayton     return sb_process;
102530fdc8d8SChris Lattner }
102630fdc8d8SChris Lattner 
102730fdc8d8SChris Lattner uint32_t
102830fdc8d8SChris Lattner SBThread::GetNumFrames ()
102930fdc8d8SChris Lattner {
10305160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1031ceb6b139SCaroline Tice 
1032ceb6b139SCaroline Tice     uint32_t num_frames = 0;
10334fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10344fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10354fc6cb9cSJim Ingham 
10361ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1037af67cecdSGreg Clayton     {
10387fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10397fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10407fdf9ef1SGreg Clayton         {
10411ac04c30SGreg Clayton             num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1042af67cecdSGreg Clayton         }
1043c9858e4dSGreg Clayton         else
1044c9858e4dSGreg Clayton         {
1045c9858e4dSGreg Clayton             if (log)
1046c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1047c9858e4dSGreg Clayton         }
10487fdf9ef1SGreg Clayton     }
1049ceb6b139SCaroline Tice 
1050ceb6b139SCaroline Tice     if (log)
10511ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1052ceb6b139SCaroline Tice 
1053ceb6b139SCaroline Tice     return num_frames;
105430fdc8d8SChris Lattner }
105530fdc8d8SChris Lattner 
105630fdc8d8SChris Lattner SBFrame
105730fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
105830fdc8d8SChris Lattner {
10595160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1060ceb6b139SCaroline Tice 
106130fdc8d8SChris Lattner     SBFrame sb_frame;
1062b9556accSGreg Clayton     StackFrameSP frame_sp;
10634fc6cb9cSJim Ingham     Mutex::Locker api_locker;
10644fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
10654fc6cb9cSJim Ingham 
10661ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1067af67cecdSGreg Clayton     {
10687fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
10697fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
10707fdf9ef1SGreg Clayton         {
10711ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1072b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1073af67cecdSGreg Clayton         }
1074c9858e4dSGreg Clayton         else
1075c9858e4dSGreg Clayton         {
1076c9858e4dSGreg Clayton             if (log)
1077c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1078c9858e4dSGreg Clayton         }
10797fdf9ef1SGreg Clayton     }
1080ceb6b139SCaroline Tice 
1081ceb6b139SCaroline Tice     if (log)
1082ceb6b139SCaroline Tice     {
1083481cef25SGreg Clayton         SBStream frame_desc_strm;
1084481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
10854838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
10861ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1087ceb6b139SCaroline Tice     }
1088ceb6b139SCaroline Tice 
108930fdc8d8SChris Lattner     return sb_frame;
109030fdc8d8SChris Lattner }
109130fdc8d8SChris Lattner 
1092f028a1fbSGreg Clayton lldb::SBFrame
1093f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
1094f028a1fbSGreg Clayton {
10955160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1096f028a1fbSGreg Clayton 
1097f028a1fbSGreg Clayton     SBFrame sb_frame;
1098b9556accSGreg Clayton     StackFrameSP frame_sp;
10994fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11004fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11014fc6cb9cSJim Ingham 
11021ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1103af67cecdSGreg Clayton     {
11047fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11057fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11067fdf9ef1SGreg Clayton         {
11071ac04c30SGreg Clayton             frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1108b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
1109af67cecdSGreg Clayton         }
1110c9858e4dSGreg Clayton         else
1111c9858e4dSGreg Clayton         {
1112c9858e4dSGreg Clayton             if (log)
1113c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1114c9858e4dSGreg Clayton         }
11157fdf9ef1SGreg Clayton     }
1116f028a1fbSGreg Clayton 
1117f028a1fbSGreg Clayton     if (log)
1118f028a1fbSGreg Clayton     {
1119481cef25SGreg Clayton         SBStream frame_desc_strm;
1120481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1121f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
11221ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1123f028a1fbSGreg Clayton     }
1124f028a1fbSGreg Clayton 
1125f028a1fbSGreg Clayton     return sb_frame;
1126f028a1fbSGreg Clayton }
1127f028a1fbSGreg Clayton 
1128f028a1fbSGreg Clayton lldb::SBFrame
1129f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
1130f028a1fbSGreg Clayton {
11315160ce5cSGreg Clayton     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1132f028a1fbSGreg Clayton 
1133f028a1fbSGreg Clayton     SBFrame sb_frame;
1134b9556accSGreg Clayton     StackFrameSP frame_sp;
11354fc6cb9cSJim Ingham     Mutex::Locker api_locker;
11364fc6cb9cSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
11374fc6cb9cSJim Ingham 
11381ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1139f028a1fbSGreg Clayton     {
11407fdf9ef1SGreg Clayton         Process::StopLocker stop_locker;
11417fdf9ef1SGreg Clayton         if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
11427fdf9ef1SGreg Clayton         {
11431ac04c30SGreg Clayton             Thread *thread = exe_ctx.GetThreadPtr();
11441ac04c30SGreg Clayton             frame_sp = thread->GetStackFrameAtIndex (idx);
1145f028a1fbSGreg Clayton             if (frame_sp)
1146f028a1fbSGreg Clayton             {
11471ac04c30SGreg Clayton                 thread->SetSelectedFrame (frame_sp.get());
1148b9556accSGreg Clayton                 sb_frame.SetFrameSP (frame_sp);
1149f028a1fbSGreg Clayton             }
1150f028a1fbSGreg Clayton         }
1151c9858e4dSGreg Clayton         else
1152c9858e4dSGreg Clayton         {
1153c9858e4dSGreg Clayton             if (log)
1154c9858e4dSGreg Clayton                 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1155c9858e4dSGreg Clayton         }
11567fdf9ef1SGreg Clayton     }
1157f028a1fbSGreg Clayton 
1158f028a1fbSGreg Clayton     if (log)
1159f028a1fbSGreg Clayton     {
1160481cef25SGreg Clayton         SBStream frame_desc_strm;
1161481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
1162f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
11631ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1164f028a1fbSGreg Clayton     }
1165f028a1fbSGreg Clayton     return sb_frame;
1166f028a1fbSGreg Clayton }
1167f028a1fbSGreg Clayton 
11684f465cffSJim Ingham bool
11694f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event)
11704f465cffSJim Ingham {
11714f465cffSJim Ingham     return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
11724f465cffSJim Ingham }
11734f465cffSJim Ingham 
11744f465cffSJim Ingham SBFrame
11754f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event)
11764f465cffSJim Ingham {
11774f465cffSJim Ingham     return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
11784f465cffSJim Ingham 
11794f465cffSJim Ingham }
11804f465cffSJim Ingham 
11814f465cffSJim Ingham SBThread
11824f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event)
11834f465cffSJim Ingham {
11844f465cffSJim Ingham     return Thread::ThreadEventData::GetThreadFromEvent (event.get());
11854f465cffSJim Ingham }
1186f028a1fbSGreg Clayton 
118730fdc8d8SChris Lattner bool
118830fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
118930fdc8d8SChris Lattner {
11907fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
119130fdc8d8SChris Lattner }
119230fdc8d8SChris Lattner 
119330fdc8d8SChris Lattner bool
119430fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
119530fdc8d8SChris Lattner {
11967fdf9ef1SGreg Clayton     return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
119730fdc8d8SChris Lattner }
1198dde9cff3SCaroline Tice 
1199dde9cff3SCaroline Tice bool
12004f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const
12014f465cffSJim Ingham {
12024f465cffSJim Ingham     Stream &strm = status.ref();
12034f465cffSJim Ingham 
12044f465cffSJim Ingham     ExecutionContext exe_ctx (m_opaque_sp.get());
12054f465cffSJim Ingham     if (exe_ctx.HasThreadScope())
12064f465cffSJim Ingham     {
12074f465cffSJim Ingham         exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
12084f465cffSJim Ingham     }
12094f465cffSJim Ingham     else
12104f465cffSJim Ingham         strm.PutCString ("No status");
12114f465cffSJim Ingham 
12124f465cffSJim Ingham     return true;
12134f465cffSJim Ingham }
12144f465cffSJim Ingham 
12154f465cffSJim Ingham bool
1216ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
1217ceb6b139SCaroline Tice {
1218da7bc7d0SGreg Clayton     Stream &strm = description.ref();
1219da7bc7d0SGreg Clayton 
12207fdf9ef1SGreg Clayton     ExecutionContext exe_ctx (m_opaque_sp.get());
12211ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1222ceb6b139SCaroline Tice     {
1223d01b2953SDaniel Malea         strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1224ceb6b139SCaroline Tice     }
1225ceb6b139SCaroline Tice     else
1226da7bc7d0SGreg Clayton         strm.PutCString ("No value");
1227ceb6b139SCaroline Tice 
1228ceb6b139SCaroline Tice     return true;
1229ceb6b139SCaroline Tice }
1230