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;
98*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
99*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
10030fdc8d8SChris Lattner     {
101*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
102*1ac04c30SGreg 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)
108*1ac04c30SGreg 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 {
117*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
118*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1194e78f606SGreg Clayton     {
120*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
121*1ac04c30SGreg 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();
137*1ac04c30SGreg 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 {
162*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
163*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
1644e78f606SGreg Clayton     {
165*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
166*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
167*1ac04c30SGreg 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();
183*1ac04c30SGreg 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 
225*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
226*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
22730fdc8d8SChris Lattner     {
228*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
229*1ac04c30SGreg 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\"",
237*1ac04c30SGreg 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                     {
278*1ac04c30SGreg 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'",
304*1ac04c30SGreg 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;
326*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
327*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
32873ca05a2SJim Ingham     {
329*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
330*1ac04c30SGreg 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)
339*1ac04c30SGreg 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)
359*1ac04c30SGreg Clayton         return thread_sp->GetID();
360*1ac04c30SGreg 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 }
371*1ac04c30SGreg Clayton 
37230fdc8d8SChris Lattner const char *
37330fdc8d8SChris Lattner SBThread::GetName () const
37430fdc8d8SChris Lattner {
3754838131bSGreg Clayton     const char *name = NULL;
376*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
377*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
378af67cecdSGreg Clayton     {
379*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
380*1ac04c30SGreg Clayton         name = exe_ctx.GetThreadPtr()->GetName();
381af67cecdSGreg Clayton     }
382ceb6b139SCaroline Tice 
3832d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
384ceb6b139SCaroline Tice     if (log)
385*1ac04c30SGreg 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;
394*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
395*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
396af67cecdSGreg Clayton     {
397*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
398*1ac04c30SGreg Clayton         name = exe_ctx.GetThreadPtr()->GetQueueName();
399af67cecdSGreg Clayton     }
400ceb6b139SCaroline Tice 
4012d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
402ceb6b139SCaroline Tice     if (log)
403*1ac04c30SGreg 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 
414*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
41517a6ad05SGreg Clayton 
416ceb6b139SCaroline Tice     if (log)
417*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
418ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
419ceb6b139SCaroline Tice 
420*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
42130fdc8d8SChris Lattner     {
422*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
423*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
42430fdc8d8SChris Lattner         bool abort_other_plans = true;
425*1ac04c30SGreg 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));
432*1ac04c30SGreg 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             {
442*1ac04c30SGreg Clayton                 thread->QueueThreadPlanForStepSingleInstruction (true,
44330fdc8d8SChris Lattner                                                                     abort_other_plans,
44430fdc8d8SChris Lattner                                                                     stop_other_threads);
44530fdc8d8SChris Lattner             }
44630fdc8d8SChris Lattner         }
44730fdc8d8SChris Lattner 
448*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
44930fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
450*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
451*1ac04c30SGreg 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!
456*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
457*1ac04c30SGreg 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 
467*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
46817a6ad05SGreg Clayton 
46917a6ad05SGreg Clayton     if (log)
470*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
47117a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
472*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
47330fdc8d8SChris Lattner     {
474*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
47530fdc8d8SChris Lattner         bool abort_other_plans = true;
47630fdc8d8SChris Lattner 
477*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
478*1ac04c30SGreg 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));
484*1ac04c30SGreg 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         {
493*1ac04c30SGreg Clayton             thread->QueueThreadPlanForStepSingleInstruction (false,
49430fdc8d8SChris Lattner                                                              abort_other_plans,
49530fdc8d8SChris Lattner                                                              stop_other_threads);
49630fdc8d8SChris Lattner         }
49730fdc8d8SChris Lattner 
498*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
49930fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
500*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
501*1ac04c30SGreg 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!
506*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
507*1ac04c30SGreg 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 
517*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
518ceb6b139SCaroline Tice 
51917a6ad05SGreg Clayton     if (log)
520*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
52117a6ad05SGreg Clayton 
522*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
52330fdc8d8SChris Lattner     {
524*1ac04c30SGreg 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 
528*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
529*1ac04c30SGreg Clayton 
530*1ac04c30SGreg 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 
538*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
539*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
540*1ac04c30SGreg 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!
545*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
546*1ac04c30SGreg 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 
556*1ac04c30SGreg 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);
562*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
563481cef25SGreg Clayton     }
564481cef25SGreg Clayton 
565*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
566481cef25SGreg Clayton     {
567*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
568481cef25SGreg Clayton         bool abort_other_plans = true;
569481cef25SGreg Clayton         bool stop_other_threads = true;
570*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
571481cef25SGreg Clayton 
572*1ac04c30SGreg 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 
580*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
581*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
582*1ac04c30SGreg 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!
587*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
588*1ac04c30SGreg 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 
598*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
599*1ac04c30SGreg Clayton 
600ceb6b139SCaroline Tice 
60117a6ad05SGreg Clayton     if (log)
602*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
60317a6ad05SGreg Clayton 
604*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
60530fdc8d8SChris Lattner     {
606*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
607*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
608*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
609*1ac04c30SGreg Clayton         thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
610*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
611*1ac04c30SGreg 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!
616*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
617*1ac04c30SGreg 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 
627*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
628ceb6b139SCaroline Tice 
62917a6ad05SGreg Clayton     if (log)
630*1ac04c30SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr);
63117a6ad05SGreg Clayton 
632*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
63330fdc8d8SChris Lattner     {
634*1ac04c30SGreg 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 
63830fdc8d8SChris Lattner         Address target_addr (NULL, addr);
63930fdc8d8SChris Lattner 
640*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
641*1ac04c30SGreg Clayton         Process *process = exe_ctx.GetProcessPtr();
642*1ac04c30SGreg Clayton 
643*1ac04c30SGreg Clayton         thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
644*1ac04c30SGreg Clayton         process->GetThreadList().SetSelectedThreadByID (thread->GetID());
645*1ac04c30SGreg 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!
650*1ac04c30SGreg Clayton             if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
651*1ac04c30SGreg 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 
665*1ac04c30SGreg 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)",
674*1ac04c30SGreg Clayton                      exe_ctx.GetThreadPtr(),
675b9556accSGreg Clayton                      frame_sp.get(),
676481cef25SGreg Clayton                      frame_desc_strm.GetData(),
677481cef25SGreg Clayton                      path, line);
678481cef25SGreg Clayton     }
679481cef25SGreg Clayton 
680*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
681481cef25SGreg Clayton     {
682*1ac04c30SGreg Clayton         Target *target = exe_ctx.GetTargetPtr();
683*1ac04c30SGreg Clayton         Mutex::Locker api_locker (target->GetAPIMutex());
684*1ac04c30SGreg 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         {
695*1ac04c30SGreg Clayton             frame_sp = thread->GetSelectedFrame ();
696481cef25SGreg Clayton             if (!frame_sp)
697*1ac04c30SGreg 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         {
788*1ac04c30SGreg 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 
794*1ac04c30SGreg Clayton             Process *process = exe_ctx.GetProcessPtr();
795*1ac04c30SGreg Clayton 
796*1ac04c30SGreg Clayton             process->GetThreadList().SetSelectedThreadByID (thread->GetID());
797*1ac04c30SGreg 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!
802*1ac04c30SGreg Clayton                 if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
803*1ac04c30SGreg 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 {
818*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
819*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
820722a0cdcSGreg Clayton     {
821*1ac04c30SGreg 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 {
830*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
831*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
832722a0cdcSGreg Clayton     {
833*1ac04c30SGreg 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 {
842*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
843*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
844*1ac04c30SGreg 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;
854*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
855*1ac04c30SGreg 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...
858*1ac04c30SGreg 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);
866*1ac04c30SGreg 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;
879*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
880*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
881af67cecdSGreg Clayton     {
882*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
883*1ac04c30SGreg Clayton         num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
884af67cecdSGreg Clayton     }
885ceb6b139SCaroline Tice 
886ceb6b139SCaroline Tice     if (log)
887*1ac04c30SGreg 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;
899*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
900*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
901af67cecdSGreg Clayton     {
902*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
903*1ac04c30SGreg 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",
912*1ac04c30SGreg 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;
925*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
926*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
927af67cecdSGreg Clayton     {
928*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
929*1ac04c30SGreg 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",
938*1ac04c30SGreg 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;
951*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
952*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
953f028a1fbSGreg Clayton     {
954*1ac04c30SGreg Clayton         Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex());
955*1ac04c30SGreg Clayton         Thread *thread = exe_ctx.GetThreadPtr();
956*1ac04c30SGreg Clayton         frame_sp = thread->GetStackFrameAtIndex (idx);
957f028a1fbSGreg Clayton         if (frame_sp)
958f028a1fbSGreg Clayton         {
959*1ac04c30SGreg 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",
969*1ac04c30SGreg 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 
992*1ac04c30SGreg Clayton     ExecutionContext exe_ctx (m_opaque_wp);
993*1ac04c30SGreg Clayton     if (exe_ctx.HasThreadScope())
994ceb6b139SCaroline Tice     {
995*1ac04c30SGreg 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