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" 35*73ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 364c5de699SEli Friedman #include "lldb/API/SBProcess.h" 37*73ca05a2SJim Ingham #include "lldb/API/SBValue.h" 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner using namespace lldb; 4030fdc8d8SChris Lattner using namespace lldb_private; 4130fdc8d8SChris Lattner 42cfd1acedSGreg Clayton //---------------------------------------------------------------------- 43cfd1acedSGreg Clayton // Constructors 44cfd1acedSGreg Clayton //---------------------------------------------------------------------- 4530fdc8d8SChris Lattner SBThread::SBThread () : 466611103cSGreg Clayton m_opaque_sp () 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 516611103cSGreg Clayton m_opaque_sp (lldb_object_sp) 5230fdc8d8SChris Lattner { 5330fdc8d8SChris Lattner } 5430fdc8d8SChris Lattner 5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 5692ef5735SGreg Clayton m_opaque_sp (rhs.m_opaque_sp) 5730fdc8d8SChris Lattner { 5830fdc8d8SChris Lattner } 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner //---------------------------------------------------------------------- 61cfd1acedSGreg Clayton // Assignment operator 62cfd1acedSGreg Clayton //---------------------------------------------------------------------- 63cfd1acedSGreg Clayton 64cfd1acedSGreg Clayton const lldb::SBThread & 65cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 66cfd1acedSGreg Clayton { 67cfd1acedSGreg Clayton if (this != &rhs) 68cfd1acedSGreg Clayton m_opaque_sp = rhs.m_opaque_sp; 69cfd1acedSGreg Clayton return *this; 70cfd1acedSGreg Clayton } 71cfd1acedSGreg Clayton 72cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7330fdc8d8SChris Lattner // Destructor 7430fdc8d8SChris Lattner //---------------------------------------------------------------------- 7530fdc8d8SChris Lattner SBThread::~SBThread() 7630fdc8d8SChris Lattner { 7730fdc8d8SChris Lattner } 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner bool 8030fdc8d8SChris Lattner SBThread::IsValid() const 8130fdc8d8SChris Lattner { 82762f7135SGreg Clayton return m_opaque_sp; 8330fdc8d8SChris Lattner } 8430fdc8d8SChris Lattner 8548e42549SGreg Clayton void 8648e42549SGreg Clayton SBThread::Clear () 8748e42549SGreg Clayton { 8848e42549SGreg Clayton m_opaque_sp.reset(); 8948e42549SGreg Clayton } 9048e42549SGreg Clayton 9148e42549SGreg Clayton 9230fdc8d8SChris Lattner StopReason 9330fdc8d8SChris Lattner SBThread::GetStopReason() 9430fdc8d8SChris Lattner { 952d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 96ceb6b139SCaroline Tice 97ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 986611103cSGreg Clayton if (m_opaque_sp) 9930fdc8d8SChris Lattner { 100af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 101b15bfc75SJim Ingham StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 102b15bfc75SJim Ingham if (stop_info_sp) 103ceb6b139SCaroline Tice reason = stop_info_sp->GetStopReason(); 10430fdc8d8SChris Lattner } 105ceb6b139SCaroline Tice 106ceb6b139SCaroline Tice if (log) 1074838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopReason () => %s", m_opaque_sp.get(), 108750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 109ceb6b139SCaroline Tice 110ceb6b139SCaroline Tice return reason; 11130fdc8d8SChris Lattner } 11230fdc8d8SChris Lattner 11330fdc8d8SChris Lattner size_t 1144e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1154e78f606SGreg Clayton { 1164e78f606SGreg Clayton if (m_opaque_sp) 1174e78f606SGreg Clayton { 118af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 1194e78f606SGreg Clayton StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 1204e78f606SGreg Clayton if (stop_info_sp) 1214e78f606SGreg Clayton { 1224e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1234e78f606SGreg Clayton switch (reason) 1244e78f606SGreg Clayton { 1254e78f606SGreg Clayton case eStopReasonInvalid: 1264e78f606SGreg Clayton case eStopReasonNone: 1274e78f606SGreg Clayton case eStopReasonTrace: 1284e78f606SGreg Clayton case eStopReasonPlanComplete: 1294e78f606SGreg Clayton // There is no data for these stop reasons. 1304e78f606SGreg Clayton return 0; 1314e78f606SGreg Clayton 1324e78f606SGreg Clayton case eStopReasonBreakpoint: 1334e78f606SGreg Clayton { 1344e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1354e78f606SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 1364e78f606SGreg Clayton if (bp_site_sp) 1374e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1384e78f606SGreg Clayton else 1394e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1404e78f606SGreg Clayton } 1414e78f606SGreg Clayton break; 1424e78f606SGreg Clayton 1434e78f606SGreg Clayton case eStopReasonWatchpoint: 1444e78f606SGreg Clayton assert (!"implement watchpoint support in SBThread::GetStopReasonDataCount ()"); 1454e78f606SGreg Clayton return 0; // We don't have watchpoint support yet... 1464e78f606SGreg Clayton 1474e78f606SGreg Clayton case eStopReasonSignal: 1484e78f606SGreg Clayton return 1; 1494e78f606SGreg Clayton 1504e78f606SGreg Clayton case eStopReasonException: 1514e78f606SGreg Clayton return 1; 1524e78f606SGreg Clayton } 1534e78f606SGreg Clayton } 1544e78f606SGreg Clayton } 1554e78f606SGreg Clayton return 0; 1564e78f606SGreg Clayton } 1574e78f606SGreg Clayton 1584e78f606SGreg Clayton uint64_t 1594e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1604e78f606SGreg Clayton { 1614e78f606SGreg Clayton if (m_opaque_sp) 1624e78f606SGreg Clayton { 163af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 1644e78f606SGreg Clayton StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 1654e78f606SGreg Clayton if (stop_info_sp) 1664e78f606SGreg Clayton { 1674e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1684e78f606SGreg Clayton switch (reason) 1694e78f606SGreg Clayton { 1704e78f606SGreg Clayton case eStopReasonInvalid: 1714e78f606SGreg Clayton case eStopReasonNone: 1724e78f606SGreg Clayton case eStopReasonTrace: 1734e78f606SGreg Clayton case eStopReasonPlanComplete: 1744e78f606SGreg Clayton // There is no data for these stop reasons. 1754e78f606SGreg Clayton return 0; 1764e78f606SGreg Clayton 1774e78f606SGreg Clayton case eStopReasonBreakpoint: 1784e78f606SGreg Clayton { 1794e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1804e78f606SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (m_opaque_sp->GetProcess().GetBreakpointSiteList().FindByID (site_id)); 1814e78f606SGreg Clayton if (bp_site_sp) 1824e78f606SGreg Clayton { 1834e78f606SGreg Clayton uint32_t bp_index = idx / 2; 1844e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 1854e78f606SGreg Clayton if (bp_loc_sp) 1864e78f606SGreg Clayton { 1874e78f606SGreg Clayton if (bp_index & 1) 1884e78f606SGreg Clayton { 1894e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 1904e78f606SGreg Clayton return bp_loc_sp->GetID(); 1914e78f606SGreg Clayton } 1924e78f606SGreg Clayton else 1934e78f606SGreg Clayton { 1944e78f606SGreg Clayton // Even idx, return the breakpoint ID 1954e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 1964e78f606SGreg Clayton } 1974e78f606SGreg Clayton } 1984e78f606SGreg Clayton } 1994e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2004e78f606SGreg Clayton } 2014e78f606SGreg Clayton break; 2024e78f606SGreg Clayton 2034e78f606SGreg Clayton case eStopReasonWatchpoint: 2044e78f606SGreg Clayton assert (!"implement watchpoint support in SBThread::GetStopReasonDataCount ()"); 2054e78f606SGreg Clayton return 0; // We don't have watchpoint support yet... 2064e78f606SGreg Clayton 2074e78f606SGreg Clayton case eStopReasonSignal: 2084e78f606SGreg Clayton return stop_info_sp->GetValue(); 2094e78f606SGreg Clayton 2104e78f606SGreg Clayton case eStopReasonException: 2114e78f606SGreg Clayton return stop_info_sp->GetValue(); 2124e78f606SGreg Clayton } 2134e78f606SGreg Clayton } 2144e78f606SGreg Clayton } 2154e78f606SGreg Clayton return 0; 2164e78f606SGreg Clayton } 2174e78f606SGreg Clayton 2184e78f606SGreg Clayton size_t 21930fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 22030fdc8d8SChris Lattner { 2212d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 222ceb6b139SCaroline Tice 2236611103cSGreg Clayton if (m_opaque_sp) 22430fdc8d8SChris Lattner { 225af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 226b15bfc75SJim Ingham StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 227b15bfc75SJim Ingham if (stop_info_sp) 22830fdc8d8SChris Lattner { 229b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 23030fdc8d8SChris Lattner if (stop_desc) 23130fdc8d8SChris Lattner { 232ceb6b139SCaroline Tice if (log) 2334838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 234750cd175SCaroline Tice m_opaque_sp.get(), stop_desc); 23530fdc8d8SChris Lattner if (dst) 23630fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 23730fdc8d8SChris Lattner else 23830fdc8d8SChris Lattner { 23930fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 24030fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 24130fdc8d8SChris Lattner } 24230fdc8d8SChris Lattner } 24330fdc8d8SChris Lattner else 24430fdc8d8SChris Lattner { 24530fdc8d8SChris Lattner size_t stop_desc_len = 0; 246b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 24730fdc8d8SChris Lattner { 24830fdc8d8SChris Lattner case eStopReasonTrace: 24930fdc8d8SChris Lattner case eStopReasonPlanComplete: 25030fdc8d8SChris Lattner { 25130fdc8d8SChris Lattner static char trace_desc[] = "step"; 25230fdc8d8SChris Lattner stop_desc = trace_desc; 25330fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 25430fdc8d8SChris Lattner } 25530fdc8d8SChris Lattner break; 25630fdc8d8SChris Lattner 25730fdc8d8SChris Lattner case eStopReasonBreakpoint: 25830fdc8d8SChris Lattner { 25930fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 26030fdc8d8SChris Lattner stop_desc = bp_desc; 26130fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 26230fdc8d8SChris Lattner } 26330fdc8d8SChris Lattner break; 26430fdc8d8SChris Lattner 26530fdc8d8SChris Lattner case eStopReasonWatchpoint: 26630fdc8d8SChris Lattner { 26730fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 26830fdc8d8SChris Lattner stop_desc = wp_desc; 26930fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 27030fdc8d8SChris Lattner } 27130fdc8d8SChris Lattner break; 27230fdc8d8SChris Lattner 27330fdc8d8SChris Lattner case eStopReasonSignal: 27430fdc8d8SChris Lattner { 275b15bfc75SJim Ingham stop_desc = m_opaque_sp->GetProcess().GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 27630fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 27730fdc8d8SChris Lattner { 27830fdc8d8SChris Lattner static char signal_desc[] = "signal"; 27930fdc8d8SChris Lattner stop_desc = signal_desc; 28030fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 28130fdc8d8SChris Lattner } 28230fdc8d8SChris Lattner } 28330fdc8d8SChris Lattner break; 28430fdc8d8SChris Lattner 28530fdc8d8SChris Lattner case eStopReasonException: 28630fdc8d8SChris Lattner { 28730fdc8d8SChris Lattner char exc_desc[] = "exception"; 28830fdc8d8SChris Lattner stop_desc = exc_desc; 28930fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 29030fdc8d8SChris Lattner } 29130fdc8d8SChris Lattner break; 292c982c768SGreg Clayton 293c982c768SGreg Clayton default: 294c982c768SGreg Clayton break; 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner 29730fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 29830fdc8d8SChris Lattner { 299ceb6b139SCaroline Tice if (log) 30093aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 301750cd175SCaroline Tice m_opaque_sp.get(), stop_desc); 302ceb6b139SCaroline Tice 30330fdc8d8SChris Lattner if (dst) 30430fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 30530fdc8d8SChris Lattner 30630fdc8d8SChris Lattner if (stop_desc_len == 0) 30730fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 30830fdc8d8SChris Lattner 30930fdc8d8SChris Lattner return stop_desc_len; 31030fdc8d8SChris Lattner } 31130fdc8d8SChris Lattner } 31230fdc8d8SChris Lattner } 31330fdc8d8SChris Lattner } 31430fdc8d8SChris Lattner if (dst) 31530fdc8d8SChris Lattner *dst = 0; 31630fdc8d8SChris Lattner return 0; 31730fdc8d8SChris Lattner } 31830fdc8d8SChris Lattner 319*73ca05a2SJim Ingham SBValue 320*73ca05a2SJim Ingham SBThread::GetStopReturnValue () 321*73ca05a2SJim Ingham { 322*73ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 323*73ca05a2SJim Ingham if (m_opaque_sp) 324*73ca05a2SJim Ingham { 325*73ca05a2SJim Ingham Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 326*73ca05a2SJim Ingham StopInfoSP stop_info_sp = m_opaque_sp->GetStopInfo (); 327*73ca05a2SJim Ingham if (stop_info_sp) 328*73ca05a2SJim Ingham { 329*73ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 330*73ca05a2SJim Ingham } 331*73ca05a2SJim Ingham } 332*73ca05a2SJim Ingham 333*73ca05a2SJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 334*73ca05a2SJim Ingham if (log) 335*73ca05a2SJim Ingham log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", m_opaque_sp.get(), 336*73ca05a2SJim Ingham return_valobj_sp.get() 337*73ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 338*73ca05a2SJim Ingham : "<no return value>"); 339*73ca05a2SJim Ingham 340*73ca05a2SJim Ingham return SBValue (return_valobj_sp); 341*73ca05a2SJim Ingham } 342*73ca05a2SJim Ingham 34330fdc8d8SChris Lattner void 34430fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 34530fdc8d8SChris Lattner { 3466611103cSGreg Clayton m_opaque_sp = lldb_object_sp; 34730fdc8d8SChris Lattner } 34830fdc8d8SChris Lattner 34930fdc8d8SChris Lattner 35030fdc8d8SChris Lattner lldb::tid_t 35130fdc8d8SChris Lattner SBThread::GetThreadID () const 35230fdc8d8SChris Lattner { 3532d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 354ceb6b139SCaroline Tice 355af67cecdSGreg Clayton lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 3566611103cSGreg Clayton if (m_opaque_sp) 357af67cecdSGreg Clayton tid = m_opaque_sp->GetID(); 358ceb6b139SCaroline Tice 359ceb6b139SCaroline Tice if (log) 36061e7a58cSGreg Clayton log->Printf ("SBThread(%p)::GetThreadID () => 0x%4.4llx", m_opaque_sp.get(), tid); 361ceb6b139SCaroline Tice 362af67cecdSGreg Clayton return tid; 36330fdc8d8SChris Lattner } 36430fdc8d8SChris Lattner 36530fdc8d8SChris Lattner uint32_t 36630fdc8d8SChris Lattner SBThread::GetIndexID () const 36730fdc8d8SChris Lattner { 3686611103cSGreg Clayton if (m_opaque_sp) 3696611103cSGreg Clayton return m_opaque_sp->GetIndexID(); 37030fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 37130fdc8d8SChris Lattner } 37230fdc8d8SChris Lattner const char * 37330fdc8d8SChris Lattner SBThread::GetName () const 37430fdc8d8SChris Lattner { 3754838131bSGreg Clayton const char *name = NULL; 3766611103cSGreg Clayton if (m_opaque_sp) 377af67cecdSGreg Clayton { 378af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 3794838131bSGreg Clayton name = m_opaque_sp->GetName(); 380af67cecdSGreg Clayton } 381ceb6b139SCaroline Tice 3822d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 383ceb6b139SCaroline Tice if (log) 3844838131bSGreg Clayton log->Printf ("SBThread(%p)::GetName () => %s", m_opaque_sp.get(), name ? name : "NULL"); 385ceb6b139SCaroline Tice 3864838131bSGreg Clayton return name; 38730fdc8d8SChris Lattner } 38830fdc8d8SChris Lattner 38930fdc8d8SChris Lattner const char * 39030fdc8d8SChris Lattner SBThread::GetQueueName () const 39130fdc8d8SChris Lattner { 3924838131bSGreg Clayton const char *name = NULL; 3936611103cSGreg Clayton if (m_opaque_sp) 394af67cecdSGreg Clayton { 395af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 3964838131bSGreg Clayton name = m_opaque_sp->GetQueueName(); 397af67cecdSGreg Clayton } 398ceb6b139SCaroline Tice 3992d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 400ceb6b139SCaroline Tice if (log) 4014838131bSGreg Clayton log->Printf ("SBThread(%p)::GetQueueName () => %s", m_opaque_sp.get(), name ? name : "NULL"); 402ceb6b139SCaroline Tice 4034838131bSGreg Clayton return name; 40430fdc8d8SChris Lattner } 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner 40730fdc8d8SChris Lattner void 40830fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 40930fdc8d8SChris Lattner { 4102d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 411ceb6b139SCaroline Tice 412ceb6b139SCaroline Tice if (log) 41393aa84e8SGreg Clayton log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", m_opaque_sp.get(), 414ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 415ceb6b139SCaroline Tice 4166611103cSGreg Clayton if (m_opaque_sp) 41730fdc8d8SChris Lattner { 418af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 41930fdc8d8SChris Lattner bool abort_other_plans = true; 4206611103cSGreg Clayton StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0)); 42130fdc8d8SChris Lattner 42230fdc8d8SChris Lattner if (frame_sp) 42330fdc8d8SChris Lattner { 42430fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 42530fdc8d8SChris Lattner { 42630fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 4276611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, 42830fdc8d8SChris Lattner eStepTypeOver, 42930fdc8d8SChris Lattner sc.line_entry.range, 43030fdc8d8SChris Lattner sc, 431474966a4SGreg Clayton stop_other_threads, 432474966a4SGreg Clayton false); 43330fdc8d8SChris Lattner 43430fdc8d8SChris Lattner } 43530fdc8d8SChris Lattner else 43630fdc8d8SChris Lattner { 4376611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForStepSingleInstruction (true, 43830fdc8d8SChris Lattner abort_other_plans, 43930fdc8d8SChris Lattner stop_other_threads); 44030fdc8d8SChris Lattner } 44130fdc8d8SChris Lattner } 44230fdc8d8SChris Lattner 4436611103cSGreg Clayton Process &process = m_opaque_sp->GetProcess(); 44430fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 4452976d00aSJim Ingham process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 4465d5028b5SGreg Clayton Error error (process.Resume()); 4475d5028b5SGreg Clayton if (error.Success()) 4485d5028b5SGreg Clayton { 4495d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 4505d5028b5SGreg Clayton // process to stop yet again! 4515d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 4525d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 4535d5028b5SGreg Clayton } 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner } 45630fdc8d8SChris Lattner 45730fdc8d8SChris Lattner void 45830fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 45930fdc8d8SChris Lattner { 4602d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 461ceb6b139SCaroline Tice 462ceb6b139SCaroline Tice if (log) 46393aa84e8SGreg Clayton log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", m_opaque_sp.get(), 464ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 465ceb6b139SCaroline Tice 4666611103cSGreg Clayton if (m_opaque_sp) 46730fdc8d8SChris Lattner { 468af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 46930fdc8d8SChris Lattner bool abort_other_plans = true; 47030fdc8d8SChris Lattner 4716611103cSGreg Clayton StackFrameSP frame_sp(m_opaque_sp->GetStackFrameAtIndex (0)); 47230fdc8d8SChris Lattner 47330fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 47430fdc8d8SChris Lattner { 475474966a4SGreg Clayton bool avoid_code_without_debug_info = true; 47630fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 4776611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForStepRange (abort_other_plans, 47830fdc8d8SChris Lattner eStepTypeInto, 47930fdc8d8SChris Lattner sc.line_entry.range, 48030fdc8d8SChris Lattner sc, 481474966a4SGreg Clayton stop_other_threads, 482474966a4SGreg Clayton avoid_code_without_debug_info); 48330fdc8d8SChris Lattner } 48430fdc8d8SChris Lattner else 48530fdc8d8SChris Lattner { 4866611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForStepSingleInstruction (false, 48730fdc8d8SChris Lattner abort_other_plans, 48830fdc8d8SChris Lattner stop_other_threads); 48930fdc8d8SChris Lattner } 49030fdc8d8SChris Lattner 4916611103cSGreg Clayton Process &process = m_opaque_sp->GetProcess(); 49230fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 4932976d00aSJim Ingham process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 4945d5028b5SGreg Clayton Error error (process.Resume()); 4955d5028b5SGreg Clayton if (error.Success()) 4965d5028b5SGreg Clayton { 4975d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 4985d5028b5SGreg Clayton // process to stop yet again! 4995d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 5005d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 5015d5028b5SGreg Clayton } 50230fdc8d8SChris Lattner } 50330fdc8d8SChris Lattner } 50430fdc8d8SChris Lattner 50530fdc8d8SChris Lattner void 50630fdc8d8SChris Lattner SBThread::StepOut () 50730fdc8d8SChris Lattner { 5082d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 509ceb6b139SCaroline Tice 510ceb6b139SCaroline Tice if (log) 5114838131bSGreg Clayton log->Printf ("SBThread(%p)::StepOut ()", m_opaque_sp.get()); 512ceb6b139SCaroline Tice 5136611103cSGreg Clayton if (m_opaque_sp) 51430fdc8d8SChris Lattner { 515af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 51630fdc8d8SChris Lattner bool abort_other_plans = true; 51730fdc8d8SChris Lattner bool stop_other_threads = true; 51830fdc8d8SChris Lattner 519481cef25SGreg Clayton m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, 520481cef25SGreg Clayton NULL, 521481cef25SGreg Clayton false, 522481cef25SGreg Clayton stop_other_threads, 523481cef25SGreg Clayton eVoteYes, 524481cef25SGreg Clayton eVoteNoOpinion, 525481cef25SGreg Clayton 0); 526481cef25SGreg Clayton 527481cef25SGreg Clayton Process &process = m_opaque_sp->GetProcess(); 528481cef25SGreg Clayton process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 529481cef25SGreg Clayton Error error (process.Resume()); 530481cef25SGreg Clayton if (error.Success()) 531481cef25SGreg Clayton { 532481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 533481cef25SGreg Clayton // process to stop yet again! 534481cef25SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 535481cef25SGreg Clayton process.WaitForProcessToStop (NULL); 536481cef25SGreg Clayton } 537481cef25SGreg Clayton } 538481cef25SGreg Clayton } 539481cef25SGreg Clayton 540481cef25SGreg Clayton void 541481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 542481cef25SGreg Clayton { 543481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 544481cef25SGreg Clayton 545481cef25SGreg Clayton if (log) 546481cef25SGreg Clayton { 547481cef25SGreg Clayton SBStream frame_desc_strm; 548481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 549481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData()); 550481cef25SGreg Clayton } 551481cef25SGreg Clayton 552481cef25SGreg Clayton if (m_opaque_sp) 553481cef25SGreg Clayton { 554481cef25SGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 555481cef25SGreg Clayton bool abort_other_plans = true; 556481cef25SGreg Clayton bool stop_other_threads = true; 557481cef25SGreg Clayton 558481cef25SGreg Clayton m_opaque_sp->QueueThreadPlanForStepOut (abort_other_plans, 559481cef25SGreg Clayton NULL, 560481cef25SGreg Clayton false, 561481cef25SGreg Clayton stop_other_threads, 562481cef25SGreg Clayton eVoteYes, 563481cef25SGreg Clayton eVoteNoOpinion, 564481cef25SGreg Clayton sb_frame->GetFrameIndex()); 56530fdc8d8SChris Lattner 5666611103cSGreg Clayton Process &process = m_opaque_sp->GetProcess(); 5672976d00aSJim Ingham process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 5685d5028b5SGreg Clayton Error error (process.Resume()); 5695d5028b5SGreg Clayton if (error.Success()) 5705d5028b5SGreg Clayton { 5715d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5725d5028b5SGreg Clayton // process to stop yet again! 5735d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 5745d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 5755d5028b5SGreg Clayton } 57630fdc8d8SChris Lattner } 57730fdc8d8SChris Lattner } 57830fdc8d8SChris Lattner 57930fdc8d8SChris Lattner void 58030fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 58130fdc8d8SChris Lattner { 5822d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 583ceb6b139SCaroline Tice 584ceb6b139SCaroline Tice if (log) 58593aa84e8SGreg Clayton log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", m_opaque_sp.get(), step_over); 586ceb6b139SCaroline Tice 5876611103cSGreg Clayton if (m_opaque_sp) 58830fdc8d8SChris Lattner { 589af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 5906611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 5916611103cSGreg Clayton Process &process = m_opaque_sp->GetProcess(); 5922976d00aSJim Ingham process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 5935d5028b5SGreg Clayton Error error (process.Resume()); 5945d5028b5SGreg Clayton if (error.Success()) 5955d5028b5SGreg Clayton { 5965d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5975d5028b5SGreg Clayton // process to stop yet again! 5985d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 5995d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 6005d5028b5SGreg Clayton } 60130fdc8d8SChris Lattner } 60230fdc8d8SChris Lattner } 60330fdc8d8SChris Lattner 60430fdc8d8SChris Lattner void 60530fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 60630fdc8d8SChris Lattner { 6072d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 608ceb6b139SCaroline Tice 609ceb6b139SCaroline Tice if (log) 61093aa84e8SGreg Clayton log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", m_opaque_sp.get(), addr); 611ceb6b139SCaroline Tice 6126611103cSGreg Clayton if (m_opaque_sp) 61330fdc8d8SChris Lattner { 61430fdc8d8SChris Lattner bool abort_other_plans = true; 61530fdc8d8SChris Lattner bool stop_other_threads = true; 61630fdc8d8SChris Lattner 61730fdc8d8SChris Lattner Address target_addr (NULL, addr); 61830fdc8d8SChris Lattner 6196611103cSGreg Clayton m_opaque_sp->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 6206611103cSGreg Clayton Process &process = m_opaque_sp->GetProcess(); 6212976d00aSJim Ingham process.GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 6225d5028b5SGreg Clayton Error error (process.Resume()); 6235d5028b5SGreg Clayton if (error.Success()) 6245d5028b5SGreg Clayton { 6255d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 6265d5028b5SGreg Clayton // process to stop yet again! 6275d5028b5SGreg Clayton if (process.GetTarget().GetDebugger().GetAsyncExecution () == false) 6285d5028b5SGreg Clayton process.WaitForProcessToStop (NULL); 6295d5028b5SGreg Clayton } 63030fdc8d8SChris Lattner } 63130fdc8d8SChris Lattner } 63230fdc8d8SChris Lattner 633481cef25SGreg Clayton SBError 634481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 635481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 636481cef25SGreg Clayton uint32_t line) 637481cef25SGreg Clayton { 638481cef25SGreg Clayton SBError sb_error; 639481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 640481cef25SGreg Clayton char path[PATH_MAX]; 641481cef25SGreg Clayton 642481cef25SGreg Clayton if (log) 643481cef25SGreg Clayton { 644481cef25SGreg Clayton SBStream frame_desc_strm; 645481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 646481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 647481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 648481cef25SGreg Clayton m_opaque_sp.get(), 649481cef25SGreg Clayton sb_frame.get(), 650481cef25SGreg Clayton frame_desc_strm.GetData(), 651481cef25SGreg Clayton path, line); 652481cef25SGreg Clayton } 653481cef25SGreg Clayton 654481cef25SGreg Clayton if (m_opaque_sp) 655481cef25SGreg Clayton { 656481cef25SGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 657481cef25SGreg Clayton 658481cef25SGreg Clayton if (line == 0) 659481cef25SGreg Clayton { 660481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 661481cef25SGreg Clayton return sb_error; 662481cef25SGreg Clayton } 663481cef25SGreg Clayton 664481cef25SGreg Clayton StackFrameSP frame_sp; 665481cef25SGreg Clayton if (sb_frame.IsValid()) 666481cef25SGreg Clayton frame_sp = sb_frame.get_sp(); 667481cef25SGreg Clayton else 668481cef25SGreg Clayton { 669481cef25SGreg Clayton frame_sp = m_opaque_sp->GetSelectedFrame (); 670481cef25SGreg Clayton if (!frame_sp) 671481cef25SGreg Clayton frame_sp = m_opaque_sp->GetStackFrameAtIndex (0); 672481cef25SGreg Clayton } 673481cef25SGreg Clayton 674481cef25SGreg Clayton SymbolContext frame_sc; 675481cef25SGreg Clayton if (!frame_sp) 676481cef25SGreg Clayton { 677481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 678481cef25SGreg Clayton return sb_error; 679481cef25SGreg Clayton } 680481cef25SGreg Clayton 681481cef25SGreg Clayton // If we have a frame, get its line 682481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 683481cef25SGreg Clayton eSymbolContextFunction | 684481cef25SGreg Clayton eSymbolContextLineEntry | 685481cef25SGreg Clayton eSymbolContextSymbol ); 686481cef25SGreg Clayton 687481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 688481cef25SGreg Clayton { 689481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 690481cef25SGreg Clayton return sb_error; 691481cef25SGreg Clayton } 692481cef25SGreg Clayton 693481cef25SGreg Clayton FileSpec step_file_spec; 694481cef25SGreg Clayton if (sb_file_spec.IsValid()) 695481cef25SGreg Clayton { 696481cef25SGreg Clayton // The file spec passed in was valid, so use it 697481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 698481cef25SGreg Clayton } 699481cef25SGreg Clayton else 700481cef25SGreg Clayton { 701481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 702481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 703481cef25SGreg Clayton else 704481cef25SGreg Clayton { 705481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 706481cef25SGreg Clayton return sb_error; 707481cef25SGreg Clayton } 708481cef25SGreg Clayton } 709481cef25SGreg Clayton 7109b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 7119b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 7129b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 7139b70ddb3SJim Ingham // error message. 7149b70ddb3SJim Ingham 7159b70ddb3SJim Ingham bool all_in_function = true; 7169b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 7179b70ddb3SJim Ingham 718481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 719481cef25SGreg Clayton const bool abort_other_plans = true; 720481cef25SGreg Clayton const bool stop_other_threads = true; 721481cef25SGreg Clayton const bool check_inlines = true; 722481cef25SGreg Clayton const bool exact = false; 7239b70ddb3SJim Ingham Target *target = &m_opaque_sp->GetProcess().GetTarget(); 724481cef25SGreg Clayton 725481cef25SGreg Clayton SymbolContextList sc_list; 7269b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 7279b70ddb3SJim Ingham line, 7289b70ddb3SJim Ingham check_inlines, 7299b70ddb3SJim Ingham exact, 7309b70ddb3SJim Ingham eSymbolContextLineEntry, 7319b70ddb3SJim Ingham sc_list); 732481cef25SGreg Clayton if (num_matches > 0) 733481cef25SGreg Clayton { 734481cef25SGreg Clayton SymbolContext sc; 735481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 736481cef25SGreg Clayton { 737481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 738481cef25SGreg Clayton { 7399b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 740481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 741481cef25SGreg Clayton { 7429b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 743481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 7449b70ddb3SJim Ingham else 7459b70ddb3SJim Ingham all_in_function = false; 746481cef25SGreg Clayton } 747481cef25SGreg Clayton } 748481cef25SGreg Clayton } 749481cef25SGreg Clayton } 750481cef25SGreg Clayton 751481cef25SGreg Clayton if (step_over_until_addrs.empty()) 752481cef25SGreg Clayton { 7539b70ddb3SJim Ingham if (all_in_function) 7549b70ddb3SJim Ingham { 755481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 756fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 757481cef25SGreg Clayton } 758481cef25SGreg Clayton else 75986edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 7609b70ddb3SJim Ingham } 7619b70ddb3SJim Ingham else 762481cef25SGreg Clayton { 763481cef25SGreg Clayton m_opaque_sp->QueueThreadPlanForStepUntil (abort_other_plans, 764481cef25SGreg Clayton &step_over_until_addrs[0], 765481cef25SGreg Clayton step_over_until_addrs.size(), 766481cef25SGreg Clayton stop_other_threads, 767481cef25SGreg Clayton frame_sp->GetFrameIndex()); 768481cef25SGreg Clayton 769481cef25SGreg Clayton m_opaque_sp->GetProcess().GetThreadList().SetSelectedThreadByID (m_opaque_sp->GetID()); 770481cef25SGreg Clayton sb_error.ref() = m_opaque_sp->GetProcess().Resume(); 771481cef25SGreg Clayton if (sb_error->Success()) 772481cef25SGreg Clayton { 773481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 774481cef25SGreg Clayton // process to stop yet again! 775481cef25SGreg Clayton if (m_opaque_sp->GetProcess().GetTarget().GetDebugger().GetAsyncExecution () == false) 776481cef25SGreg Clayton m_opaque_sp->GetProcess().WaitForProcessToStop (NULL); 777481cef25SGreg Clayton } 778481cef25SGreg Clayton } 779481cef25SGreg Clayton } 780481cef25SGreg Clayton else 781481cef25SGreg Clayton { 782481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 783481cef25SGreg Clayton } 784481cef25SGreg Clayton return sb_error; 785481cef25SGreg Clayton } 786481cef25SGreg Clayton 787481cef25SGreg Clayton 788722a0cdcSGreg Clayton bool 789722a0cdcSGreg Clayton SBThread::Suspend() 790722a0cdcSGreg Clayton { 791722a0cdcSGreg Clayton if (m_opaque_sp) 792722a0cdcSGreg Clayton { 793722a0cdcSGreg Clayton m_opaque_sp->SetResumeState (eStateSuspended); 794722a0cdcSGreg Clayton return true; 795722a0cdcSGreg Clayton } 796722a0cdcSGreg Clayton return false; 797722a0cdcSGreg Clayton } 798722a0cdcSGreg Clayton 799722a0cdcSGreg Clayton bool 800722a0cdcSGreg Clayton SBThread::Resume () 801722a0cdcSGreg Clayton { 802722a0cdcSGreg Clayton if (m_opaque_sp) 803722a0cdcSGreg Clayton { 804722a0cdcSGreg Clayton m_opaque_sp->SetResumeState (eStateRunning); 805722a0cdcSGreg Clayton return true; 806722a0cdcSGreg Clayton } 807722a0cdcSGreg Clayton return false; 808722a0cdcSGreg Clayton } 809722a0cdcSGreg Clayton 810722a0cdcSGreg Clayton bool 811722a0cdcSGreg Clayton SBThread::IsSuspended() 812722a0cdcSGreg Clayton { 813722a0cdcSGreg Clayton if (m_opaque_sp) 8149566143fSGreg Clayton return m_opaque_sp->GetResumeState () == eStateSuspended; 815722a0cdcSGreg Clayton return false; 816722a0cdcSGreg Clayton } 817722a0cdcSGreg Clayton 81830fdc8d8SChris Lattner SBProcess 81930fdc8d8SChris Lattner SBThread::GetProcess () 82030fdc8d8SChris Lattner { 821ceb6b139SCaroline Tice 82230fdc8d8SChris Lattner SBProcess process; 8236611103cSGreg Clayton if (m_opaque_sp) 82430fdc8d8SChris Lattner { 82530fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 8266611103cSGreg Clayton process.SetProcess(m_opaque_sp->GetProcess().GetTarget().GetProcessSP()); 82730fdc8d8SChris Lattner } 828ceb6b139SCaroline Tice 8292d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 830ceb6b139SCaroline Tice if (log) 831ceb6b139SCaroline Tice { 832481cef25SGreg Clayton SBStream frame_desc_strm; 833481cef25SGreg Clayton process.GetDescription (frame_desc_strm); 8344838131bSGreg Clayton log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", m_opaque_sp.get(), 835481cef25SGreg Clayton process.get(), frame_desc_strm.GetData()); 836ceb6b139SCaroline Tice } 837ceb6b139SCaroline Tice 83830fdc8d8SChris Lattner return process; 83930fdc8d8SChris Lattner } 84030fdc8d8SChris Lattner 84130fdc8d8SChris Lattner uint32_t 84230fdc8d8SChris Lattner SBThread::GetNumFrames () 84330fdc8d8SChris Lattner { 8442d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 845ceb6b139SCaroline Tice 846ceb6b139SCaroline Tice uint32_t num_frames = 0; 8476611103cSGreg Clayton if (m_opaque_sp) 848af67cecdSGreg Clayton { 849af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 850ceb6b139SCaroline Tice num_frames = m_opaque_sp->GetStackFrameCount(); 851af67cecdSGreg Clayton } 852ceb6b139SCaroline Tice 853ceb6b139SCaroline Tice if (log) 8544838131bSGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames () => %u", m_opaque_sp.get(), num_frames); 855ceb6b139SCaroline Tice 856ceb6b139SCaroline Tice return num_frames; 85730fdc8d8SChris Lattner } 85830fdc8d8SChris Lattner 85930fdc8d8SChris Lattner SBFrame 86030fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 86130fdc8d8SChris Lattner { 8622d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 863ceb6b139SCaroline Tice 86430fdc8d8SChris Lattner SBFrame sb_frame; 8656611103cSGreg Clayton if (m_opaque_sp) 866af67cecdSGreg Clayton { 867af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 8686611103cSGreg Clayton sb_frame.SetFrame (m_opaque_sp->GetStackFrameAtIndex (idx)); 869af67cecdSGreg Clayton } 870ceb6b139SCaroline Tice 871ceb6b139SCaroline Tice if (log) 872ceb6b139SCaroline Tice { 873481cef25SGreg Clayton SBStream frame_desc_strm; 874481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 8754838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 876481cef25SGreg Clayton m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData()); 877ceb6b139SCaroline Tice } 878ceb6b139SCaroline Tice 87930fdc8d8SChris Lattner return sb_frame; 88030fdc8d8SChris Lattner } 88130fdc8d8SChris Lattner 882f028a1fbSGreg Clayton lldb::SBFrame 883f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 884f028a1fbSGreg Clayton { 885f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 886f028a1fbSGreg Clayton 887f028a1fbSGreg Clayton SBFrame sb_frame; 888f028a1fbSGreg Clayton if (m_opaque_sp) 889af67cecdSGreg Clayton { 890af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 891f028a1fbSGreg Clayton sb_frame.SetFrame (m_opaque_sp->GetSelectedFrame ()); 892af67cecdSGreg Clayton } 893f028a1fbSGreg Clayton 894f028a1fbSGreg Clayton if (log) 895f028a1fbSGreg Clayton { 896481cef25SGreg Clayton SBStream frame_desc_strm; 897481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 898f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 899481cef25SGreg Clayton m_opaque_sp.get(), sb_frame.get(), frame_desc_strm.GetData()); 900f028a1fbSGreg Clayton } 901f028a1fbSGreg Clayton 902f028a1fbSGreg Clayton return sb_frame; 903f028a1fbSGreg Clayton } 904f028a1fbSGreg Clayton 905f028a1fbSGreg Clayton lldb::SBFrame 906f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 907f028a1fbSGreg Clayton { 908f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 909f028a1fbSGreg Clayton 910f028a1fbSGreg Clayton SBFrame sb_frame; 911f028a1fbSGreg Clayton if (m_opaque_sp) 912f028a1fbSGreg Clayton { 913af67cecdSGreg Clayton Mutex::Locker api_locker (m_opaque_sp->GetProcess().GetTarget().GetAPIMutex()); 914f028a1fbSGreg Clayton lldb::StackFrameSP frame_sp (m_opaque_sp->GetStackFrameAtIndex (idx)); 915f028a1fbSGreg Clayton if (frame_sp) 916f028a1fbSGreg Clayton { 917f028a1fbSGreg Clayton m_opaque_sp->SetSelectedFrame (frame_sp.get()); 918f028a1fbSGreg Clayton sb_frame.SetFrame (frame_sp); 919f028a1fbSGreg Clayton } 920f028a1fbSGreg Clayton } 921f028a1fbSGreg Clayton 922f028a1fbSGreg Clayton if (log) 923f028a1fbSGreg Clayton { 924481cef25SGreg Clayton SBStream frame_desc_strm; 925481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 926f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 927481cef25SGreg Clayton m_opaque_sp.get(), idx, sb_frame.get(), frame_desc_strm.GetData()); 928f028a1fbSGreg Clayton } 929f028a1fbSGreg Clayton return sb_frame; 930f028a1fbSGreg Clayton } 931f028a1fbSGreg Clayton 932f028a1fbSGreg Clayton 93330fdc8d8SChris Lattner bool 93430fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 93530fdc8d8SChris Lattner { 9366611103cSGreg Clayton return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 93730fdc8d8SChris Lattner } 93830fdc8d8SChris Lattner 93930fdc8d8SChris Lattner bool 94030fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 94130fdc8d8SChris Lattner { 9426611103cSGreg Clayton return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 94330fdc8d8SChris Lattner } 94430fdc8d8SChris Lattner 94530fdc8d8SChris Lattner lldb_private::Thread * 9464838131bSGreg Clayton SBThread::get () 94730fdc8d8SChris Lattner { 9486611103cSGreg Clayton return m_opaque_sp.get(); 94930fdc8d8SChris Lattner } 95030fdc8d8SChris Lattner 95130fdc8d8SChris Lattner const lldb_private::Thread * 95230fdc8d8SChris Lattner SBThread::operator->() const 95330fdc8d8SChris Lattner { 9546611103cSGreg Clayton return m_opaque_sp.get(); 95530fdc8d8SChris Lattner } 95630fdc8d8SChris Lattner 95730fdc8d8SChris Lattner const lldb_private::Thread & 95830fdc8d8SChris Lattner SBThread::operator*() const 95930fdc8d8SChris Lattner { 9606611103cSGreg Clayton return *m_opaque_sp; 96130fdc8d8SChris Lattner } 96230fdc8d8SChris Lattner 96330fdc8d8SChris Lattner lldb_private::Thread * 96430fdc8d8SChris Lattner SBThread::operator->() 96530fdc8d8SChris Lattner { 9666611103cSGreg Clayton return m_opaque_sp.get(); 96730fdc8d8SChris Lattner } 96830fdc8d8SChris Lattner 96930fdc8d8SChris Lattner lldb_private::Thread & 97030fdc8d8SChris Lattner SBThread::operator*() 97130fdc8d8SChris Lattner { 9726611103cSGreg Clayton return *m_opaque_sp; 97330fdc8d8SChris Lattner } 974dde9cff3SCaroline Tice 975dde9cff3SCaroline Tice bool 976ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 977ceb6b139SCaroline Tice { 978da7bc7d0SGreg Clayton Stream &strm = description.ref(); 979da7bc7d0SGreg Clayton 980ceb6b139SCaroline Tice if (m_opaque_sp) 981ceb6b139SCaroline Tice { 982da7bc7d0SGreg Clayton strm.Printf("SBThread: tid = 0x%4.4llx", m_opaque_sp->GetID()); 983ceb6b139SCaroline Tice } 984ceb6b139SCaroline Tice else 985da7bc7d0SGreg Clayton strm.PutCString ("No value"); 986ceb6b139SCaroline Tice 987ceb6b139SCaroline Tice return true; 988ceb6b139SCaroline Tice } 989