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;
9817a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
9917a6ad05SGreg Clayton     if (thread_sp)
10030fdc8d8SChris Lattner     {
10117a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
10217a6ad05SGreg Clayton         StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
103b15bfc75SJim Ingham         if (stop_info_sp)
104ceb6b139SCaroline Tice             reason =  stop_info_sp->GetStopReason();
10530fdc8d8SChris Lattner     }
106ceb6b139SCaroline Tice 
107ceb6b139SCaroline Tice     if (log)
10817a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReason () => %s", thread_sp.get(),
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 {
11717a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
11817a6ad05SGreg Clayton     if (thread_sp)
1194e78f606SGreg Clayton     {
12017a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
12117a6ad05SGreg Clayton         StopInfoSP stop_info_sp = thread_sp->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();
13717a6ad05SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().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 {
16217a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
16317a6ad05SGreg Clayton     if (thread_sp)
1644e78f606SGreg Clayton     {
16517a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
16617a6ad05SGreg Clayton         StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
1674e78f606SGreg Clayton         if (stop_info_sp)
1684e78f606SGreg Clayton         {
1694e78f606SGreg Clayton             StopReason reason = stop_info_sp->GetStopReason();
1704e78f606SGreg Clayton             switch (reason)
1714e78f606SGreg Clayton             {
1724e78f606SGreg Clayton             case eStopReasonInvalid:
1734e78f606SGreg Clayton             case eStopReasonNone:
1744e78f606SGreg Clayton             case eStopReasonTrace:
1754e78f606SGreg Clayton             case eStopReasonPlanComplete:
1764e78f606SGreg Clayton                 // There is no data for these stop reasons.
1774e78f606SGreg Clayton                 return 0;
1784e78f606SGreg Clayton 
1794e78f606SGreg Clayton             case eStopReasonBreakpoint:
1804e78f606SGreg Clayton                 {
1814e78f606SGreg Clayton                     break_id_t site_id = stop_info_sp->GetValue();
18217a6ad05SGreg Clayton                     lldb::BreakpointSiteSP bp_site_sp (thread_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id));
1834e78f606SGreg Clayton                     if (bp_site_sp)
1844e78f606SGreg Clayton                     {
1854e78f606SGreg Clayton                         uint32_t bp_index = idx / 2;
1864e78f606SGreg Clayton                         BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
1874e78f606SGreg Clayton                         if (bp_loc_sp)
1884e78f606SGreg Clayton                         {
1894e78f606SGreg Clayton                             if (bp_index & 1)
1904e78f606SGreg Clayton                             {
1914e78f606SGreg Clayton                                 // Odd idx, return the breakpoint location ID
1924e78f606SGreg Clayton                                 return bp_loc_sp->GetID();
1934e78f606SGreg Clayton                             }
1944e78f606SGreg Clayton                             else
1954e78f606SGreg Clayton                             {
1964e78f606SGreg Clayton                                 // Even idx, return the breakpoint ID
1974e78f606SGreg Clayton                                 return bp_loc_sp->GetBreakpoint().GetID();
1984e78f606SGreg Clayton                             }
1994e78f606SGreg Clayton                         }
2004e78f606SGreg Clayton                     }
2014e78f606SGreg Clayton                     return LLDB_INVALID_BREAK_ID;
2024e78f606SGreg Clayton                 }
2034e78f606SGreg Clayton                 break;
2044e78f606SGreg Clayton 
2054e78f606SGreg Clayton             case eStopReasonWatchpoint:
206290fa41bSJohnny Chen                 return stop_info_sp->GetValue();
2074e78f606SGreg Clayton 
2084e78f606SGreg Clayton             case eStopReasonSignal:
2094e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2104e78f606SGreg Clayton 
2114e78f606SGreg Clayton             case eStopReasonException:
2124e78f606SGreg Clayton                 return stop_info_sp->GetValue();
2134e78f606SGreg Clayton             }
2144e78f606SGreg Clayton         }
2154e78f606SGreg Clayton     }
2164e78f606SGreg Clayton     return 0;
2174e78f606SGreg Clayton }
2184e78f606SGreg Clayton 
2194e78f606SGreg Clayton size_t
22030fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len)
22130fdc8d8SChris Lattner {
2222d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
223ceb6b139SCaroline Tice 
22417a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
22517a6ad05SGreg Clayton     if (thread_sp)
22630fdc8d8SChris Lattner     {
22717a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
22817a6ad05SGreg Clayton         StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
229b15bfc75SJim Ingham         if (stop_info_sp)
23030fdc8d8SChris Lattner         {
231b15bfc75SJim Ingham             const char *stop_desc = stop_info_sp->GetDescription();
23230fdc8d8SChris Lattner             if (stop_desc)
23330fdc8d8SChris Lattner             {
234ceb6b139SCaroline Tice                 if (log)
2354838131bSGreg Clayton                     log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
23617a6ad05SGreg Clayton                                  thread_sp.get(), stop_desc);
23730fdc8d8SChris Lattner                 if (dst)
23830fdc8d8SChris Lattner                     return ::snprintf (dst, dst_len, "%s", stop_desc);
23930fdc8d8SChris Lattner                 else
24030fdc8d8SChris Lattner                 {
24130fdc8d8SChris Lattner                     // NULL dst passed in, return the length needed to contain the description
24230fdc8d8SChris Lattner                     return ::strlen (stop_desc) + 1; // Include the NULL byte for size
24330fdc8d8SChris Lattner                 }
24430fdc8d8SChris Lattner             }
24530fdc8d8SChris Lattner             else
24630fdc8d8SChris Lattner             {
24730fdc8d8SChris Lattner                 size_t stop_desc_len = 0;
248b15bfc75SJim Ingham                 switch (stop_info_sp->GetStopReason())
24930fdc8d8SChris Lattner                 {
25030fdc8d8SChris Lattner                 case eStopReasonTrace:
25130fdc8d8SChris Lattner                 case eStopReasonPlanComplete:
25230fdc8d8SChris Lattner                     {
25330fdc8d8SChris Lattner                         static char trace_desc[] = "step";
25430fdc8d8SChris Lattner                         stop_desc = trace_desc;
25530fdc8d8SChris Lattner                         stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
25630fdc8d8SChris Lattner                     }
25730fdc8d8SChris Lattner                     break;
25830fdc8d8SChris Lattner 
25930fdc8d8SChris Lattner                 case eStopReasonBreakpoint:
26030fdc8d8SChris Lattner                     {
26130fdc8d8SChris Lattner                         static char bp_desc[] = "breakpoint hit";
26230fdc8d8SChris Lattner                         stop_desc = bp_desc;
26330fdc8d8SChris Lattner                         stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
26430fdc8d8SChris Lattner                     }
26530fdc8d8SChris Lattner                     break;
26630fdc8d8SChris Lattner 
26730fdc8d8SChris Lattner                 case eStopReasonWatchpoint:
26830fdc8d8SChris Lattner                     {
26930fdc8d8SChris Lattner                         static char wp_desc[] = "watchpoint hit";
27030fdc8d8SChris Lattner                         stop_desc = wp_desc;
27130fdc8d8SChris Lattner                         stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
27230fdc8d8SChris Lattner                     }
27330fdc8d8SChris Lattner                     break;
27430fdc8d8SChris Lattner 
27530fdc8d8SChris Lattner                 case eStopReasonSignal:
27630fdc8d8SChris Lattner                     {
27717a6ad05SGreg Clayton                         stop_desc = thread_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
27830fdc8d8SChris Lattner                         if (stop_desc == NULL || stop_desc[0] == '\0')
27930fdc8d8SChris Lattner                         {
28030fdc8d8SChris Lattner                             static char signal_desc[] = "signal";
28130fdc8d8SChris Lattner                             stop_desc = signal_desc;
28230fdc8d8SChris Lattner                             stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
28330fdc8d8SChris Lattner                         }
28430fdc8d8SChris Lattner                     }
28530fdc8d8SChris Lattner                     break;
28630fdc8d8SChris Lattner 
28730fdc8d8SChris Lattner                 case eStopReasonException:
28830fdc8d8SChris Lattner                     {
28930fdc8d8SChris Lattner                         char exc_desc[] = "exception";
29030fdc8d8SChris Lattner                         stop_desc = exc_desc;
29130fdc8d8SChris Lattner                         stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
29230fdc8d8SChris Lattner                     }
29330fdc8d8SChris Lattner                     break;
294c982c768SGreg Clayton 
295c982c768SGreg Clayton                 default:
296c982c768SGreg Clayton                     break;
29730fdc8d8SChris Lattner                 }
29830fdc8d8SChris Lattner 
29930fdc8d8SChris Lattner                 if (stop_desc && stop_desc[0])
30030fdc8d8SChris Lattner                 {
301ceb6b139SCaroline Tice                     if (log)
30293aa84e8SGreg Clayton                         log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
30317a6ad05SGreg Clayton                                      thread_sp.get(), stop_desc);
304ceb6b139SCaroline Tice 
30530fdc8d8SChris Lattner                     if (dst)
30630fdc8d8SChris Lattner                         return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
30730fdc8d8SChris Lattner 
30830fdc8d8SChris Lattner                     if (stop_desc_len == 0)
30930fdc8d8SChris Lattner                         stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
31030fdc8d8SChris Lattner 
31130fdc8d8SChris Lattner                     return stop_desc_len;
31230fdc8d8SChris Lattner                 }
31330fdc8d8SChris Lattner             }
31430fdc8d8SChris Lattner         }
31530fdc8d8SChris Lattner     }
31630fdc8d8SChris Lattner     if (dst)
31730fdc8d8SChris Lattner         *dst = 0;
31830fdc8d8SChris Lattner     return 0;
31930fdc8d8SChris Lattner }
32030fdc8d8SChris Lattner 
32173ca05a2SJim Ingham SBValue
32273ca05a2SJim Ingham SBThread::GetStopReturnValue ()
32373ca05a2SJim Ingham {
32473ca05a2SJim Ingham     ValueObjectSP return_valobj_sp;
32517a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
32617a6ad05SGreg Clayton     if (thread_sp)
32773ca05a2SJim Ingham     {
32817a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
32917a6ad05SGreg Clayton         StopInfoSP stop_info_sp = thread_sp->GetStopInfo ();
33073ca05a2SJim Ingham         if (stop_info_sp)
33173ca05a2SJim Ingham         {
33273ca05a2SJim Ingham             return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
33373ca05a2SJim Ingham         }
33473ca05a2SJim Ingham     }
33573ca05a2SJim Ingham 
33673ca05a2SJim Ingham     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
33773ca05a2SJim Ingham     if (log)
33817a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", thread_sp.get(),
33973ca05a2SJim Ingham                                                                   return_valobj_sp.get()
34073ca05a2SJim Ingham                                                                       ? return_valobj_sp->GetValueAsCString()
34173ca05a2SJim Ingham                                                                         : "<no return value>");
34273ca05a2SJim Ingham 
34373ca05a2SJim Ingham     return SBValue (return_valobj_sp);
34473ca05a2SJim Ingham }
34573ca05a2SJim Ingham 
34630fdc8d8SChris Lattner void
34730fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp)
34830fdc8d8SChris Lattner {
34917a6ad05SGreg Clayton     m_opaque_wp = lldb_object_sp;
35030fdc8d8SChris Lattner }
35130fdc8d8SChris Lattner 
35230fdc8d8SChris Lattner 
35330fdc8d8SChris Lattner lldb::tid_t
35430fdc8d8SChris Lattner SBThread::GetThreadID () const
35530fdc8d8SChris Lattner {
3562d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
357ceb6b139SCaroline Tice 
358af67cecdSGreg Clayton     lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
35917a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
36017a6ad05SGreg Clayton     if (thread_sp)
36117a6ad05SGreg Clayton         tid = thread_sp->GetID();
362ceb6b139SCaroline Tice 
363ceb6b139SCaroline Tice     if (log)
36417a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", thread_sp.get(), tid);
365ceb6b139SCaroline Tice 
366af67cecdSGreg Clayton     return tid;
36730fdc8d8SChris Lattner }
36830fdc8d8SChris Lattner 
36930fdc8d8SChris Lattner uint32_t
37030fdc8d8SChris Lattner SBThread::GetIndexID () const
37130fdc8d8SChris Lattner {
37217a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
37317a6ad05SGreg Clayton     if (thread_sp)
37417a6ad05SGreg Clayton         return thread_sp->GetIndexID();
37530fdc8d8SChris Lattner     return LLDB_INVALID_INDEX32;
37630fdc8d8SChris Lattner }
37730fdc8d8SChris Lattner const char *
37830fdc8d8SChris Lattner SBThread::GetName () const
37930fdc8d8SChris Lattner {
3804838131bSGreg Clayton     const char *name = NULL;
38117a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
38217a6ad05SGreg Clayton     if (thread_sp)
383af67cecdSGreg Clayton     {
38417a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
38517a6ad05SGreg Clayton         name = thread_sp->GetName();
386af67cecdSGreg Clayton     }
387ceb6b139SCaroline Tice 
3882d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
389ceb6b139SCaroline Tice     if (log)
39017a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetName () => %s", thread_sp.get(), name ? name : "NULL");
391ceb6b139SCaroline Tice 
3924838131bSGreg Clayton     return name;
39330fdc8d8SChris Lattner }
39430fdc8d8SChris Lattner 
39530fdc8d8SChris Lattner const char *
39630fdc8d8SChris Lattner SBThread::GetQueueName () const
39730fdc8d8SChris Lattner {
3984838131bSGreg Clayton     const char *name = NULL;
39917a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
40017a6ad05SGreg Clayton     if (thread_sp)
401af67cecdSGreg Clayton     {
40217a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
40317a6ad05SGreg Clayton         name = thread_sp->GetQueueName();
404af67cecdSGreg Clayton     }
405ceb6b139SCaroline Tice 
4062d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
407ceb6b139SCaroline Tice     if (log)
40817a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetQueueName () => %s", thread_sp.get(), name ? name : "NULL");
409ceb6b139SCaroline Tice 
4104838131bSGreg Clayton     return name;
41130fdc8d8SChris Lattner }
41230fdc8d8SChris Lattner 
41330fdc8d8SChris Lattner 
41430fdc8d8SChris Lattner void
41530fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads)
41630fdc8d8SChris Lattner {
4172d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
418ceb6b139SCaroline Tice 
41917a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
42017a6ad05SGreg Clayton 
421ceb6b139SCaroline Tice     if (log)
42217a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", thread_sp.get(),
423ceb6b139SCaroline Tice                      Thread::RunModeAsCString (stop_other_threads));
424ceb6b139SCaroline Tice 
42517a6ad05SGreg Clayton     if (thread_sp)
42630fdc8d8SChris Lattner     {
42717a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
42830fdc8d8SChris Lattner         bool abort_other_plans = true;
42917a6ad05SGreg Clayton         StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
43030fdc8d8SChris Lattner 
43130fdc8d8SChris Lattner         if (frame_sp)
43230fdc8d8SChris Lattner         {
43330fdc8d8SChris Lattner             if (frame_sp->HasDebugInformation ())
43430fdc8d8SChris Lattner             {
43530fdc8d8SChris Lattner                 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
43617a6ad05SGreg Clayton                 thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
43730fdc8d8SChris Lattner                                                         eStepTypeOver,
43830fdc8d8SChris Lattner                                                         sc.line_entry.range,
43930fdc8d8SChris Lattner                                                         sc,
440474966a4SGreg Clayton                                                         stop_other_threads,
441474966a4SGreg Clayton                                                         false);
44230fdc8d8SChris Lattner 
44330fdc8d8SChris Lattner             }
44430fdc8d8SChris Lattner             else
44530fdc8d8SChris Lattner             {
44617a6ad05SGreg Clayton                 thread_sp->QueueThreadPlanForStepSingleInstruction (true,
44730fdc8d8SChris Lattner                                                                     abort_other_plans,
44830fdc8d8SChris Lattner                                                                     stop_other_threads);
44930fdc8d8SChris Lattner             }
45030fdc8d8SChris Lattner         }
45130fdc8d8SChris Lattner 
45217a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
45330fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
45417a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
4555d5028b5SGreg Clayton         Error error (process.Resume());
4565d5028b5SGreg Clayton         if (error.Success())
4575d5028b5SGreg Clayton         {
4585d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
4595d5028b5SGreg Clayton             // process to stop yet again!
4605d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
4615d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
4625d5028b5SGreg Clayton         }
46330fdc8d8SChris Lattner     }
46430fdc8d8SChris Lattner }
46530fdc8d8SChris Lattner 
46630fdc8d8SChris Lattner void
46730fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads)
46830fdc8d8SChris Lattner {
4692d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
470ceb6b139SCaroline Tice 
471ceb6b139SCaroline Tice 
47217a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
47317a6ad05SGreg Clayton 
47417a6ad05SGreg Clayton     if (log)
47517a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", thread_sp.get(),
47617a6ad05SGreg Clayton                      Thread::RunModeAsCString (stop_other_threads));
47717a6ad05SGreg Clayton     if (thread_sp)
47830fdc8d8SChris Lattner     {
47917a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
48030fdc8d8SChris Lattner         bool abort_other_plans = true;
48130fdc8d8SChris Lattner 
48217a6ad05SGreg Clayton         StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex (0));
48330fdc8d8SChris Lattner 
48430fdc8d8SChris Lattner         if (frame_sp && frame_sp->HasDebugInformation ())
48530fdc8d8SChris Lattner         {
486474966a4SGreg Clayton             bool avoid_code_without_debug_info = true;
48730fdc8d8SChris Lattner             SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
48817a6ad05SGreg Clayton             thread_sp->QueueThreadPlanForStepRange (abort_other_plans,
48930fdc8d8SChris Lattner                                                     eStepTypeInto,
49030fdc8d8SChris Lattner                                                     sc.line_entry.range,
49130fdc8d8SChris Lattner                                                     sc,
492474966a4SGreg Clayton                                                     stop_other_threads,
493474966a4SGreg Clayton                                                     avoid_code_without_debug_info);
49430fdc8d8SChris Lattner         }
49530fdc8d8SChris Lattner         else
49630fdc8d8SChris Lattner         {
49717a6ad05SGreg Clayton             thread_sp->QueueThreadPlanForStepSingleInstruction (false,
49830fdc8d8SChris Lattner                                                                 abort_other_plans,
49930fdc8d8SChris Lattner                                                                 stop_other_threads);
50030fdc8d8SChris Lattner         }
50130fdc8d8SChris Lattner 
50217a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
50330fdc8d8SChris Lattner         // Why do we need to set the current thread by ID here???
50417a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
5055d5028b5SGreg Clayton         Error error (process.Resume());
5065d5028b5SGreg Clayton         if (error.Success())
5075d5028b5SGreg Clayton         {
5085d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5095d5028b5SGreg Clayton             // process to stop yet again!
5105d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
5115d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
5125d5028b5SGreg Clayton         }
51330fdc8d8SChris Lattner     }
51430fdc8d8SChris Lattner }
51530fdc8d8SChris Lattner 
51630fdc8d8SChris Lattner void
51730fdc8d8SChris Lattner SBThread::StepOut ()
51830fdc8d8SChris Lattner {
5192d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
520ceb6b139SCaroline Tice 
52117a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
522ceb6b139SCaroline Tice 
52317a6ad05SGreg Clayton     if (log)
52417a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::StepOut ()", thread_sp.get());
52517a6ad05SGreg Clayton 
52617a6ad05SGreg Clayton     if (thread_sp)
52730fdc8d8SChris Lattner     {
52817a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
52930fdc8d8SChris Lattner         bool abort_other_plans = true;
53030fdc8d8SChris Lattner         bool stop_other_threads = true;
53130fdc8d8SChris Lattner 
53217a6ad05SGreg Clayton         thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
533481cef25SGreg Clayton                                               NULL,
534481cef25SGreg Clayton                                               false,
535481cef25SGreg Clayton                                               stop_other_threads,
536481cef25SGreg Clayton                                               eVoteYes,
537481cef25SGreg Clayton                                               eVoteNoOpinion,
538481cef25SGreg Clayton                                               0);
539481cef25SGreg Clayton 
54017a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
54117a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
542481cef25SGreg Clayton         Error error (process.Resume());
543481cef25SGreg Clayton         if (error.Success())
544481cef25SGreg Clayton         {
545481cef25SGreg Clayton             // If we are doing synchronous mode, then wait for the
546481cef25SGreg Clayton             // process to stop yet again!
547481cef25SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
548481cef25SGreg Clayton                 process.WaitForProcessToStop (NULL);
549481cef25SGreg Clayton         }
550481cef25SGreg Clayton     }
551481cef25SGreg Clayton }
552481cef25SGreg Clayton 
553481cef25SGreg Clayton void
554481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
555481cef25SGreg Clayton {
556481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
557481cef25SGreg Clayton 
55817a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
55917a6ad05SGreg Clayton 
560*b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
561481cef25SGreg Clayton     if (log)
562481cef25SGreg Clayton     {
563481cef25SGreg Clayton         SBStream frame_desc_strm;
564481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
565*b9556accSGreg Clayton         log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData());
566481cef25SGreg Clayton     }
567481cef25SGreg Clayton 
56817a6ad05SGreg Clayton     if (thread_sp)
569481cef25SGreg Clayton     {
57017a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
571481cef25SGreg Clayton         bool abort_other_plans = true;
572481cef25SGreg Clayton         bool stop_other_threads = true;
573481cef25SGreg Clayton 
57417a6ad05SGreg Clayton         thread_sp->QueueThreadPlanForStepOut (abort_other_plans,
575481cef25SGreg Clayton                                               NULL,
576481cef25SGreg Clayton                                               false,
577481cef25SGreg Clayton                                               stop_other_threads,
578481cef25SGreg Clayton                                               eVoteYes,
579481cef25SGreg Clayton                                               eVoteNoOpinion,
580*b9556accSGreg Clayton                                               frame_sp->GetFrameIndex());
58130fdc8d8SChris Lattner 
58217a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
58317a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
5845d5028b5SGreg Clayton         Error error (process.Resume());
5855d5028b5SGreg Clayton         if (error.Success())
5865d5028b5SGreg Clayton         {
5875d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
5885d5028b5SGreg Clayton             // process to stop yet again!
5895d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
5905d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
5915d5028b5SGreg Clayton         }
59230fdc8d8SChris Lattner     }
59330fdc8d8SChris Lattner }
59430fdc8d8SChris Lattner 
59530fdc8d8SChris Lattner void
59630fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over)
59730fdc8d8SChris Lattner {
5982d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
599ceb6b139SCaroline Tice 
60017a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
601ceb6b139SCaroline Tice 
60217a6ad05SGreg Clayton     if (log)
60317a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", thread_sp.get(), step_over);
60417a6ad05SGreg Clayton 
60517a6ad05SGreg Clayton     if (thread_sp)
60630fdc8d8SChris Lattner     {
60717a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
60817a6ad05SGreg Clayton         thread_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true);
60917a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
61017a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
6115d5028b5SGreg 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!
6165d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
6175d5028b5SGreg 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 
62717a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
628ceb6b139SCaroline Tice 
62917a6ad05SGreg Clayton     if (log)
63017a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", thread_sp.get(), addr);
63117a6ad05SGreg Clayton 
63217a6ad05SGreg Clayton     if (thread_sp)
63330fdc8d8SChris Lattner     {
63430fdc8d8SChris Lattner         bool abort_other_plans = true;
63530fdc8d8SChris Lattner         bool stop_other_threads = true;
63630fdc8d8SChris Lattner 
63730fdc8d8SChris Lattner         Address target_addr (NULL, addr);
63830fdc8d8SChris Lattner 
63917a6ad05SGreg Clayton         thread_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads);
64017a6ad05SGreg Clayton         Process &process = thread_sp->GetProcess();
64117a6ad05SGreg Clayton         process.GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
6425d5028b5SGreg Clayton         Error error (process.Resume());
6435d5028b5SGreg Clayton         if (error.Success())
6445d5028b5SGreg Clayton         {
6455d5028b5SGreg Clayton             // If we are doing synchronous mode, then wait for the
6465d5028b5SGreg Clayton             // process to stop yet again!
6475d5028b5SGreg Clayton             if (process.GetTarget().GetDebugger().GetAsyncExecution () == false)
6485d5028b5SGreg Clayton                 process.WaitForProcessToStop (NULL);
6495d5028b5SGreg Clayton         }
65030fdc8d8SChris Lattner     }
65130fdc8d8SChris Lattner }
65230fdc8d8SChris Lattner 
653481cef25SGreg Clayton SBError
654481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
655481cef25SGreg Clayton                          lldb::SBFileSpec &sb_file_spec,
656481cef25SGreg Clayton                          uint32_t line)
657481cef25SGreg Clayton {
658481cef25SGreg Clayton     SBError sb_error;
659481cef25SGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
660481cef25SGreg Clayton     char path[PATH_MAX];
661481cef25SGreg Clayton 
66217a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
663*b9556accSGreg Clayton     StackFrameSP frame_sp (sb_frame.GetFrameSP());
66417a6ad05SGreg Clayton 
665481cef25SGreg Clayton     if (log)
666481cef25SGreg Clayton     {
667481cef25SGreg Clayton         SBStream frame_desc_strm;
668481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
669481cef25SGreg Clayton         sb_file_spec->GetPath (path, sizeof(path));
670481cef25SGreg Clayton         log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
67117a6ad05SGreg Clayton                      thread_sp.get(),
672*b9556accSGreg Clayton                      frame_sp.get(),
673481cef25SGreg Clayton                      frame_desc_strm.GetData(),
674481cef25SGreg Clayton                      path, line);
675481cef25SGreg Clayton     }
676481cef25SGreg Clayton 
67717a6ad05SGreg Clayton     if (thread_sp)
678481cef25SGreg Clayton     {
67917a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
680481cef25SGreg Clayton 
681481cef25SGreg Clayton         if (line == 0)
682481cef25SGreg Clayton         {
683481cef25SGreg Clayton             sb_error.SetErrorString("invalid line argument");
684481cef25SGreg Clayton             return sb_error;
685481cef25SGreg Clayton         }
686481cef25SGreg Clayton 
687481cef25SGreg Clayton         StackFrameSP frame_sp;
688*b9556accSGreg Clayton         if (!frame_sp)
689481cef25SGreg Clayton         {
69017a6ad05SGreg Clayton             frame_sp = thread_sp->GetSelectedFrame ();
691481cef25SGreg Clayton             if (!frame_sp)
69217a6ad05SGreg Clayton                 frame_sp = thread_sp->GetStackFrameAtIndex (0);
693481cef25SGreg Clayton         }
694481cef25SGreg Clayton 
695481cef25SGreg Clayton         SymbolContext frame_sc;
696481cef25SGreg Clayton         if (!frame_sp)
697481cef25SGreg Clayton         {
698481cef25SGreg Clayton             sb_error.SetErrorString("no valid frames in thread to step");
699481cef25SGreg Clayton             return sb_error;
700481cef25SGreg Clayton         }
701481cef25SGreg Clayton 
702481cef25SGreg Clayton         // If we have a frame, get its line
703481cef25SGreg Clayton         frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit  |
704481cef25SGreg Clayton                                                eSymbolContextFunction  |
705481cef25SGreg Clayton                                                eSymbolContextLineEntry |
706481cef25SGreg Clayton                                                eSymbolContextSymbol    );
707481cef25SGreg Clayton 
708481cef25SGreg Clayton         if (frame_sc.comp_unit == NULL)
709481cef25SGreg Clayton         {
710481cef25SGreg Clayton             sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
711481cef25SGreg Clayton             return sb_error;
712481cef25SGreg Clayton         }
713481cef25SGreg Clayton 
714481cef25SGreg Clayton         FileSpec step_file_spec;
715481cef25SGreg Clayton         if (sb_file_spec.IsValid())
716481cef25SGreg Clayton         {
717481cef25SGreg Clayton             // The file spec passed in was valid, so use it
718481cef25SGreg Clayton             step_file_spec = sb_file_spec.ref();
719481cef25SGreg Clayton         }
720481cef25SGreg Clayton         else
721481cef25SGreg Clayton         {
722481cef25SGreg Clayton             if (frame_sc.line_entry.IsValid())
723481cef25SGreg Clayton                 step_file_spec = frame_sc.line_entry.file;
724481cef25SGreg Clayton             else
725481cef25SGreg Clayton             {
726481cef25SGreg Clayton                 sb_error.SetErrorString("invalid file argument or no file for frame");
727481cef25SGreg Clayton                 return sb_error;
728481cef25SGreg Clayton             }
729481cef25SGreg Clayton         }
730481cef25SGreg Clayton 
7319b70ddb3SJim Ingham         // Grab the current function, then we will make sure the "until" address is
7329b70ddb3SJim Ingham         // within the function.  We discard addresses that are out of the current
7339b70ddb3SJim Ingham         // function, and then if there are no addresses remaining, give an appropriate
7349b70ddb3SJim Ingham         // error message.
7359b70ddb3SJim Ingham 
7369b70ddb3SJim Ingham         bool all_in_function = true;
7379b70ddb3SJim Ingham         AddressRange fun_range = frame_sc.function->GetAddressRange();
7389b70ddb3SJim Ingham 
739481cef25SGreg Clayton         std::vector<addr_t> step_over_until_addrs;
740481cef25SGreg Clayton         const bool abort_other_plans = true;
741481cef25SGreg Clayton         const bool stop_other_threads = true;
742481cef25SGreg Clayton         const bool check_inlines = true;
743481cef25SGreg Clayton         const bool exact = false;
74417a6ad05SGreg Clayton         Target *target = &thread_sp->GetProcess().GetTarget();
745481cef25SGreg Clayton 
746481cef25SGreg Clayton         SymbolContextList sc_list;
7479b70ddb3SJim Ingham         const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
7489b70ddb3SJim Ingham                                                                                line,
7499b70ddb3SJim Ingham                                                                                check_inlines,
7509b70ddb3SJim Ingham                                                                                exact,
7519b70ddb3SJim Ingham                                                                                eSymbolContextLineEntry,
7529b70ddb3SJim Ingham                                                                                sc_list);
753481cef25SGreg Clayton         if (num_matches > 0)
754481cef25SGreg Clayton         {
755481cef25SGreg Clayton             SymbolContext sc;
756481cef25SGreg Clayton             for (uint32_t i=0; i<num_matches; ++i)
757481cef25SGreg Clayton             {
758481cef25SGreg Clayton                 if (sc_list.GetContextAtIndex(i, sc))
759481cef25SGreg Clayton                 {
7609b70ddb3SJim Ingham                     addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
761481cef25SGreg Clayton                     if (step_addr != LLDB_INVALID_ADDRESS)
762481cef25SGreg Clayton                     {
7639b70ddb3SJim Ingham                         if (fun_range.ContainsLoadAddress(step_addr, target))
764481cef25SGreg Clayton                             step_over_until_addrs.push_back(step_addr);
7659b70ddb3SJim Ingham                         else
7669b70ddb3SJim Ingham                             all_in_function = false;
767481cef25SGreg Clayton                     }
768481cef25SGreg Clayton                 }
769481cef25SGreg Clayton             }
770481cef25SGreg Clayton         }
771481cef25SGreg Clayton 
772481cef25SGreg Clayton         if (step_over_until_addrs.empty())
773481cef25SGreg Clayton         {
7749b70ddb3SJim Ingham             if (all_in_function)
7759b70ddb3SJim Ingham             {
776481cef25SGreg Clayton                 step_file_spec.GetPath (path, sizeof(path));
777fd54b368SJason Molenda                 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
778481cef25SGreg Clayton             }
779481cef25SGreg Clayton             else
78086edbf41SGreg Clayton                 sb_error.SetErrorString ("step until target not in current function");
7819b70ddb3SJim Ingham         }
7829b70ddb3SJim Ingham         else
783481cef25SGreg Clayton         {
78417a6ad05SGreg Clayton             thread_sp->QueueThreadPlanForStepUntil (abort_other_plans,
785481cef25SGreg Clayton                                                     &step_over_until_addrs[0],
786481cef25SGreg Clayton                                                     step_over_until_addrs.size(),
787481cef25SGreg Clayton                                                     stop_other_threads,
788481cef25SGreg Clayton                                                     frame_sp->GetFrameIndex());
789481cef25SGreg Clayton 
79017a6ad05SGreg Clayton             thread_sp->GetProcess().GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
79117a6ad05SGreg Clayton             sb_error.ref() = thread_sp->GetProcess().Resume();
792481cef25SGreg Clayton             if (sb_error->Success())
793481cef25SGreg Clayton             {
794481cef25SGreg Clayton                 // If we are doing synchronous mode, then wait for the
795481cef25SGreg Clayton                 // process to stop yet again!
79617a6ad05SGreg Clayton                 if (thread_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false)
79717a6ad05SGreg Clayton                     thread_sp->GetProcess().WaitForProcessToStop (NULL);
798481cef25SGreg Clayton             }
799481cef25SGreg Clayton         }
800481cef25SGreg Clayton     }
801481cef25SGreg Clayton     else
802481cef25SGreg Clayton     {
803481cef25SGreg Clayton         sb_error.SetErrorString("this SBThread object is invalid");
804481cef25SGreg Clayton     }
805481cef25SGreg Clayton     return sb_error;
806481cef25SGreg Clayton }
807481cef25SGreg Clayton 
808481cef25SGreg Clayton 
809722a0cdcSGreg Clayton bool
810722a0cdcSGreg Clayton SBThread::Suspend()
811722a0cdcSGreg Clayton {
81217a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
81317a6ad05SGreg Clayton     if (thread_sp)
814722a0cdcSGreg Clayton     {
81517a6ad05SGreg Clayton         thread_sp->SetResumeState (eStateSuspended);
816722a0cdcSGreg Clayton         return true;
817722a0cdcSGreg Clayton     }
818722a0cdcSGreg Clayton     return false;
819722a0cdcSGreg Clayton }
820722a0cdcSGreg Clayton 
821722a0cdcSGreg Clayton bool
822722a0cdcSGreg Clayton SBThread::Resume ()
823722a0cdcSGreg Clayton {
82417a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
82517a6ad05SGreg Clayton     if (thread_sp)
826722a0cdcSGreg Clayton     {
82717a6ad05SGreg Clayton         thread_sp->SetResumeState (eStateRunning);
828722a0cdcSGreg Clayton         return true;
829722a0cdcSGreg Clayton     }
830722a0cdcSGreg Clayton     return false;
831722a0cdcSGreg Clayton }
832722a0cdcSGreg Clayton 
833722a0cdcSGreg Clayton bool
834722a0cdcSGreg Clayton SBThread::IsSuspended()
835722a0cdcSGreg Clayton {
83617a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
83717a6ad05SGreg Clayton     if (thread_sp)
83817a6ad05SGreg Clayton         return thread_sp->GetResumeState () == eStateSuspended;
839722a0cdcSGreg Clayton     return false;
840722a0cdcSGreg Clayton }
841722a0cdcSGreg Clayton 
84230fdc8d8SChris Lattner SBProcess
84330fdc8d8SChris Lattner SBThread::GetProcess ()
84430fdc8d8SChris Lattner {
845ceb6b139SCaroline Tice 
846*b9556accSGreg Clayton     SBProcess sb_process;
847*b9556accSGreg Clayton     ProcessSP process_sp;
84817a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
84917a6ad05SGreg Clayton     if (thread_sp)
85030fdc8d8SChris Lattner     {
85130fdc8d8SChris Lattner         // Have to go up to the target so we can get a shared pointer to our process...
852*b9556accSGreg Clayton         process_sp = thread_sp->GetProcess().GetTarget().GetProcessSP();
853*b9556accSGreg Clayton         sb_process.SetSP (process_sp);
85430fdc8d8SChris Lattner     }
855ceb6b139SCaroline Tice 
8562d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
857ceb6b139SCaroline Tice     if (log)
858ceb6b139SCaroline Tice     {
859481cef25SGreg Clayton         SBStream frame_desc_strm;
860*b9556accSGreg Clayton         sb_process.GetDescription (frame_desc_strm);
86117a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", thread_sp.get(),
862*b9556accSGreg Clayton                      process_sp.get(), frame_desc_strm.GetData());
863ceb6b139SCaroline Tice     }
864ceb6b139SCaroline Tice 
865*b9556accSGreg Clayton     return sb_process;
86630fdc8d8SChris Lattner }
86730fdc8d8SChris Lattner 
86830fdc8d8SChris Lattner uint32_t
86930fdc8d8SChris Lattner SBThread::GetNumFrames ()
87030fdc8d8SChris Lattner {
8712d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
872ceb6b139SCaroline Tice 
873ceb6b139SCaroline Tice     uint32_t num_frames = 0;
87417a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
87517a6ad05SGreg Clayton     if (thread_sp)
876af67cecdSGreg Clayton     {
87717a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
87817a6ad05SGreg Clayton         num_frames = thread_sp->GetStackFrameCount();
879af67cecdSGreg Clayton     }
880ceb6b139SCaroline Tice 
881ceb6b139SCaroline Tice     if (log)
88217a6ad05SGreg Clayton         log->Printf ("SBThread(%p)::GetNumFrames () => %u", thread_sp.get(), num_frames);
883ceb6b139SCaroline Tice 
884ceb6b139SCaroline Tice     return num_frames;
88530fdc8d8SChris Lattner }
88630fdc8d8SChris Lattner 
88730fdc8d8SChris Lattner SBFrame
88830fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx)
88930fdc8d8SChris Lattner {
8902d4edfbcSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
891ceb6b139SCaroline Tice 
89230fdc8d8SChris Lattner     SBFrame sb_frame;
893*b9556accSGreg Clayton     StackFrameSP frame_sp;
89417a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
89517a6ad05SGreg Clayton     if (thread_sp)
896af67cecdSGreg Clayton     {
89717a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
898*b9556accSGreg Clayton         frame_sp = thread_sp->GetStackFrameAtIndex (idx);
899*b9556accSGreg Clayton         sb_frame.SetFrameSP (frame_sp);
900af67cecdSGreg Clayton     }
901ceb6b139SCaroline Tice 
902ceb6b139SCaroline Tice     if (log)
903ceb6b139SCaroline Tice     {
904481cef25SGreg Clayton         SBStream frame_desc_strm;
905481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
9064838131bSGreg Clayton         log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
907*b9556accSGreg Clayton                      thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData());
908ceb6b139SCaroline Tice     }
909ceb6b139SCaroline Tice 
91030fdc8d8SChris Lattner     return sb_frame;
91130fdc8d8SChris Lattner }
91230fdc8d8SChris Lattner 
913f028a1fbSGreg Clayton lldb::SBFrame
914f028a1fbSGreg Clayton SBThread::GetSelectedFrame ()
915f028a1fbSGreg Clayton {
916f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
917f028a1fbSGreg Clayton 
918f028a1fbSGreg Clayton     SBFrame sb_frame;
919*b9556accSGreg Clayton     StackFrameSP frame_sp;
92017a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
92117a6ad05SGreg Clayton     if (thread_sp)
922af67cecdSGreg Clayton     {
92317a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
924*b9556accSGreg Clayton         frame_sp = thread_sp->GetSelectedFrame ();
925*b9556accSGreg Clayton         sb_frame.SetFrameSP (frame_sp);
926af67cecdSGreg Clayton     }
927f028a1fbSGreg Clayton 
928f028a1fbSGreg Clayton     if (log)
929f028a1fbSGreg Clayton     {
930481cef25SGreg Clayton         SBStream frame_desc_strm;
931481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
932f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
933*b9556accSGreg Clayton                      thread_sp.get(), frame_sp.get(), frame_desc_strm.GetData());
934f028a1fbSGreg Clayton     }
935f028a1fbSGreg Clayton 
936f028a1fbSGreg Clayton     return sb_frame;
937f028a1fbSGreg Clayton }
938f028a1fbSGreg Clayton 
939f028a1fbSGreg Clayton lldb::SBFrame
940f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx)
941f028a1fbSGreg Clayton {
942f028a1fbSGreg Clayton     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
943f028a1fbSGreg Clayton 
944f028a1fbSGreg Clayton     SBFrame sb_frame;
945*b9556accSGreg Clayton     StackFrameSP frame_sp;
94617a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
94717a6ad05SGreg Clayton     if (thread_sp)
948f028a1fbSGreg Clayton     {
94917a6ad05SGreg Clayton         Mutex::Locker api_locker (thread_sp->GetProcess().GetTarget().GetAPIMutex());
950*b9556accSGreg Clayton         frame_sp = thread_sp->GetStackFrameAtIndex (idx);
951f028a1fbSGreg Clayton         if (frame_sp)
952f028a1fbSGreg Clayton         {
95317a6ad05SGreg Clayton             thread_sp->SetSelectedFrame (frame_sp.get());
954*b9556accSGreg Clayton             sb_frame.SetFrameSP (frame_sp);
955f028a1fbSGreg Clayton         }
956f028a1fbSGreg Clayton     }
957f028a1fbSGreg Clayton 
958f028a1fbSGreg Clayton     if (log)
959f028a1fbSGreg Clayton     {
960481cef25SGreg Clayton         SBStream frame_desc_strm;
961481cef25SGreg Clayton         sb_frame.GetDescription (frame_desc_strm);
962f028a1fbSGreg Clayton         log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
963*b9556accSGreg Clayton                      thread_sp.get(), idx, frame_sp.get(), frame_desc_strm.GetData());
964f028a1fbSGreg Clayton     }
965f028a1fbSGreg Clayton     return sb_frame;
966f028a1fbSGreg Clayton }
967f028a1fbSGreg Clayton 
968f028a1fbSGreg Clayton 
96930fdc8d8SChris Lattner bool
97030fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const
97130fdc8d8SChris Lattner {
97217a6ad05SGreg Clayton     return m_opaque_wp.lock().get() == rhs.m_opaque_wp.lock().get();
97330fdc8d8SChris Lattner }
97430fdc8d8SChris Lattner 
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 }
980dde9cff3SCaroline Tice 
981dde9cff3SCaroline Tice bool
982ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const
983ceb6b139SCaroline Tice {
984da7bc7d0SGreg Clayton     Stream &strm = description.ref();
985da7bc7d0SGreg Clayton 
98617a6ad05SGreg Clayton     ThreadSP thread_sp(m_opaque_wp.lock());
98717a6ad05SGreg Clayton     if (thread_sp)
988ceb6b139SCaroline Tice     {
98917a6ad05SGreg Clayton         strm.Printf("SBThread: tid = 0x%4.4llx", thread_sp->GetID());
990ceb6b139SCaroline Tice     }
991ceb6b139SCaroline Tice     else
992da7bc7d0SGreg Clayton         strm.PutCString ("No value");
993ceb6b139SCaroline Tice 
994ceb6b139SCaroline Tice     return true;
995ceb6b139SCaroline Tice }
996