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 () :
4617a6ad05SGreg Clayton     m_opaque_wp ()
4730fdc8d8SChris Lattner {
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner 
5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) :
5117a6ad05SGreg Clayton     m_opaque_wp (lldb_object_sp)
5230fdc8d8SChris Lattner {
5330fdc8d8SChris Lattner }
5430fdc8d8SChris Lattner 
5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) :
5617a6ad05SGreg Clayton     m_opaque_wp (rhs.m_opaque_wp)
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)
6817a6ad05SGreg Clayton         m_opaque_wp = rhs.m_opaque_wp;
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 {
8217a6ad05SGreg Clayton     return !m_opaque_wp.expired();
8330fdc8d8SChris Lattner }
8430fdc8d8SChris Lattner 
8548e42549SGreg Clayton void
8648e42549SGreg Clayton SBThread::Clear ()
8748e42549SGreg Clayton {
8817a6ad05SGreg Clayton     m_opaque_wp.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;
981ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
991ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
10030fdc8d8SChris Lattner     {
1011ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1021ac04c30SGreg Clayton         StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
103b15bfc75SJim Ingham         if (stop_info_sp)
104ceb6b139SCaroline Tice             reason =  stop_info_sp->GetStopReason();
10530fdc8d8SChris Lattner     }
106ceb6b139SCaroline Tice 
107ceb6b139SCaroline Tice     if (log)
1081ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
109750cd175SCaroline Tice                      Thread::StopReasonAsCString (reason));
110ceb6b139SCaroline Tice 
111ceb6b139SCaroline Tice     return reason;
11230fdc8d8SChris Lattner }
11330fdc8d8SChris Lattner 
11430fdc8d8SChris Lattner size_t
1154e78f606SGreg Clayton SBThread::GetStopReasonDataCount ()
1164e78f606SGreg Clayton {
1171ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
1181ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1194e78f606SGreg Clayton     {
1201ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1211ac04c30SGreg Clayton         StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
1224e78f606SGreg Clayton         if (stop_info_sp)
1234e78f606SGreg Clayton         {
1244e78f606SGreg Clayton             StopReason reason = stop_info_sp->GetStopReason();
1254e78f606SGreg Clayton             switch (reason)
1264e78f606SGreg Clayton             {
1274e78f606SGreg Clayton             case eStopReasonInvalid:
1284e78f606SGreg Clayton             case eStopReasonNone:
1294e78f606SGreg Clayton             case eStopReasonTrace:
1304e78f606SGreg Clayton             case eStopReasonPlanComplete:
1314e78f606SGreg Clayton                 // There is no data for these stop reasons.
1324e78f606SGreg Clayton                 return 0;
1334e78f606SGreg Clayton 
1344e78f606SGreg Clayton             case eStopReasonBreakpoint:
1354e78f606SGreg Clayton                 {
1364e78f606SGreg Clayton                     break_id_t site_id = stop_info_sp->GetValue();
1371ac04c30SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1384e78f606SGreg Clayton                     if (bp_site_sp)
1394e78f606SGreg Clayton                         return bp_site_sp->GetNumberOfOwners () * 2;
1404e78f606SGreg Clayton                     else
1414e78f606SGreg Clayton                         return 0; // Breakpoint must have cleared itself...
1424e78f606SGreg Clayton                 }
1434e78f606SGreg Clayton                 break;
1444e78f606SGreg Clayton 
1454e78f606SGreg Clayton             case eStopReasonWatchpoint:
146290fa41bSJohnny Chen                 return 1;
1474e78f606SGreg Clayton 
1484e78f606SGreg Clayton             case eStopReasonSignal:
1494e78f606SGreg Clayton                 return 1;
1504e78f606SGreg Clayton 
1514e78f606SGreg Clayton             case eStopReasonException:
1524e78f606SGreg Clayton                 return 1;
1534e78f606SGreg Clayton             }
1544e78f606SGreg Clayton         }
1554e78f606SGreg Clayton     }
1564e78f606SGreg Clayton     return 0;
1574e78f606SGreg Clayton }
1584e78f606SGreg Clayton 
1594e78f606SGreg Clayton uint64_t
1604e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx)
1614e78f606SGreg Clayton {
1621ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
1631ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1644e78f606SGreg Clayton     {
1651ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
1661ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
1671ac04c30SGreg Clayton         StopInfoSP stop_info_sp = thread->GetStopInfo ();
1684e78f606SGreg Clayton         if (stop_info_sp)
1694e78f606SGreg Clayton         {
1704e78f606SGreg Clayton             StopReason reason = stop_info_sp->GetStopReason();
1714e78f606SGreg Clayton             switch (reason)
1724e78f606SGreg Clayton             {
1734e78f606SGreg Clayton             case eStopReasonInvalid:
1744e78f606SGreg Clayton             case eStopReasonNone:
1754e78f606SGreg Clayton             case eStopReasonTrace:
1764e78f606SGreg Clayton             case eStopReasonPlanComplete:
1774e78f606SGreg Clayton                 // There is no data for these stop reasons.
1784e78f606SGreg Clayton                 return 0;
1794e78f606SGreg Clayton 
1804e78f606SGreg Clayton             case eStopReasonBreakpoint:
1814e78f606SGreg Clayton                 {
1824e78f606SGreg Clayton                     break_id_t site_id = stop_info_sp->GetValue();
1831ac04c30SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
1844e78f606SGreg Clayton                     if (bp_site_sp)
1854e78f606SGreg Clayton                     {
1864e78f606SGreg Clayton                         uint32_t bp_index = idx / 2;
1874e78f606SGreg Clayton                         BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
1884e78f606SGreg Clayton                         if (bp_loc_sp)
1894e78f606SGreg Clayton                         {
1904e78f606SGreg Clayton                             if (bp_index & 1)
1914e78f606SGreg Clayton                             {
1924e78f606SGreg Clayton                                 // Odd idx, return the breakpoint location ID
1934e78f606SGreg Clayton                                 return bp_loc_sp->GetID();
1944e78f606SGreg Clayton                             }
1954e78f606SGreg Clayton                             else
1964e78f606SGreg Clayton                             {
1974e78f606SGreg Clayton                                 // Even idx, return the breakpoint ID
1984e78f606SGreg Clayton                                 return bp_loc_sp->GetBreakpoint().GetID();
1994e78f606SGreg Clayton                             }
2004e78f606SGreg Clayton                         }
2014e78f606SGreg Clayton                     }
2024e78f606SGreg Clayton                     return LLDB_INVALID_BREAK_ID;
2034e78f606SGreg Clayton                 }
2044e78f606SGreg Clayton                 break;
2054e78f606SGreg Clayton 
2064e78f606SGreg Clayton             case eStopReasonWatchpoint:
207290fa41bSJohnny Chen                 return stop_info_sp->GetValue();
2084e78f606SGreg Clayton 
2094e78f606SGreg Clayton             case eStopReasonSignal:
2104e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2114e78f606SGreg Clayton 
2124e78f606SGreg Clayton             case eStopReasonException:
2134e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2144e78f606SGreg Clayton             }
2154e78f606SGreg Clayton         }
2164e78f606SGreg Clayton     }
2174e78f606SGreg Clayton     return 0;
2184e78f606SGreg Clayton }
2194e78f606SGreg Clayton 
2204e78f606SGreg Clayton size_t
22130fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
22230fdc8d8SChris Lattner {
2232d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
224ceb6b139SCaroline Tice 
2251ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
2261ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
22730fdc8d8SChris Lattner     {
2281ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
2291ac04c30SGreg Clayton         StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
230b15bfc75SJim Ingham         if (stop_info_sp)
23130fdc8d8SChris Lattner         {
232b15bfc75SJim Ingham             const char *stop_desc = stop_info_sp->GetDescription();
23330fdc8d8SChris Lattner             if (stop_desc)
23430fdc8d8SChris Lattner             {
235ceb6b139SCaroline Tice                 if (log)
2364838131bSGreg Clayton                     log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
2371ac04c30SGreg Clayton                                  exe_ctx.GetThreadPtr(), stop_desc);
23830fdc8d8SChris Lattner                 if (dst)
23930fdc8d8SChris Lattner                     return ::snprintf (dst, dst_len, "%s", stop_desc);
24030fdc8d8SChris Lattner                 else
24130fdc8d8SChris Lattner                 {
24230fdc8d8SChris Lattner                     // NULL dst passed in, return the length needed to contain the description
24330fdc8d8SChris Lattner                     return ::strlen (stop_desc) + 1; // Include the NULL byte for size
24430fdc8d8SChris Lattner                 }
24530fdc8d8SChris Lattner             }
24630fdc8d8SChris Lattner             else
24730fdc8d8SChris Lattner             {
24830fdc8d8SChris Lattner                 size_t stop_desc_len = 0;
249b15bfc75SJim Ingham                 switch (stop_info_sp->GetStopReason())
25030fdc8d8SChris Lattner                 {
25130fdc8d8SChris Lattner                 case eStopReasonTrace:
25230fdc8d8SChris Lattner                 case eStopReasonPlanComplete:
25330fdc8d8SChris Lattner                     {
25430fdc8d8SChris Lattner                         static char trace_desc[] = "step";
25530fdc8d8SChris Lattner                         stop_desc = trace_desc;
25630fdc8d8SChris Lattner                         stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
25730fdc8d8SChris Lattner                     }
25830fdc8d8SChris Lattner                     break;
25930fdc8d8SChris Lattner 
26030fdc8d8SChris Lattner                 case eStopReasonBreakpoint:
26130fdc8d8SChris Lattner                     {
26230fdc8d8SChris Lattner                         static char bp_desc[] = "breakpoint hit";
26330fdc8d8SChris Lattner                         stop_desc = bp_desc;
26430fdc8d8SChris Lattner                         stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
26530fdc8d8SChris Lattner                     }
26630fdc8d8SChris Lattner                     break;
26730fdc8d8SChris Lattner 
26830fdc8d8SChris Lattner                 case eStopReasonWatchpoint:
26930fdc8d8SChris Lattner                     {
27030fdc8d8SChris Lattner                         static char wp_desc[] = "watchpoint hit";
27130fdc8d8SChris Lattner                         stop_desc = wp_desc;
27230fdc8d8SChris Lattner                         stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
27330fdc8d8SChris Lattner                     }
27430fdc8d8SChris Lattner                     break;
27530fdc8d8SChris Lattner 
27630fdc8d8SChris Lattner                 case eStopReasonSignal:
27730fdc8d8SChris Lattner                     {
2781ac04c30SGreg Clayton                         stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
27930fdc8d8SChris Lattner                         if (stop_desc == NULL || stop_desc[0] == '\0')
28030fdc8d8SChris Lattner                         {
28130fdc8d8SChris Lattner                             static char signal_desc[] = "signal";
28230fdc8d8SChris Lattner                             stop_desc = signal_desc;
28330fdc8d8SChris Lattner                             stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
28430fdc8d8SChris Lattner                         }
28530fdc8d8SChris Lattner                     }
28630fdc8d8SChris Lattner                     break;
28730fdc8d8SChris Lattner 
28830fdc8d8SChris Lattner                 case eStopReasonException:
28930fdc8d8SChris Lattner                     {
29030fdc8d8SChris Lattner                         char exc_desc[] = "exception";
29130fdc8d8SChris Lattner                         stop_desc = exc_desc;
29230fdc8d8SChris Lattner                         stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
29330fdc8d8SChris Lattner                     }
29430fdc8d8SChris Lattner                     break;
295c982c768SGreg Clayton 
296c982c768SGreg Clayton                 default:
297c982c768SGreg Clayton                     break;
29830fdc8d8SChris Lattner                 }
29930fdc8d8SChris Lattner 
30030fdc8d8SChris Lattner                 if (stop_desc && stop_desc[0])
30130fdc8d8SChris Lattner                 {
302ceb6b139SCaroline Tice                     if (log)
30393aa84e8SGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
3041ac04c30SGreg Clayton                                      exe_ctx.GetThreadPtr(), stop_desc);
305ceb6b139SCaroline Tice 
30630fdc8d8SChris Lattner                     if (dst)
30730fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
30830fdc8d8SChris Lattner 
30930fdc8d8SChris Lattner                     if (stop_desc_len == 0)
31030fdc8d8SChris Lattner                         stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
31130fdc8d8SChris Lattner 
31230fdc8d8SChris Lattner                     return stop_desc_len;
31330fdc8d8SChris Lattner                 }
31430fdc8d8SChris Lattner             }
31530fdc8d8SChris Lattner         }
31630fdc8d8SChris Lattner     }
31730fdc8d8SChris Lattner     if (dst)
31830fdc8d8SChris Lattner         *dst = 0;
31930fdc8d8SChris Lattner     return 0;
32030fdc8d8SChris Lattner }
32130fdc8d8SChris Lattner 
32273ca05a2SJim Ingham SBValue
32373ca05a2SJim Ingham SBThread::GetStopReturnValue ()
32473ca05a2SJim Ingham {
32573ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
3261ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
3271ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
32873ca05a2SJim Ingham     {
3291ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
3301ac04c30SGreg Clayton         StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
33173ca05a2SJim Ingham         if (stop_info_sp)
33273ca05a2SJim Ingham         {
33373ca05a2SJim Ingham             return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
33473ca05a2SJim Ingham         }
33573ca05a2SJim Ingham     }
33673ca05a2SJim Ingham 
33773ca05a2SJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
33873ca05a2SJim Ingham     if (log)
3391ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
34073ca05a2SJim Ingham                                                                   return_valobj_sp.get()
34173ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
34273ca05a2SJim Ingham                                                                         : "<no return value>");
34373ca05a2SJim Ingham 
34473ca05a2SJim Ingham     return SBValue (return_valobj_sp);
34573ca05a2SJim Ingham }
34673ca05a2SJim Ingham 
34730fdc8d8SChris Lattner void
34830fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
34930fdc8d8SChris Lattner {
35017a6ad05SGreg Clayton     m_opaque_wp = lldb_object_sp;
35130fdc8d8SChris Lattner }
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner lldb::tid_t
35530fdc8d8SChris Lattner SBThread::GetThreadID () const
35630fdc8d8SChris Lattner {
35717a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
35817a6ad05SGreg Clayton     if (thread_sp)
3591ac04c30SGreg Clayton         return thread_sp->GetID();
3601ac04c30SGreg Clayton     return LLDB_INVALID_THREAD_ID;
36130fdc8d8SChris Lattner }
36230fdc8d8SChris Lattner 
36330fdc8d8SChris Lattner uint32_t
36430fdc8d8SChris Lattner SBThread::GetIndexID () const
36530fdc8d8SChris Lattner {
36617a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
36717a6ad05SGreg Clayton     if (thread_sp)
36817a6ad05SGreg Clayton         return thread_sp->GetIndexID();
36930fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
37030fdc8d8SChris Lattner }
3711ac04c30SGreg Clayton 
37230fdc8d8SChris Lattner const char *
37330fdc8d8SChris Lattner SBThread::GetName () const
37430fdc8d8SChris Lattner {
3754838131bSGreg Clayton     const char *name = NULL;
3761ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
3771ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
378af67cecdSGreg Clayton     {
3791ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
3801ac04c30SGreg Clayton         name = exe_ctx.GetThreadPtr()->GetName();
381af67cecdSGreg Clayton     }
382ceb6b139SCaroline Tice 
3832d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
384ceb6b139SCaroline Tice     if (log)
3851ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
386ceb6b139SCaroline Tice 
3874838131bSGreg Clayton     return name;
38830fdc8d8SChris Lattner }
38930fdc8d8SChris Lattner 
39030fdc8d8SChris Lattner const char *
39130fdc8d8SChris Lattner SBThread::GetQueueName () const
39230fdc8d8SChris Lattner {
3934838131bSGreg Clayton     const char *name = NULL;
3941ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
3951ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
396af67cecdSGreg Clayton     {
3971ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
3981ac04c30SGreg Clayton         name = exe_ctx.GetThreadPtr()->GetQueueName();
399af67cecdSGreg Clayton     }
400ceb6b139SCaroline Tice 
4012d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
402ceb6b139SCaroline Tice     if (log)
4031ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
404ceb6b139SCaroline Tice 
4054838131bSGreg Clayton     return name;
40630fdc8d8SChris Lattner }
40730fdc8d8SChris Lattner 
40830fdc8d8SChris Lattner 
40930fdc8d8SChris Lattner void
41030fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
41130fdc8d8SChris Lattner {
4122d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
413ceb6b139SCaroline Tice 
4141ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
41517a6ad05SGreg Clayton 
416ceb6b139SCaroline Tice     if (log)
4171ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
418ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
419ceb6b139SCaroline Tice 
4201ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
42130fdc8d8SChris Lattner     {
4221ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
4231ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
42430fdc8d8SChris Lattner         bool abort_other_plans = true;
4251ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
42630fdc8d8SChris Lattner 
42730fdc8d8SChris Lattner         if (frame_sp)
42830fdc8d8SChris Lattner         {
42930fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
43030fdc8d8SChris Lattner             {
43130fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
4321ac04c30SGreg Clayton                 thread->QueueThreadPlanForStepRange (abort_other_plans,
43330fdc8d8SChris Lattner                                                         eStepTypeOver,
43430fdc8d8SChris Lattner                                                         sc.line_entry.range,
43530fdc8d8SChris Lattner                                                         sc,
436474966a4SGreg Clayton                                                         stop_other_threads,
437474966a4SGreg Clayton                                                         false);
43830fdc8d8SChris Lattner 
43930fdc8d8SChris Lattner             }
44030fdc8d8SChris Lattner             else
44130fdc8d8SChris Lattner             {
4421ac04c30SGreg Clayton                 thread->QueueThreadPlanForStepSingleInstruction (true,
44330fdc8d8SChris Lattner                                                                     abort_other_plans,
44430fdc8d8SChris Lattner                                                                     stop_other_threads);
44530fdc8d8SChris Lattner             }
44630fdc8d8SChris Lattner         }
44730fdc8d8SChris Lattner 
4481ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
44930fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
4501ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
4511ac04c30SGreg Clayton         Error error (process->Resume());
4525d5028b5SGreg Clayton         if (error.Success())
4535d5028b5SGreg Clayton         {
4545d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
4555d5028b5SGreg Clayton             // process to stop yet again!
4561ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
4571ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
4585d5028b5SGreg Clayton         }
45930fdc8d8SChris Lattner     }
46030fdc8d8SChris Lattner }
46130fdc8d8SChris Lattner 
46230fdc8d8SChris Lattner void
46330fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
46430fdc8d8SChris Lattner {
4652d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
466ceb6b139SCaroline Tice 
4671ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
46817a6ad05SGreg Clayton 
46917a6ad05SGreg Clayton     if (log)
4701ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
47117a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
4721ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
47330fdc8d8SChris Lattner     {
4741ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
47530fdc8d8SChris Lattner         bool abort_other_plans = true;
47630fdc8d8SChris Lattner 
4771ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
4781ac04c30SGreg Clayton         StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
48130fdc8d8SChris Lattner         {
482474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
48330fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
4841ac04c30SGreg Clayton             thread->QueueThreadPlanForStepRange (abort_other_plans,
48530fdc8d8SChris Lattner                                                  eStepTypeInto,
48630fdc8d8SChris Lattner                                                  sc.line_entry.range,
48730fdc8d8SChris Lattner                                                  sc,
488474966a4SGreg Clayton                                                  stop_other_threads,
489474966a4SGreg Clayton                                                  avoid_code_without_debug_info);
49030fdc8d8SChris Lattner         }
49130fdc8d8SChris Lattner         else
49230fdc8d8SChris Lattner         {
4931ac04c30SGreg Clayton             thread->QueueThreadPlanForStepSingleInstruction (false,
49430fdc8d8SChris Lattner                                                              abort_other_plans,
49530fdc8d8SChris Lattner                                                              stop_other_threads);
49630fdc8d8SChris Lattner         }
49730fdc8d8SChris Lattner 
4981ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
49930fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
5001ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
5011ac04c30SGreg Clayton         Error error (process->Resume());
5025d5028b5SGreg Clayton         if (error.Success())
5035d5028b5SGreg Clayton         {
5045d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5055d5028b5SGreg Clayton             // process to stop yet again!
5061ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
5071ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
5085d5028b5SGreg Clayton         }
50930fdc8d8SChris Lattner     }
51030fdc8d8SChris Lattner }
51130fdc8d8SChris Lattner 
51230fdc8d8SChris Lattner void
51330fdc8d8SChris Lattner SBThread::StepOut ()
51430fdc8d8SChris Lattner {
5152d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
516ceb6b139SCaroline Tice 
5171ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
518ceb6b139SCaroline Tice 
51917a6ad05SGreg Clayton     if (log)
5201ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
52117a6ad05SGreg Clayton 
5221ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
52330fdc8d8SChris Lattner     {
5241ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
52530fdc8d8SChris Lattner         bool abort_other_plans = true;
52630fdc8d8SChris Lattner         bool stop_other_threads = true;
52730fdc8d8SChris Lattner 
5281ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
5291ac04c30SGreg Clayton 
5301ac04c30SGreg Clayton         thread->QueueThreadPlanForStepOut (abort_other_plans,
531481cef25SGreg Clayton                                               NULL,
532481cef25SGreg Clayton                                               false,
533481cef25SGreg Clayton                                               stop_other_threads,
534481cef25SGreg Clayton                                               eVoteYes,
535481cef25SGreg Clayton                                               eVoteNoOpinion,
536481cef25SGreg Clayton                                               0);
537481cef25SGreg Clayton 
5381ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
5391ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
5401ac04c30SGreg Clayton         Error error (process->Resume());
541481cef25SGreg Clayton         if (error.Success())
542481cef25SGreg Clayton         {
543481cef25SGreg Clayton             // If we are doing synchronous mode, then wait for the
544481cef25SGreg Clayton             // process to stop yet again!
5451ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
5461ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
547481cef25SGreg Clayton         }
548481cef25SGreg Clayton     }
549481cef25SGreg Clayton }
550481cef25SGreg Clayton 
551481cef25SGreg Clayton void
552481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
553481cef25SGreg Clayton {
554481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
555481cef25SGreg Clayton 
5561ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
557b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
558481cef25SGreg Clayton     if (log)
559481cef25SGreg Clayton     {
560481cef25SGreg Clayton         SBStream frame_desc_strm;
561481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
5621ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
563481cef25SGreg Clayton     }
564481cef25SGreg Clayton 
5651ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
566481cef25SGreg Clayton     {
5671ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
568481cef25SGreg Clayton         bool abort_other_plans = true;
569481cef25SGreg Clayton         bool stop_other_threads = true;
5701ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
571481cef25SGreg Clayton 
5721ac04c30SGreg Clayton         thread->QueueThreadPlanForStepOut (abort_other_plans,
573481cef25SGreg Clayton                                               NULL,
574481cef25SGreg Clayton                                               false,
575481cef25SGreg Clayton                                               stop_other_threads,
576481cef25SGreg Clayton                                               eVoteYes,
577481cef25SGreg Clayton                                               eVoteNoOpinion,
578b9556accSGreg Clayton                                               frame_sp->GetFrameIndex());
57930fdc8d8SChris Lattner 
5801ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
5811ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
5821ac04c30SGreg Clayton         Error error (process->Resume());
5835d5028b5SGreg Clayton         if (error.Success())
5845d5028b5SGreg Clayton         {
5855d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5865d5028b5SGreg Clayton             // process to stop yet again!
5871ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
5881ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
5895d5028b5SGreg Clayton         }
59030fdc8d8SChris Lattner     }
59130fdc8d8SChris Lattner }
59230fdc8d8SChris Lattner 
59330fdc8d8SChris Lattner void
59430fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
59530fdc8d8SChris Lattner {
5962d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
597ceb6b139SCaroline Tice 
5981ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
5991ac04c30SGreg Clayton 
600ceb6b139SCaroline Tice 
60117a6ad05SGreg Clayton     if (log)
6021ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
60317a6ad05SGreg Clayton 
6041ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
60530fdc8d8SChris Lattner     {
6061ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
6071ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6081ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
6091ac04c30SGreg Clayton         thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
6101ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
6111ac04c30SGreg Clayton         Error error (process->Resume());
6125d5028b5SGreg Clayton         if (error.Success())
6135d5028b5SGreg Clayton         {
6145d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6155d5028b5SGreg Clayton             // process to stop yet again!
6161ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
6171ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
6185d5028b5SGreg Clayton         }
61930fdc8d8SChris Lattner     }
62030fdc8d8SChris Lattner }
62130fdc8d8SChris Lattner 
62230fdc8d8SChris Lattner void
62330fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr)
62430fdc8d8SChris Lattner {
6252d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
626ceb6b139SCaroline Tice 
6271ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
628ceb6b139SCaroline Tice 
62917a6ad05SGreg Clayton     if (log)
6301ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
63117a6ad05SGreg Clayton 
6321ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
63330fdc8d8SChris Lattner     {
6341ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
63530fdc8d8SChris Lattner         bool abort_other_plans = true;
63630fdc8d8SChris Lattner         bool stop_other_threads = true;
63730fdc8d8SChris Lattner 
638*e72dfb32SGreg Clayton         Address target_addr (addr);
63930fdc8d8SChris Lattner 
6401ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
6411ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
6421ac04c30SGreg Clayton 
6431ac04c30SGreg Clayton         thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
6441ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
6451ac04c30SGreg Clayton         Error error (process->Resume());
6465d5028b5SGreg Clayton         if (error.Success())
6475d5028b5SGreg Clayton         {
6485d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6495d5028b5SGreg Clayton             // process to stop yet again!
6501ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
6511ac04c30SGreg Clayton                 process->WaitForProcessToStop (NULL);
6525d5028b5SGreg Clayton         }
65330fdc8d8SChris Lattner     }
65430fdc8d8SChris Lattner }
65530fdc8d8SChris Lattner 
656481cef25SGreg Clayton SBError
657481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
658481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
659481cef25SGreg Clayton                          uint32_t line)
660481cef25SGreg Clayton {
661481cef25SGreg Clayton     SBError sb_error;
662481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
663481cef25SGreg Clayton     char path[PATH_MAX];
664481cef25SGreg Clayton 
6651ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
666b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
66717a6ad05SGreg Clayton 
668481cef25SGreg Clayton     if (log)
669481cef25SGreg Clayton     {
670481cef25SGreg Clayton         SBStream frame_desc_strm;
671481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
672481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
673481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
6741ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
675b9556accSGreg Clayton                      frame_sp.get(),
676481cef25SGreg Clayton                      frame_desc_strm.GetData(),
677481cef25SGreg Clayton                      path, line);
678481cef25SGreg Clayton     }
679481cef25SGreg Clayton 
6801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
681481cef25SGreg Clayton     {
6821ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
6831ac04c30SGreg Clayton         Mutex::Locker api_locker (target->GetAPIMutex());
6841ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
685481cef25SGreg Clayton 
686481cef25SGreg Clayton         if (line == 0)
687481cef25SGreg Clayton         {
688481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
689481cef25SGreg Clayton             return sb_error;
690481cef25SGreg Clayton         }
691481cef25SGreg Clayton 
692481cef25SGreg Clayton         StackFrameSP frame_sp;
693b9556accSGreg Clayton         if (!frame_sp)
694481cef25SGreg Clayton         {
6951ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
696481cef25SGreg Clayton             if (!frame_sp)
6971ac04c30SGreg Clayton                 frame_sp = thread->GetStackFrameAtIndex (0);
698481cef25SGreg Clayton         }
699481cef25SGreg Clayton 
700481cef25SGreg Clayton         SymbolContext frame_sc;
701481cef25SGreg Clayton         if (!frame_sp)
702481cef25SGreg Clayton         {
703481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
704481cef25SGreg Clayton             return sb_error;
705481cef25SGreg Clayton         }
706481cef25SGreg Clayton 
707481cef25SGreg Clayton         // If we have a frame, get its line
708481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
709481cef25SGreg Clayton                                                eSymbolContextFunction  |
710481cef25SGreg Clayton                                                eSymbolContextLineEntry |
711481cef25SGreg Clayton                                                eSymbolContextSymbol    );
712481cef25SGreg Clayton 
713481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
714481cef25SGreg Clayton         {
715481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
716481cef25SGreg Clayton             return sb_error;
717481cef25SGreg Clayton         }
718481cef25SGreg Clayton 
719481cef25SGreg Clayton         FileSpec step_file_spec;
720481cef25SGreg Clayton         if (sb_file_spec.IsValid())
721481cef25SGreg Clayton         {
722481cef25SGreg Clayton             // The file spec passed in was valid, so use it
723481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
724481cef25SGreg Clayton         }
725481cef25SGreg Clayton         else
726481cef25SGreg Clayton         {
727481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
728481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
729481cef25SGreg Clayton             else
730481cef25SGreg Clayton             {
731481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
732481cef25SGreg Clayton                 return sb_error;
733481cef25SGreg Clayton             }
734481cef25SGreg Clayton         }
735481cef25SGreg Clayton 
7369b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
7379b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
7389b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
7399b70ddb3SJim Ingham         // error message.
7409b70ddb3SJim Ingham 
7419b70ddb3SJim Ingham         bool all_in_function = true;
7429b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
7439b70ddb3SJim Ingham 
744481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
745481cef25SGreg Clayton         const bool abort_other_plans = true;
746481cef25SGreg Clayton         const bool stop_other_threads = true;
747481cef25SGreg Clayton         const bool check_inlines = true;
748481cef25SGreg Clayton         const bool exact = false;
749481cef25SGreg Clayton 
750481cef25SGreg Clayton         SymbolContextList sc_list;
7519b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
7529b70ddb3SJim Ingham                                                                                line,
7539b70ddb3SJim Ingham                                                                                check_inlines,
7549b70ddb3SJim Ingham                                                                                exact,
7559b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
7569b70ddb3SJim Ingham                                                                                sc_list);
757481cef25SGreg Clayton         if (num_matches > 0)
758481cef25SGreg Clayton         {
759481cef25SGreg Clayton             SymbolContext sc;
760481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
761481cef25SGreg Clayton             {
762481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
763481cef25SGreg Clayton                 {
7649b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
765481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
766481cef25SGreg Clayton                     {
7679b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
768481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
7699b70ddb3SJim Ingham                         else
7709b70ddb3SJim Ingham                             all_in_function = false;
771481cef25SGreg Clayton                     }
772481cef25SGreg Clayton                 }
773481cef25SGreg Clayton             }
774481cef25SGreg Clayton         }
775481cef25SGreg Clayton 
776481cef25SGreg Clayton         if (step_over_until_addrs.empty())
777481cef25SGreg Clayton         {
7789b70ddb3SJim Ingham             if (all_in_function)
7799b70ddb3SJim Ingham             {
780481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
781fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
782481cef25SGreg Clayton             }
783481cef25SGreg Clayton             else
78486edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
7859b70ddb3SJim Ingham         }
7869b70ddb3SJim Ingham         else
787481cef25SGreg Clayton         {
7881ac04c30SGreg Clayton             thread->QueueThreadPlanForStepUntil (abort_other_plans,
789481cef25SGreg Clayton                                                  &step_over_until_addrs[0],
790481cef25SGreg Clayton                                                  step_over_until_addrs.size(),
791481cef25SGreg Clayton                                                  stop_other_threads,
792481cef25SGreg Clayton                                                  frame_sp->GetFrameIndex());
793481cef25SGreg Clayton 
7941ac04c30SGreg Clayton             Process *process = exe_ctx.GetProcessPtr();
7951ac04c30SGreg Clayton 
7961ac04c30SGreg Clayton             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
7971ac04c30SGreg Clayton             sb_error.ref() = process->Resume();
798481cef25SGreg Clayton             if (sb_error->Success())
799481cef25SGreg Clayton             {
800481cef25SGreg Clayton                 // If we are doing synchronous mode, then wait for the
801481cef25SGreg Clayton                 // process to stop yet again!
8021ac04c30SGreg Clayton                 if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
8031ac04c30SGreg Clayton                     process->WaitForProcessToStop (NULL);
804481cef25SGreg Clayton             }
805481cef25SGreg Clayton         }
806481cef25SGreg Clayton     }
807481cef25SGreg Clayton     else
808481cef25SGreg Clayton     {
809481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
810481cef25SGreg Clayton     }
811481cef25SGreg Clayton     return sb_error;
812481cef25SGreg Clayton }
813481cef25SGreg Clayton 
814481cef25SGreg Clayton 
815722a0cdcSGreg Clayton bool
816722a0cdcSGreg Clayton SBThread::Suspend()
817722a0cdcSGreg Clayton {
8181ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
8191ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
820722a0cdcSGreg Clayton     {
8211ac04c30SGreg Clayton         exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
822722a0cdcSGreg Clayton         return true;
823722a0cdcSGreg Clayton     }
824722a0cdcSGreg Clayton     return false;
825722a0cdcSGreg Clayton }
826722a0cdcSGreg Clayton 
827722a0cdcSGreg Clayton bool
828722a0cdcSGreg Clayton SBThread::Resume ()
829722a0cdcSGreg Clayton {
8301ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
8311ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
832722a0cdcSGreg Clayton     {
8331ac04c30SGreg Clayton         exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
834722a0cdcSGreg Clayton         return true;
835722a0cdcSGreg Clayton     }
836722a0cdcSGreg Clayton     return false;
837722a0cdcSGreg Clayton }
838722a0cdcSGreg Clayton 
839722a0cdcSGreg Clayton bool
840722a0cdcSGreg Clayton SBThread::IsSuspended()
841722a0cdcSGreg Clayton {
8421ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
8431ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
8441ac04c30SGreg Clayton         return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
845722a0cdcSGreg Clayton     return false;
846722a0cdcSGreg Clayton }
847722a0cdcSGreg Clayton 
84830fdc8d8SChris Lattner SBProcess
84930fdc8d8SChris Lattner SBThread::GetProcess ()
85030fdc8d8SChris Lattner {
851ceb6b139SCaroline Tice 
852b9556accSGreg Clayton     SBProcess sb_process;
853b9556accSGreg Clayton     ProcessSP process_sp;
8541ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
8551ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
85630fdc8d8SChris Lattner     {
85730fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
8581ac04c30SGreg Clayton         sb_process.SetSP (exe_ctx.GetProcessSP());
85930fdc8d8SChris Lattner     }
860ceb6b139SCaroline Tice 
8612d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
862ceb6b139SCaroline Tice     if (log)
863ceb6b139SCaroline Tice     {
864481cef25SGreg Clayton         SBStream frame_desc_strm;
865b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
8661ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
867b9556accSGreg Clayton                      process_sp.get(), frame_desc_strm.GetData());
868ceb6b139SCaroline Tice     }
869ceb6b139SCaroline Tice 
870b9556accSGreg Clayton     return sb_process;
87130fdc8d8SChris Lattner }
87230fdc8d8SChris Lattner 
87330fdc8d8SChris Lattner uint32_t
87430fdc8d8SChris Lattner SBThread::GetNumFrames ()
87530fdc8d8SChris Lattner {
8762d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
877ceb6b139SCaroline Tice 
878ceb6b139SCaroline Tice     uint32_t num_frames = 0;
8791ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
8801ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
881af67cecdSGreg Clayton     {
8821ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
8831ac04c30SGreg Clayton         num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
884af67cecdSGreg Clayton     }
885ceb6b139SCaroline Tice 
886ceb6b139SCaroline Tice     if (log)
8871ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
888ceb6b139SCaroline Tice 
889ceb6b139SCaroline Tice     return num_frames;
89030fdc8d8SChris Lattner }
89130fdc8d8SChris Lattner 
89230fdc8d8SChris Lattner SBFrame
89330fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
89430fdc8d8SChris Lattner {
8952d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
896ceb6b139SCaroline Tice 
89730fdc8d8SChris Lattner     SBFrame sb_frame;
898b9556accSGreg Clayton     StackFrameSP frame_sp;
8991ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
9001ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
901af67cecdSGreg Clayton     {
9021ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
9031ac04c30SGreg Clayton         frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
904b9556accSGreg Clayton         sb_frame.SetFrameSP (frame_sp);
905af67cecdSGreg Clayton     }
906ceb6b139SCaroline Tice 
907ceb6b139SCaroline Tice     if (log)
908ceb6b139SCaroline Tice     {
909481cef25SGreg Clayton         SBStream frame_desc_strm;
910481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
9114838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
9121ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
913ceb6b139SCaroline Tice     }
914ceb6b139SCaroline Tice 
91530fdc8d8SChris Lattner     return sb_frame;
91630fdc8d8SChris Lattner }
91730fdc8d8SChris Lattner 
918f028a1fbSGreg Clayton lldb::SBFrame
919f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
920f028a1fbSGreg Clayton {
921f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
922f028a1fbSGreg Clayton 
923f028a1fbSGreg Clayton     SBFrame sb_frame;
924b9556accSGreg Clayton     StackFrameSP frame_sp;
9251ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
9261ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
927af67cecdSGreg Clayton     {
9281ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
9291ac04c30SGreg Clayton         frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
930b9556accSGreg Clayton         sb_frame.SetFrameSP (frame_sp);
931af67cecdSGreg Clayton     }
932f028a1fbSGreg Clayton 
933f028a1fbSGreg Clayton     if (log)
934f028a1fbSGreg Clayton     {
935481cef25SGreg Clayton         SBStream frame_desc_strm;
936481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
937f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
9381ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
939f028a1fbSGreg Clayton     }
940f028a1fbSGreg Clayton 
941f028a1fbSGreg Clayton     return sb_frame;
942f028a1fbSGreg Clayton }
943f028a1fbSGreg Clayton 
944f028a1fbSGreg Clayton lldb::SBFrame
945f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
946f028a1fbSGreg Clayton {
947f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
948f028a1fbSGreg Clayton 
949f028a1fbSGreg Clayton     SBFrame sb_frame;
950b9556accSGreg Clayton     StackFrameSP frame_sp;
9511ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
9521ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
953f028a1fbSGreg Clayton     {
9541ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
9551ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
9561ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex (idx);
957f028a1fbSGreg Clayton         if (frame_sp)
958f028a1fbSGreg Clayton         {
9591ac04c30SGreg Clayton             thread->SetSelectedFrame (frame_sp.get());
960b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
961f028a1fbSGreg Clayton         }
962f028a1fbSGreg Clayton     }
963f028a1fbSGreg Clayton 
964f028a1fbSGreg Clayton     if (log)
965f028a1fbSGreg Clayton     {
966481cef25SGreg Clayton         SBStream frame_desc_strm;
967481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
968f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
9691ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
970f028a1fbSGreg Clayton     }
971f028a1fbSGreg Clayton     return sb_frame;
972f028a1fbSGreg Clayton }
973f028a1fbSGreg Clayton 
974f028a1fbSGreg Clayton 
97530fdc8d8SChris Lattner bool
97630fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
97730fdc8d8SChris Lattner {
97817a6ad05SGreg Clayton     return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get();
97930fdc8d8SChris Lattner }
98030fdc8d8SChris Lattner 
98130fdc8d8SChris Lattner bool
98230fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const
98330fdc8d8SChris Lattner {
98417a6ad05SGreg Clayton     return m_opaque_wp.lock().get() != rhs.m_opaque_wp.lock().get();
98530fdc8d8SChris Lattner }
986dde9cff3SCaroline Tice 
987dde9cff3SCaroline Tice bool
988ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
989ceb6b139SCaroline Tice {
990da7bc7d0SGreg Clayton     Stream &strm = description.ref();
991da7bc7d0SGreg Clayton 
9921ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
9931ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
994ceb6b139SCaroline Tice     {
9951ac04c30SGreg Clayton         strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID());
996ceb6b139SCaroline Tice     }
997ceb6b139SCaroline Tice     else
998da7bc7d0SGreg Clayton         strm.PutCString ("No value");
999ceb6b139SCaroline Tice 
1000ceb6b139SCaroline Tice     return true;
1001ceb6b139SCaroline Tice }
1002