130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
104c5de699SEli Friedman #include "lldb/API/SBThread.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h"
1330fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h"
14dde9cff3SCaroline Tice #include "lldb/API/SBStream.h"
154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h"
166611103cSGreg Clayton #include "lldb/Core/Debugger.h"
1730fdc8d8SChris Lattner #include "lldb/Core/Stream.h"
1830fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h"
196611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2030fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2230fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h"
2330fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
24f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
2530fdc8d8SChris Lattner #include "lldb/Target/Target.h"
2630fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
2730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h"
2830fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h"
2930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h"
3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h"
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner 
334c5de699SEli Friedman #include "lldb/API/SBAddress.h"
344c5de699SEli Friedman #include "lldb/API/SBDebugger.h"
3573ca05a2SJim Ingham #include "lldb/API/SBFrame.h"
364c5de699SEli Friedman #include "lldb/API/SBProcess.h"
3773ca05a2SJim Ingham #include "lldb/API/SBValue.h"
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner using namespace lldb;
4030fdc8d8SChris Lattner using namespace lldb_private;
4130fdc8d8SChris Lattner 
42cfd1acedSGreg Clayton //----------------------------------------------------------------------
43cfd1acedSGreg Clayton // Constructors
44cfd1acedSGreg Clayton //----------------------------------------------------------------------
4530fdc8d8SChris Lattner SBThread::SBThread () :
466611103cSGreg Clayton     m_opaque_sp ()
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner 
5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
516611103cSGreg Clayton     m_opaque_sp (lldb_object_sp)
5230fdc8d8SChris Lattner {
5330fdc8d8SChris Lattner }
5430fdc8d8SChris Lattner 
5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
5692ef5735SGreg Clayton     m_opaque_sp (rhs.m_opaque_sp)
5730fdc8d8SChris Lattner {
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner //----------------------------------------------------------------------
61cfd1acedSGreg Clayton // Assignment operator
62cfd1acedSGreg Clayton //----------------------------------------------------------------------
63cfd1acedSGreg Clayton 
64cfd1acedSGreg Clayton const lldb::SBThread &
65cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs)
66cfd1acedSGreg Clayton {
67cfd1acedSGreg Clayton     if (this != &rhs)
68cfd1acedSGreg Clayton         m_opaque_sp = rhs.m_opaque_sp;
69cfd1acedSGreg Clayton     return *this;
70cfd1acedSGreg Clayton }
71cfd1acedSGreg Clayton 
72cfd1acedSGreg Clayton //----------------------------------------------------------------------
7330fdc8d8SChris Lattner // Destructor
7430fdc8d8SChris Lattner //----------------------------------------------------------------------
7530fdc8d8SChris Lattner SBThread::~SBThread()
7630fdc8d8SChris Lattner {
7730fdc8d8SChris Lattner }
7830fdc8d8SChris Lattner 
7930fdc8d8SChris Lattner bool
8030fdc8d8SChris Lattner SBThread::IsValid() const
8130fdc8d8SChris Lattner {
82762f7135SGreg Clayton     return m_opaque_sp;
8330fdc8d8SChris Lattner }
8430fdc8d8SChris Lattner 
8548e42549SGreg Clayton void
8648e42549SGreg Clayton SBThread::Clear ()
8748e42549SGreg Clayton {
8848e42549SGreg Clayton     m_opaque_sp.reset();
8948e42549SGreg Clayton }
9048e42549SGreg Clayton 
9148e42549SGreg Clayton 
9230fdc8d8SChris Lattner StopReason
9330fdc8d8SChris Lattner SBThread::GetStopReason()
9430fdc8d8SChris Lattner {
952d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
96ceb6b139SCaroline Tice 
97ceb6b139SCaroline Tice     StopReason reason = eStopReasonInvalid;
986611103cSGreg Clayton     if (m_opaque_sp)
9930fdc8d8SChris Lattner     {
100af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
101b15bfc75SJim Ingham         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
102b15bfc75SJim Ingham         if (stop_info_sp)
103ceb6b139SCaroline Tice             reason =  stop_info_sp->GetStopReason();
10430fdc8d8SChris Lattner     }
105ceb6b139SCaroline Tice 
106ceb6b139SCaroline Tice     if (log)
1074838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", m_opaque_sp.get(),
108750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
109ceb6b139SCaroline Tice 
110ceb6b139SCaroline Tice     return reason;
11130fdc8d8SChris Lattner }
11230fdc8d8SChris Lattner 
11330fdc8d8SChris Lattner size_t
1144e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1154e78f606SGreg Clayton {
1164e78f606SGreg Clayton     if (m_opaque_sp)
1174e78f606SGreg Clayton     {
118af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
1194e78f606SGreg Clayton         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
1204e78f606SGreg Clayton         if (stop_info_sp)
1214e78f606SGreg Clayton         {
1224e78f606SGreg Clayton             StopReason reason = stop_info_sp->GetStopReason();
1234e78f606SGreg Clayton             switch (reason)
1244e78f606SGreg Clayton             {
1254e78f606SGreg Clayton             case eStopReasonInvalid:
1264e78f606SGreg Clayton             case eStopReasonNone:
1274e78f606SGreg Clayton             case eStopReasonTrace:
1284e78f606SGreg Clayton             case eStopReasonPlanComplete:
1294e78f606SGreg Clayton                 // There is no data for these stop reasons.
1304e78f606SGreg Clayton                 return 0;
1314e78f606SGreg Clayton 
1324e78f606SGreg Clayton             case eStopReasonBreakpoint:
1334e78f606SGreg Clayton                 {
1344e78f606SGreg Clayton                     break_id_t site_id = stop_info_sp->GetValue();
1354e78f606SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
1364e78f606SGreg Clayton                     if (bp_site_sp)
1374e78f606SGreg Clayton                         return bp_site_sp->GetNumberOfOwners () * 2;
1384e78f606SGreg Clayton                     else
1394e78f606SGreg Clayton                         return 0; // Breakpoint must have cleared itself...
1404e78f606SGreg Clayton                 }
1414e78f606SGreg Clayton                 break;
1424e78f606SGreg Clayton 
1434e78f606SGreg Clayton             case eStopReasonWatchpoint:
144*290fa41bSJohnny Chen                 return 1;
1454e78f606SGreg Clayton 
1464e78f606SGreg Clayton             case eStopReasonSignal:
1474e78f606SGreg Clayton                 return 1;
1484e78f606SGreg Clayton 
1494e78f606SGreg Clayton             case eStopReasonException:
1504e78f606SGreg Clayton                 return 1;
1514e78f606SGreg Clayton             }
1524e78f606SGreg Clayton         }
1534e78f606SGreg Clayton     }
1544e78f606SGreg Clayton     return 0;
1554e78f606SGreg Clayton }
1564e78f606SGreg Clayton 
1574e78f606SGreg Clayton uint64_t
1584e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1594e78f606SGreg Clayton {
1604e78f606SGreg Clayton     if (m_opaque_sp)
1614e78f606SGreg Clayton     {
162af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
1634e78f606SGreg Clayton         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
1644e78f606SGreg Clayton         if (stop_info_sp)
1654e78f606SGreg Clayton         {
1664e78f606SGreg Clayton             StopReason reason = stop_info_sp->GetStopReason();
1674e78f606SGreg Clayton             switch (reason)
1684e78f606SGreg Clayton             {
1694e78f606SGreg Clayton             case eStopReasonInvalid:
1704e78f606SGreg Clayton             case eStopReasonNone:
1714e78f606SGreg Clayton             case eStopReasonTrace:
1724e78f606SGreg Clayton             case eStopReasonPlanComplete:
1734e78f606SGreg Clayton                 // There is no data for these stop reasons.
1744e78f606SGreg Clayton                 return 0;
1754e78f606SGreg Clayton 
1764e78f606SGreg Clayton             case eStopReasonBreakpoint:
1774e78f606SGreg Clayton                 {
1784e78f606SGreg Clayton                     break_id_t site_id = stop_info_sp->GetValue();
1794e78f606SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
1804e78f606SGreg Clayton                     if (bp_site_sp)
1814e78f606SGreg Clayton                     {
1824e78f606SGreg Clayton                         uint32_t bp_index = idx / 2;
1834e78f606SGreg Clayton                         BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
1844e78f606SGreg Clayton                         if (bp_loc_sp)
1854e78f606SGreg Clayton                         {
1864e78f606SGreg Clayton                             if (bp_index & 1)
1874e78f606SGreg Clayton                             {
1884e78f606SGreg Clayton                                 // Odd idx, return the breakpoint location ID
1894e78f606SGreg Clayton                                 return bp_loc_sp->GetID();
1904e78f606SGreg Clayton                             }
1914e78f606SGreg Clayton                             else
1924e78f606SGreg Clayton                             {
1934e78f606SGreg Clayton                                 // Even idx, return the breakpoint ID
1944e78f606SGreg Clayton                                 return bp_loc_sp->GetBreakpoint().GetID();
1954e78f606SGreg Clayton                             }
1964e78f606SGreg Clayton                         }
1974e78f606SGreg Clayton                     }
1984e78f606SGreg Clayton                     return LLDB_INVALID_BREAK_ID;
1994e78f606SGreg Clayton                 }
2004e78f606SGreg Clayton                 break;
2014e78f606SGreg Clayton 
2024e78f606SGreg Clayton             case eStopReasonWatchpoint:
203*290fa41bSJohnny Chen                 return stop_info_sp->GetValue();
2044e78f606SGreg Clayton 
2054e78f606SGreg Clayton             case eStopReasonSignal:
2064e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2074e78f606SGreg Clayton 
2084e78f606SGreg Clayton             case eStopReasonException:
2094e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2104e78f606SGreg Clayton             }
2114e78f606SGreg Clayton         }
2124e78f606SGreg Clayton     }
2134e78f606SGreg Clayton     return 0;
2144e78f606SGreg Clayton }
2154e78f606SGreg Clayton 
2164e78f606SGreg Clayton size_t
21730fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
21830fdc8d8SChris Lattner {
2192d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
220ceb6b139SCaroline Tice 
2216611103cSGreg Clayton     if (m_opaque_sp)
22230fdc8d8SChris Lattner     {
223af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
224b15bfc75SJim Ingham         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
225b15bfc75SJim Ingham         if (stop_info_sp)
22630fdc8d8SChris Lattner         {
227b15bfc75SJim Ingham             const char *stop_desc = stop_info_sp->GetDescription();
22830fdc8d8SChris Lattner             if (stop_desc)
22930fdc8d8SChris Lattner             {
230ceb6b139SCaroline Tice                 if (log)
2314838131bSGreg Clayton                     log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
232750cd175SCaroline Tice                                  m_opaque_sp.get(), stop_desc);
23330fdc8d8SChris Lattner                 if (dst)
23430fdc8d8SChris Lattner                     return ::snprintf (dst, dst_len, "%s", stop_desc);
23530fdc8d8SChris Lattner                 else
23630fdc8d8SChris Lattner                 {
23730fdc8d8SChris Lattner                     // NULL dst passed in, return the length needed to contain the description
23830fdc8d8SChris Lattner                     return ::strlen (stop_desc) + 1; // Include the NULL byte for size
23930fdc8d8SChris Lattner                 }
24030fdc8d8SChris Lattner             }
24130fdc8d8SChris Lattner             else
24230fdc8d8SChris Lattner             {
24330fdc8d8SChris Lattner                 size_t stop_desc_len = 0;
244b15bfc75SJim Ingham                 switch (stop_info_sp->GetStopReason())
24530fdc8d8SChris Lattner                 {
24630fdc8d8SChris Lattner                 case eStopReasonTrace:
24730fdc8d8SChris Lattner                 case eStopReasonPlanComplete:
24830fdc8d8SChris Lattner                     {
24930fdc8d8SChris Lattner                         static char trace_desc[] = "step";
25030fdc8d8SChris Lattner                         stop_desc = trace_desc;
25130fdc8d8SChris Lattner                         stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
25230fdc8d8SChris Lattner                     }
25330fdc8d8SChris Lattner                     break;
25430fdc8d8SChris Lattner 
25530fdc8d8SChris Lattner                 case eStopReasonBreakpoint:
25630fdc8d8SChris Lattner                     {
25730fdc8d8SChris Lattner                         static char bp_desc[] = "breakpoint hit";
25830fdc8d8SChris Lattner                         stop_desc = bp_desc;
25930fdc8d8SChris Lattner                         stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
26030fdc8d8SChris Lattner                     }
26130fdc8d8SChris Lattner                     break;
26230fdc8d8SChris Lattner 
26330fdc8d8SChris Lattner                 case eStopReasonWatchpoint:
26430fdc8d8SChris Lattner                     {
26530fdc8d8SChris Lattner                         static char wp_desc[] = "watchpoint hit";
26630fdc8d8SChris Lattner                         stop_desc = wp_desc;
26730fdc8d8SChris Lattner                         stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
26830fdc8d8SChris Lattner                     }
26930fdc8d8SChris Lattner                     break;
27030fdc8d8SChris Lattner 
27130fdc8d8SChris Lattner                 case eStopReasonSignal:
27230fdc8d8SChris Lattner                     {
273b15bfc75SJim Ingham                         stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
27430fdc8d8SChris Lattner                         if (stop_desc == NULL || stop_desc[0] == '\0')
27530fdc8d8SChris Lattner                         {
27630fdc8d8SChris Lattner                             static char signal_desc[] = "signal";
27730fdc8d8SChris Lattner                             stop_desc = signal_desc;
27830fdc8d8SChris Lattner                             stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
27930fdc8d8SChris Lattner                         }
28030fdc8d8SChris Lattner                     }
28130fdc8d8SChris Lattner                     break;
28230fdc8d8SChris Lattner 
28330fdc8d8SChris Lattner                 case eStopReasonException:
28430fdc8d8SChris Lattner                     {
28530fdc8d8SChris Lattner                         char exc_desc[] = "exception";
28630fdc8d8SChris Lattner                         stop_desc = exc_desc;
28730fdc8d8SChris Lattner                         stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
28830fdc8d8SChris Lattner                     }
28930fdc8d8SChris Lattner                     break;
290c982c768SGreg Clayton 
291c982c768SGreg Clayton                 default:
292c982c768SGreg Clayton                     break;
29330fdc8d8SChris Lattner                 }
29430fdc8d8SChris Lattner 
29530fdc8d8SChris Lattner                 if (stop_desc && stop_desc[0])
29630fdc8d8SChris Lattner                 {
297ceb6b139SCaroline Tice                     if (log)
29893aa84e8SGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
299750cd175SCaroline Tice                                      m_opaque_sp.get(), stop_desc);
300ceb6b139SCaroline Tice 
30130fdc8d8SChris Lattner                     if (dst)
30230fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
30330fdc8d8SChris Lattner 
30430fdc8d8SChris Lattner                     if (stop_desc_len == 0)
30530fdc8d8SChris Lattner                         stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
30630fdc8d8SChris Lattner 
30730fdc8d8SChris Lattner                     return stop_desc_len;
30830fdc8d8SChris Lattner                 }
30930fdc8d8SChris Lattner             }
31030fdc8d8SChris Lattner         }
31130fdc8d8SChris Lattner     }
31230fdc8d8SChris Lattner     if (dst)
31330fdc8d8SChris Lattner         *dst = 0;
31430fdc8d8SChris Lattner     return 0;
31530fdc8d8SChris Lattner }
31630fdc8d8SChris Lattner 
31773ca05a2SJim Ingham SBValue
31873ca05a2SJim Ingham SBThread::GetStopReturnValue ()
31973ca05a2SJim Ingham {
32073ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
32173ca05a2SJim Ingham     if (m_opaque_sp)
32273ca05a2SJim Ingham     {
32373ca05a2SJim Ingham         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
32473ca05a2SJim Ingham         StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo ();
32573ca05a2SJim Ingham         if (stop_info_sp)
32673ca05a2SJim Ingham         {
32773ca05a2SJim Ingham             return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
32873ca05a2SJim Ingham         }
32973ca05a2SJim Ingham     }
33073ca05a2SJim Ingham 
33173ca05a2SJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
33273ca05a2SJim Ingham     if (log)
33373ca05a2SJim Ingham         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", m_opaque_sp.get(),
33473ca05a2SJim Ingham                                                                   return_valobj_sp.get()
33573ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
33673ca05a2SJim Ingham                                                                         : "<no return value>");
33773ca05a2SJim Ingham 
33873ca05a2SJim Ingham     return SBValue (return_valobj_sp);
33973ca05a2SJim Ingham }
34073ca05a2SJim Ingham 
34130fdc8d8SChris Lattner void
34230fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
34330fdc8d8SChris Lattner {
3446611103cSGreg Clayton     m_opaque_sp = lldb_object_sp;
34530fdc8d8SChris Lattner }
34630fdc8d8SChris Lattner 
34730fdc8d8SChris Lattner 
34830fdc8d8SChris Lattner lldb::tid_t
34930fdc8d8SChris Lattner SBThread::GetThreadID () const
35030fdc8d8SChris Lattner {
3512d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
352ceb6b139SCaroline Tice 
353af67cecdSGreg Clayton     lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
3546611103cSGreg Clayton     if (m_opaque_sp)
355af67cecdSGreg Clayton         tid = m_opaque_sp->GetID();
356ceb6b139SCaroline Tice 
357ceb6b139SCaroline Tice     if (log)
35861e7a58cSGreg Clayton         log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", m_opaque_sp.get(), tid);
359ceb6b139SCaroline Tice 
360af67cecdSGreg Clayton     return tid;
36130fdc8d8SChris Lattner }
36230fdc8d8SChris Lattner 
36330fdc8d8SChris Lattner uint32_t
36430fdc8d8SChris Lattner SBThread::GetIndexID () const
36530fdc8d8SChris Lattner {
3666611103cSGreg Clayton     if (m_opaque_sp)
3676611103cSGreg Clayton         return m_opaque_sp->GetIndexID();
36830fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
36930fdc8d8SChris Lattner }
37030fdc8d8SChris Lattner const char *
37130fdc8d8SChris Lattner SBThread::GetName () const
37230fdc8d8SChris Lattner {
3734838131bSGreg Clayton     const char *name = NULL;
3746611103cSGreg Clayton     if (m_opaque_sp)
375af67cecdSGreg Clayton     {
376af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
3774838131bSGreg Clayton         name = m_opaque_sp->GetName();
378af67cecdSGreg Clayton     }
379ceb6b139SCaroline Tice 
3802d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
381ceb6b139SCaroline Tice     if (log)
3824838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", m_opaque_sp.get(), name ? name : "NULL");
383ceb6b139SCaroline Tice 
3844838131bSGreg Clayton     return name;
38530fdc8d8SChris Lattner }
38630fdc8d8SChris Lattner 
38730fdc8d8SChris Lattner const char *
38830fdc8d8SChris Lattner SBThread::GetQueueName () const
38930fdc8d8SChris Lattner {
3904838131bSGreg Clayton     const char *name = NULL;
3916611103cSGreg Clayton     if (m_opaque_sp)
392af67cecdSGreg Clayton     {
393af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
3944838131bSGreg Clayton         name = m_opaque_sp->GetQueueName();
395af67cecdSGreg Clayton     }
396ceb6b139SCaroline Tice 
3972d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
398ceb6b139SCaroline Tice     if (log)
3994838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", m_opaque_sp.get(), name ? name : "NULL");
400ceb6b139SCaroline Tice 
4014838131bSGreg Clayton     return name;
40230fdc8d8SChris Lattner }
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner 
40530fdc8d8SChris Lattner void
40630fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
40730fdc8d8SChris Lattner {
4082d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
409ceb6b139SCaroline Tice 
410ceb6b139SCaroline Tice     if (log)
41193aa84e8SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", m_opaque_sp.get(),
412ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
413ceb6b139SCaroline Tice 
4146611103cSGreg Clayton     if (m_opaque_sp)
41530fdc8d8SChris Lattner     {
416af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
41730fdc8d8SChris Lattner         bool abort_other_plans = true;
4186611103cSGreg Clayton         StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
41930fdc8d8SChris Lattner 
42030fdc8d8SChris Lattner         if (frame_sp)
42130fdc8d8SChris Lattner         {
42230fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
42330fdc8d8SChris Lattner             {
42430fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
4256611103cSGreg Clayton                 m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
42630fdc8d8SChris Lattner                                                           eStepTypeOver,
42730fdc8d8SChris Lattner                                                           sc.line_entry.range,
42830fdc8d8SChris Lattner                                                           sc,
429474966a4SGreg Clayton                                                           stop_other_threads,
430474966a4SGreg Clayton                                                           false);
43130fdc8d8SChris Lattner 
43230fdc8d8SChris Lattner             }
43330fdc8d8SChris Lattner             else
43430fdc8d8SChris Lattner             {
4356611103cSGreg Clayton                 m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true,
43630fdc8d8SChris Lattner                                                                       abort_other_plans,
43730fdc8d8SChris Lattner                                                                       stop_other_threads);
43830fdc8d8SChris Lattner             }
43930fdc8d8SChris Lattner         }
44030fdc8d8SChris Lattner 
4416611103cSGreg Clayton         Process &process = m_opaque_sp->GetProcess();
44230fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
4432976d00aSJim Ingham         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
4445d5028b5SGreg Clayton         Error error (process.Resume());
4455d5028b5SGreg Clayton         if (error.Success())
4465d5028b5SGreg Clayton         {
4475d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
4485d5028b5SGreg Clayton             // process to stop yet again!
4495d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
4505d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
4515d5028b5SGreg Clayton         }
45230fdc8d8SChris Lattner     }
45330fdc8d8SChris Lattner }
45430fdc8d8SChris Lattner 
45530fdc8d8SChris Lattner void
45630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
45730fdc8d8SChris Lattner {
4582d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
459ceb6b139SCaroline Tice 
460ceb6b139SCaroline Tice     if (log)
46193aa84e8SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", m_opaque_sp.get(),
462ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
463ceb6b139SCaroline Tice 
4646611103cSGreg Clayton     if (m_opaque_sp)
46530fdc8d8SChris Lattner     {
466af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
46730fdc8d8SChris Lattner         bool abort_other_plans = true;
46830fdc8d8SChris Lattner 
4696611103cSGreg Clayton         StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0));
47030fdc8d8SChris Lattner 
47130fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
47230fdc8d8SChris Lattner         {
473474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
47430fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
4756611103cSGreg Clayton             m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans,
47630fdc8d8SChris Lattner                                                       eStepTypeInto,
47730fdc8d8SChris Lattner                                                       sc.line_entry.range,
47830fdc8d8SChris Lattner                                                       sc,
479474966a4SGreg Clayton                                                       stop_other_threads,
480474966a4SGreg Clayton                                                       avoid_code_without_debug_info);
48130fdc8d8SChris Lattner         }
48230fdc8d8SChris Lattner         else
48330fdc8d8SChris Lattner         {
4846611103cSGreg Clayton             m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false,
48530fdc8d8SChris Lattner                                                                   abort_other_plans,
48630fdc8d8SChris Lattner                                                                   stop_other_threads);
48730fdc8d8SChris Lattner         }
48830fdc8d8SChris Lattner 
4896611103cSGreg Clayton         Process &process = m_opaque_sp->GetProcess();
49030fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
4912976d00aSJim Ingham         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
4925d5028b5SGreg Clayton         Error error (process.Resume());
4935d5028b5SGreg Clayton         if (error.Success())
4945d5028b5SGreg Clayton         {
4955d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
4965d5028b5SGreg Clayton             // process to stop yet again!
4975d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
4985d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
4995d5028b5SGreg Clayton         }
50030fdc8d8SChris Lattner     }
50130fdc8d8SChris Lattner }
50230fdc8d8SChris Lattner 
50330fdc8d8SChris Lattner void
50430fdc8d8SChris Lattner SBThread::StepOut ()
50530fdc8d8SChris Lattner {
5062d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
507ceb6b139SCaroline Tice 
508ceb6b139SCaroline Tice     if (log)
5094838131bSGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", m_opaque_sp.get());
510ceb6b139SCaroline Tice 
5116611103cSGreg Clayton     if (m_opaque_sp)
51230fdc8d8SChris Lattner     {
513af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
51430fdc8d8SChris Lattner         bool abort_other_plans = true;
51530fdc8d8SChris Lattner         bool stop_other_threads = true;
51630fdc8d8SChris Lattner 
517481cef25SGreg Clayton         m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans,
518481cef25SGreg Clayton                                                 NULL,
519481cef25SGreg Clayton                                                 false,
520481cef25SGreg Clayton                                                 stop_other_threads,
521481cef25SGreg Clayton                                                 eVoteYes,
522481cef25SGreg Clayton                                                 eVoteNoOpinion,
523481cef25SGreg Clayton                                                 0);
524481cef25SGreg Clayton 
525481cef25SGreg Clayton         Process &process = m_opaque_sp->GetProcess();
526481cef25SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
527481cef25SGreg Clayton         Error error (process.Resume());
528481cef25SGreg Clayton         if (error.Success())
529481cef25SGreg Clayton         {
530481cef25SGreg Clayton             // If we are doing synchronous mode, then wait for the
531481cef25SGreg Clayton             // process to stop yet again!
532481cef25SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
533481cef25SGreg Clayton                 process.WaitForProcessToStop (NULL);
534481cef25SGreg Clayton         }
535481cef25SGreg Clayton     }
536481cef25SGreg Clayton }
537481cef25SGreg Clayton 
538481cef25SGreg Clayton void
539481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
540481cef25SGreg Clayton {
541481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
542481cef25SGreg Clayton 
543481cef25SGreg Clayton     if (log)
544481cef25SGreg Clayton     {
545481cef25SGreg Clayton         SBStream frame_desc_strm;
546481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
547481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
548481cef25SGreg Clayton     }
549481cef25SGreg Clayton 
550481cef25SGreg Clayton     if (m_opaque_sp)
551481cef25SGreg Clayton     {
552481cef25SGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
553481cef25SGreg Clayton         bool abort_other_plans = true;
554481cef25SGreg Clayton         bool stop_other_threads = true;
555481cef25SGreg Clayton 
556481cef25SGreg Clayton         m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans,
557481cef25SGreg Clayton                                                 NULL,
558481cef25SGreg Clayton                                                 false,
559481cef25SGreg Clayton                                                 stop_other_threads,
560481cef25SGreg Clayton                                                 eVoteYes,
561481cef25SGreg Clayton                                                 eVoteNoOpinion,
562481cef25SGreg Clayton                                                 sb_frame->GetFrameIndex());
56330fdc8d8SChris Lattner 
5646611103cSGreg Clayton         Process &process = m_opaque_sp->GetProcess();
5652976d00aSJim Ingham         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
5665d5028b5SGreg Clayton         Error error (process.Resume());
5675d5028b5SGreg Clayton         if (error.Success())
5685d5028b5SGreg Clayton         {
5695d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5705d5028b5SGreg Clayton             // process to stop yet again!
5715d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
5725d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
5735d5028b5SGreg Clayton         }
57430fdc8d8SChris Lattner     }
57530fdc8d8SChris Lattner }
57630fdc8d8SChris Lattner 
57730fdc8d8SChris Lattner void
57830fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
57930fdc8d8SChris Lattner {
5802d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
581ceb6b139SCaroline Tice 
582ceb6b139SCaroline Tice     if (log)
58393aa84e8SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", m_opaque_sp.get(), step_over);
584ceb6b139SCaroline Tice 
5856611103cSGreg Clayton     if (m_opaque_sp)
58630fdc8d8SChris Lattner     {
587af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
5886611103cSGreg Clayton         m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
5896611103cSGreg Clayton         Process &process = m_opaque_sp->GetProcess();
5902976d00aSJim Ingham         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
5915d5028b5SGreg Clayton         Error error (process.Resume());
5925d5028b5SGreg Clayton         if (error.Success())
5935d5028b5SGreg Clayton         {
5945d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5955d5028b5SGreg Clayton             // process to stop yet again!
5965d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
5975d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
5985d5028b5SGreg Clayton         }
59930fdc8d8SChris Lattner     }
60030fdc8d8SChris Lattner }
60130fdc8d8SChris Lattner 
60230fdc8d8SChris Lattner void
60330fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
60430fdc8d8SChris Lattner {
6052d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
606ceb6b139SCaroline Tice 
607ceb6b139SCaroline Tice     if (log)
60893aa84e8SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", m_opaque_sp.get(), addr);
609ceb6b139SCaroline Tice 
6106611103cSGreg Clayton     if (m_opaque_sp)
61130fdc8d8SChris Lattner     {
61230fdc8d8SChris Lattner         bool abort_other_plans = true;
61330fdc8d8SChris Lattner         bool stop_other_threads = true;
61430fdc8d8SChris Lattner 
61530fdc8d8SChris Lattner         Address target_addr (NULL, addr);
61630fdc8d8SChris Lattner 
6176611103cSGreg Clayton         m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
6186611103cSGreg Clayton         Process &process = m_opaque_sp->GetProcess();
6192976d00aSJim Ingham         process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
6205d5028b5SGreg Clayton         Error error (process.Resume());
6215d5028b5SGreg Clayton         if (error.Success())
6225d5028b5SGreg Clayton         {
6235d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6245d5028b5SGreg Clayton             // process to stop yet again!
6255d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
6265d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
6275d5028b5SGreg Clayton         }
62830fdc8d8SChris Lattner     }
62930fdc8d8SChris Lattner }
63030fdc8d8SChris Lattner 
631481cef25SGreg Clayton SBError
632481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
633481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
634481cef25SGreg Clayton                          uint32_t line)
635481cef25SGreg Clayton {
636481cef25SGreg Clayton     SBError sb_error;
637481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
638481cef25SGreg Clayton     char path[PATH_MAX];
639481cef25SGreg Clayton 
640481cef25SGreg Clayton     if (log)
641481cef25SGreg Clayton     {
642481cef25SGreg Clayton         SBStream frame_desc_strm;
643481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
644481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
645481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
646481cef25SGreg Clayton                      m_opaque_sp.get(),
647481cef25SGreg Clayton                      sb_frame.get(),
648481cef25SGreg Clayton                      frame_desc_strm.GetData(),
649481cef25SGreg Clayton                      path, line);
650481cef25SGreg Clayton     }
651481cef25SGreg Clayton 
652481cef25SGreg Clayton     if (m_opaque_sp)
653481cef25SGreg Clayton     {
654481cef25SGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
655481cef25SGreg Clayton 
656481cef25SGreg Clayton         if (line == 0)
657481cef25SGreg Clayton         {
658481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
659481cef25SGreg Clayton             return sb_error;
660481cef25SGreg Clayton         }
661481cef25SGreg Clayton 
662481cef25SGreg Clayton         StackFrameSP frame_sp;
663481cef25SGreg Clayton         if (sb_frame.IsValid())
664481cef25SGreg Clayton             frame_sp = sb_frame.get_sp();
665481cef25SGreg Clayton         else
666481cef25SGreg Clayton         {
667481cef25SGreg Clayton             frame_sp = m_opaque_sp->GetSelectedFrame ();
668481cef25SGreg Clayton             if (!frame_sp)
669481cef25SGreg Clayton                 frame_sp = m_opaque_sp->GetStackFrameAtIndex (0);
670481cef25SGreg Clayton         }
671481cef25SGreg Clayton 
672481cef25SGreg Clayton         SymbolContext frame_sc;
673481cef25SGreg Clayton         if (!frame_sp)
674481cef25SGreg Clayton         {
675481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
676481cef25SGreg Clayton             return sb_error;
677481cef25SGreg Clayton         }
678481cef25SGreg Clayton 
679481cef25SGreg Clayton         // If we have a frame, get its line
680481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
681481cef25SGreg Clayton                                                eSymbolContextFunction  |
682481cef25SGreg Clayton                                                eSymbolContextLineEntry |
683481cef25SGreg Clayton                                                eSymbolContextSymbol    );
684481cef25SGreg Clayton 
685481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
686481cef25SGreg Clayton         {
687481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
688481cef25SGreg Clayton             return sb_error;
689481cef25SGreg Clayton         }
690481cef25SGreg Clayton 
691481cef25SGreg Clayton         FileSpec step_file_spec;
692481cef25SGreg Clayton         if (sb_file_spec.IsValid())
693481cef25SGreg Clayton         {
694481cef25SGreg Clayton             // The file spec passed in was valid, so use it
695481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
696481cef25SGreg Clayton         }
697481cef25SGreg Clayton         else
698481cef25SGreg Clayton         {
699481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
700481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
701481cef25SGreg Clayton             else
702481cef25SGreg Clayton             {
703481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
704481cef25SGreg Clayton                 return sb_error;
705481cef25SGreg Clayton             }
706481cef25SGreg Clayton         }
707481cef25SGreg Clayton 
7089b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
7099b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
7109b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
7119b70ddb3SJim Ingham         // error message.
7129b70ddb3SJim Ingham 
7139b70ddb3SJim Ingham         bool all_in_function = true;
7149b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
7159b70ddb3SJim Ingham 
716481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
717481cef25SGreg Clayton         const bool abort_other_plans = true;
718481cef25SGreg Clayton         const bool stop_other_threads = true;
719481cef25SGreg Clayton         const bool check_inlines = true;
720481cef25SGreg Clayton         const bool exact = false;
7219b70ddb3SJim Ingham         Target *target = &m_opaque_sp->GetProcess().GetTarget();
722481cef25SGreg Clayton 
723481cef25SGreg Clayton         SymbolContextList sc_list;
7249b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
7259b70ddb3SJim Ingham                                                                                line,
7269b70ddb3SJim Ingham                                                                                check_inlines,
7279b70ddb3SJim Ingham                                                                                exact,
7289b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
7299b70ddb3SJim Ingham                                                                                sc_list);
730481cef25SGreg Clayton         if (num_matches > 0)
731481cef25SGreg Clayton         {
732481cef25SGreg Clayton             SymbolContext sc;
733481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
734481cef25SGreg Clayton             {
735481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
736481cef25SGreg Clayton                 {
7379b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
738481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
739481cef25SGreg Clayton                     {
7409b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
741481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
7429b70ddb3SJim Ingham                         else
7439b70ddb3SJim Ingham                             all_in_function = false;
744481cef25SGreg Clayton                     }
745481cef25SGreg Clayton                 }
746481cef25SGreg Clayton             }
747481cef25SGreg Clayton         }
748481cef25SGreg Clayton 
749481cef25SGreg Clayton         if (step_over_until_addrs.empty())
750481cef25SGreg Clayton         {
7519b70ddb3SJim Ingham             if (all_in_function)
7529b70ddb3SJim Ingham             {
753481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
754fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
755481cef25SGreg Clayton             }
756481cef25SGreg Clayton             else
75786edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
7589b70ddb3SJim Ingham         }
7599b70ddb3SJim Ingham         else
760481cef25SGreg Clayton         {
761481cef25SGreg Clayton             m_opaque_sp->QueueThreadPlanForStepUntil (abort_other_plans,
762481cef25SGreg Clayton                                                       &step_over_until_addrs[0],
763481cef25SGreg Clayton                                                       step_over_until_addrs.size(),
764481cef25SGreg Clayton                                                       stop_other_threads,
765481cef25SGreg Clayton                                                       frame_sp->GetFrameIndex());
766481cef25SGreg Clayton 
767481cef25SGreg Clayton             m_opaque_sp->GetProcess().GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID());
768481cef25SGreg Clayton             sb_error.ref() = m_opaque_sp->GetProcess().Resume();
769481cef25SGreg Clayton             if (sb_error->Success())
770481cef25SGreg Clayton             {
771481cef25SGreg Clayton                 // If we are doing synchronous mode, then wait for the
772481cef25SGreg Clayton                 // process to stop yet again!
773481cef25SGreg Clayton                 if (m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
774481cef25SGreg Clayton                     m_opaque_sp->GetProcess().WaitForProcessToStop (NULL);
775481cef25SGreg Clayton             }
776481cef25SGreg Clayton         }
777481cef25SGreg Clayton     }
778481cef25SGreg Clayton     else
779481cef25SGreg Clayton     {
780481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
781481cef25SGreg Clayton     }
782481cef25SGreg Clayton     return sb_error;
783481cef25SGreg Clayton }
784481cef25SGreg Clayton 
785481cef25SGreg Clayton 
786722a0cdcSGreg Clayton bool
787722a0cdcSGreg Clayton SBThread::Suspend()
788722a0cdcSGreg Clayton {
789722a0cdcSGreg Clayton     if (m_opaque_sp)
790722a0cdcSGreg Clayton     {
791722a0cdcSGreg Clayton         m_opaque_sp->SetResumeState (eStateSuspended);
792722a0cdcSGreg Clayton         return true;
793722a0cdcSGreg Clayton     }
794722a0cdcSGreg Clayton     return false;
795722a0cdcSGreg Clayton }
796722a0cdcSGreg Clayton 
797722a0cdcSGreg Clayton bool
798722a0cdcSGreg Clayton SBThread::Resume ()
799722a0cdcSGreg Clayton {
800722a0cdcSGreg Clayton     if (m_opaque_sp)
801722a0cdcSGreg Clayton     {
802722a0cdcSGreg Clayton         m_opaque_sp->SetResumeState (eStateRunning);
803722a0cdcSGreg Clayton         return true;
804722a0cdcSGreg Clayton     }
805722a0cdcSGreg Clayton     return false;
806722a0cdcSGreg Clayton }
807722a0cdcSGreg Clayton 
808722a0cdcSGreg Clayton bool
809722a0cdcSGreg Clayton SBThread::IsSuspended()
810722a0cdcSGreg Clayton {
811722a0cdcSGreg Clayton     if (m_opaque_sp)
8129566143fSGreg Clayton         return m_opaque_sp->GetResumeState () == eStateSuspended;
813722a0cdcSGreg Clayton     return false;
814722a0cdcSGreg Clayton }
815722a0cdcSGreg Clayton 
81630fdc8d8SChris Lattner SBProcess
81730fdc8d8SChris Lattner SBThread::GetProcess ()
81830fdc8d8SChris Lattner {
819ceb6b139SCaroline Tice 
82030fdc8d8SChris Lattner     SBProcess process;
8216611103cSGreg Clayton     if (m_opaque_sp)
82230fdc8d8SChris Lattner     {
82330fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
8246611103cSGreg Clayton         process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP());
82530fdc8d8SChris Lattner     }
826ceb6b139SCaroline Tice 
8272d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
828ceb6b139SCaroline Tice     if (log)
829ceb6b139SCaroline Tice     {
830481cef25SGreg Clayton         SBStream frame_desc_strm;
831481cef25SGreg Clayton         process.GetDescription (frame_desc_strm);
8324838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(),
833481cef25SGreg Clayton                      process.get(), frame_desc_strm.GetData());
834ceb6b139SCaroline Tice     }
835ceb6b139SCaroline Tice 
83630fdc8d8SChris Lattner     return process;
83730fdc8d8SChris Lattner }
83830fdc8d8SChris Lattner 
83930fdc8d8SChris Lattner uint32_t
84030fdc8d8SChris Lattner SBThread::GetNumFrames ()
84130fdc8d8SChris Lattner {
8422d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
843ceb6b139SCaroline Tice 
844ceb6b139SCaroline Tice     uint32_t num_frames = 0;
8456611103cSGreg Clayton     if (m_opaque_sp)
846af67cecdSGreg Clayton     {
847af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
848ceb6b139SCaroline Tice         num_frames = m_opaque_sp->GetStackFrameCount();
849af67cecdSGreg Clayton     }
850ceb6b139SCaroline Tice 
851ceb6b139SCaroline Tice     if (log)
8524838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", m_opaque_sp.get(), num_frames);
853ceb6b139SCaroline Tice 
854ceb6b139SCaroline Tice     return num_frames;
85530fdc8d8SChris Lattner }
85630fdc8d8SChris Lattner 
85730fdc8d8SChris Lattner SBFrame
85830fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
85930fdc8d8SChris Lattner {
8602d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
861ceb6b139SCaroline Tice 
86230fdc8d8SChris Lattner     SBFrame sb_frame;
8636611103cSGreg Clayton     if (m_opaque_sp)
864af67cecdSGreg Clayton     {
865af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
8666611103cSGreg Clayton         sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx));
867af67cecdSGreg Clayton     }
868ceb6b139SCaroline Tice 
869ceb6b139SCaroline Tice     if (log)
870ceb6b139SCaroline Tice     {
871481cef25SGreg Clayton         SBStream frame_desc_strm;
872481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
8734838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
874481cef25SGreg Clayton                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
875ceb6b139SCaroline Tice     }
876ceb6b139SCaroline Tice 
87730fdc8d8SChris Lattner     return sb_frame;
87830fdc8d8SChris Lattner }
87930fdc8d8SChris Lattner 
880f028a1fbSGreg Clayton lldb::SBFrame
881f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
882f028a1fbSGreg Clayton {
883f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
884f028a1fbSGreg Clayton 
885f028a1fbSGreg Clayton     SBFrame sb_frame;
886f028a1fbSGreg Clayton     if (m_opaque_sp)
887af67cecdSGreg Clayton     {
888af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
889f028a1fbSGreg Clayton         sb_frame.SetFrame (m_opaque_sp->GetSelectedFrame ());
890af67cecdSGreg Clayton     }
891f028a1fbSGreg Clayton 
892f028a1fbSGreg Clayton     if (log)
893f028a1fbSGreg Clayton     {
894481cef25SGreg Clayton         SBStream frame_desc_strm;
895481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
896f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
897481cef25SGreg Clayton                      m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData());
898f028a1fbSGreg Clayton     }
899f028a1fbSGreg Clayton 
900f028a1fbSGreg Clayton     return sb_frame;
901f028a1fbSGreg Clayton }
902f028a1fbSGreg Clayton 
903f028a1fbSGreg Clayton lldb::SBFrame
904f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
905f028a1fbSGreg Clayton {
906f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
907f028a1fbSGreg Clayton 
908f028a1fbSGreg Clayton     SBFrame sb_frame;
909f028a1fbSGreg Clayton     if (m_opaque_sp)
910f028a1fbSGreg Clayton     {
911af67cecdSGreg Clayton         Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex());
912f028a1fbSGreg Clayton         lldb::StackFrameSP frame_sp (m_opaque_sp->GetStackFrameAtIndex (idx));
913f028a1fbSGreg Clayton         if (frame_sp)
914f028a1fbSGreg Clayton         {
915f028a1fbSGreg Clayton             m_opaque_sp->SetSelectedFrame (frame_sp.get());
916f028a1fbSGreg Clayton             sb_frame.SetFrame (frame_sp);
917f028a1fbSGreg Clayton         }
918f028a1fbSGreg Clayton     }
919f028a1fbSGreg Clayton 
920f028a1fbSGreg Clayton     if (log)
921f028a1fbSGreg Clayton     {
922481cef25SGreg Clayton         SBStream frame_desc_strm;
923481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
924f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
925481cef25SGreg Clayton                      m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData());
926f028a1fbSGreg Clayton     }
927f028a1fbSGreg Clayton     return sb_frame;
928f028a1fbSGreg Clayton }
929f028a1fbSGreg Clayton 
930f028a1fbSGreg Clayton 
93130fdc8d8SChris Lattner bool
93230fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
93330fdc8d8SChris Lattner {
9346611103cSGreg Clayton     return m_opaque_sp.get() == rhs.m_opaque_sp.get();
93530fdc8d8SChris Lattner }
93630fdc8d8SChris Lattner 
93730fdc8d8SChris Lattner bool
93830fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
93930fdc8d8SChris Lattner {
9406611103cSGreg Clayton     return m_opaque_sp.get() != rhs.m_opaque_sp.get();
94130fdc8d8SChris Lattner }
94230fdc8d8SChris Lattner 
94330fdc8d8SChris Lattner lldb_private::Thread *
9444838131bSGreg Clayton SBThread::get ()
94530fdc8d8SChris Lattner {
9466611103cSGreg Clayton     return m_opaque_sp.get();
94730fdc8d8SChris Lattner }
94830fdc8d8SChris Lattner 
94930fdc8d8SChris Lattner const lldb_private::Thread *
95030fdc8d8SChris Lattner SBThread::operator->() const
95130fdc8d8SChris Lattner {
9526611103cSGreg Clayton     return m_opaque_sp.get();
95330fdc8d8SChris Lattner }
95430fdc8d8SChris Lattner 
95530fdc8d8SChris Lattner const lldb_private::Thread &
95630fdc8d8SChris Lattner SBThread::operator*() const
95730fdc8d8SChris Lattner {
9586611103cSGreg Clayton     return *m_opaque_sp;
95930fdc8d8SChris Lattner }
96030fdc8d8SChris Lattner 
96130fdc8d8SChris Lattner lldb_private::Thread *
96230fdc8d8SChris Lattner SBThread::operator->()
96330fdc8d8SChris Lattner {
9646611103cSGreg Clayton     return m_opaque_sp.get();
96530fdc8d8SChris Lattner }
96630fdc8d8SChris Lattner 
96730fdc8d8SChris Lattner lldb_private::Thread &
96830fdc8d8SChris Lattner SBThread::operator*()
96930fdc8d8SChris Lattner {
9706611103cSGreg Clayton     return *m_opaque_sp;
97130fdc8d8SChris Lattner }
972dde9cff3SCaroline Tice 
973dde9cff3SCaroline Tice bool
974ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
975ceb6b139SCaroline Tice {
976da7bc7d0SGreg Clayton     Stream &strm = description.ref();
977da7bc7d0SGreg Clayton 
978ceb6b139SCaroline Tice     if (m_opaque_sp)
979ceb6b139SCaroline Tice     {
980da7bc7d0SGreg Clayton         strm.Printf("SBThread: tid = 0x%4.4llx", m_opaque_sp->GetID());
981ceb6b139SCaroline Tice     }
982ceb6b139SCaroline Tice     else
983da7bc7d0SGreg Clayton         strm.PutCString ("No value");
984ceb6b139SCaroline Tice 
985ceb6b139SCaroline Tice     return true;
986ceb6b139SCaroline Tice }
987