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 () : 467fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef()) 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner } 4930fdc8d8SChris Lattner 5030fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 517fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) 5230fdc8d8SChris Lattner { 5330fdc8d8SChris Lattner } 5430fdc8d8SChris Lattner 5592ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 567fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) 5730fdc8d8SChris Lattner { 587fdf9ef1SGreg Clayton 5930fdc8d8SChris Lattner } 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner //---------------------------------------------------------------------- 62cfd1acedSGreg Clayton // Assignment operator 63cfd1acedSGreg Clayton //---------------------------------------------------------------------- 64cfd1acedSGreg Clayton 65cfd1acedSGreg Clayton const lldb::SBThread & 66cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 67cfd1acedSGreg Clayton { 68cfd1acedSGreg Clayton if (this != &rhs) 697fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 70cfd1acedSGreg Clayton return *this; 71cfd1acedSGreg Clayton } 72cfd1acedSGreg Clayton 73cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7430fdc8d8SChris Lattner // Destructor 7530fdc8d8SChris Lattner //---------------------------------------------------------------------- 7630fdc8d8SChris Lattner SBThread::~SBThread() 7730fdc8d8SChris Lattner { 7830fdc8d8SChris Lattner } 7930fdc8d8SChris Lattner 8030fdc8d8SChris Lattner bool 8130fdc8d8SChris Lattner SBThread::IsValid() const 8230fdc8d8SChris Lattner { 837fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner 8648e42549SGreg Clayton void 8748e42549SGreg Clayton SBThread::Clear () 8848e42549SGreg Clayton { 897fdf9ef1SGreg Clayton m_opaque_sp->Clear(); 9048e42549SGreg Clayton } 9148e42549SGreg Clayton 9248e42549SGreg Clayton 9330fdc8d8SChris Lattner StopReason 9430fdc8d8SChris Lattner SBThread::GetStopReason() 9530fdc8d8SChris Lattner { 962d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 97ceb6b139SCaroline Tice 98ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 997fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1001ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 10130fdc8d8SChris Lattner { 1027fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1037fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1047fdf9ef1SGreg Clayton { 1051ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 1061ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 107b15bfc75SJim Ingham if (stop_info_sp) 108ceb6b139SCaroline Tice reason = stop_info_sp->GetStopReason(); 10930fdc8d8SChris Lattner } 110*c9858e4dSGreg Clayton else 111*c9858e4dSGreg Clayton { 112*c9858e4dSGreg Clayton if (log) 113*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); 114*c9858e4dSGreg Clayton } 1157fdf9ef1SGreg Clayton } 116ceb6b139SCaroline Tice 117ceb6b139SCaroline Tice if (log) 1181ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), 119750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 120ceb6b139SCaroline Tice 121ceb6b139SCaroline Tice return reason; 12230fdc8d8SChris Lattner } 12330fdc8d8SChris Lattner 12430fdc8d8SChris Lattner size_t 1254e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1264e78f606SGreg Clayton { 1277fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1281ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1294e78f606SGreg Clayton { 1307fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1317fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1327fdf9ef1SGreg Clayton { 1331ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 1341ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1354e78f606SGreg Clayton if (stop_info_sp) 1364e78f606SGreg Clayton { 1374e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1384e78f606SGreg Clayton switch (reason) 1394e78f606SGreg Clayton { 1404e78f606SGreg Clayton case eStopReasonInvalid: 1414e78f606SGreg Clayton case eStopReasonNone: 1424e78f606SGreg Clayton case eStopReasonTrace: 1434e78f606SGreg Clayton case eStopReasonPlanComplete: 1444e78f606SGreg Clayton // There is no data for these stop reasons. 1454e78f606SGreg Clayton return 0; 1464e78f606SGreg Clayton 1474e78f606SGreg Clayton case eStopReasonBreakpoint: 1484e78f606SGreg Clayton { 1494e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1501ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 1514e78f606SGreg Clayton if (bp_site_sp) 1524e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1534e78f606SGreg Clayton else 1544e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1554e78f606SGreg Clayton } 1564e78f606SGreg Clayton break; 1574e78f606SGreg Clayton 1584e78f606SGreg Clayton case eStopReasonWatchpoint: 159290fa41bSJohnny Chen return 1; 1604e78f606SGreg Clayton 1614e78f606SGreg Clayton case eStopReasonSignal: 1624e78f606SGreg Clayton return 1; 1634e78f606SGreg Clayton 1644e78f606SGreg Clayton case eStopReasonException: 1654e78f606SGreg Clayton return 1; 1664e78f606SGreg Clayton } 1674e78f606SGreg Clayton } 1684e78f606SGreg Clayton } 169*c9858e4dSGreg Clayton else 170*c9858e4dSGreg Clayton { 171*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 172*c9858e4dSGreg Clayton if (log) 173*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); 174*c9858e4dSGreg Clayton } 1757fdf9ef1SGreg Clayton } 1764e78f606SGreg Clayton return 0; 1774e78f606SGreg Clayton } 1784e78f606SGreg Clayton 1794e78f606SGreg Clayton uint64_t 1804e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1814e78f606SGreg Clayton { 1827fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1831ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1844e78f606SGreg Clayton { 1857fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1867fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1877fdf9ef1SGreg Clayton { 1887fdf9ef1SGreg Clayton 1891ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 1901ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 1911ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 1924e78f606SGreg Clayton if (stop_info_sp) 1934e78f606SGreg Clayton { 1944e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1954e78f606SGreg Clayton switch (reason) 1964e78f606SGreg Clayton { 1974e78f606SGreg Clayton case eStopReasonInvalid: 1984e78f606SGreg Clayton case eStopReasonNone: 1994e78f606SGreg Clayton case eStopReasonTrace: 2004e78f606SGreg Clayton case eStopReasonPlanComplete: 2014e78f606SGreg Clayton // There is no data for these stop reasons. 2024e78f606SGreg Clayton return 0; 2034e78f606SGreg Clayton 2044e78f606SGreg Clayton case eStopReasonBreakpoint: 2054e78f606SGreg Clayton { 2064e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2071ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2084e78f606SGreg Clayton if (bp_site_sp) 2094e78f606SGreg Clayton { 2104e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2114e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2124e78f606SGreg Clayton if (bp_loc_sp) 2134e78f606SGreg Clayton { 2144e78f606SGreg Clayton if (bp_index & 1) 2154e78f606SGreg Clayton { 2164e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2174e78f606SGreg Clayton return bp_loc_sp->GetID(); 2184e78f606SGreg Clayton } 2194e78f606SGreg Clayton else 2204e78f606SGreg Clayton { 2214e78f606SGreg Clayton // Even idx, return the breakpoint ID 2224e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2234e78f606SGreg Clayton } 2244e78f606SGreg Clayton } 2254e78f606SGreg Clayton } 2264e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2274e78f606SGreg Clayton } 2284e78f606SGreg Clayton break; 2294e78f606SGreg Clayton 2304e78f606SGreg Clayton case eStopReasonWatchpoint: 231290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2324e78f606SGreg Clayton 2334e78f606SGreg Clayton case eStopReasonSignal: 2344e78f606SGreg Clayton return stop_info_sp->GetValue(); 2354e78f606SGreg Clayton 2364e78f606SGreg Clayton case eStopReasonException: 2374e78f606SGreg Clayton return stop_info_sp->GetValue(); 2384e78f606SGreg Clayton } 2394e78f606SGreg Clayton } 2404e78f606SGreg Clayton } 241*c9858e4dSGreg Clayton else 242*c9858e4dSGreg Clayton { 243*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 244*c9858e4dSGreg Clayton if (log) 245*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 246*c9858e4dSGreg Clayton } 2477fdf9ef1SGreg Clayton } 2484e78f606SGreg Clayton return 0; 2494e78f606SGreg Clayton } 2504e78f606SGreg Clayton 2514e78f606SGreg Clayton size_t 25230fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 25330fdc8d8SChris Lattner { 2542d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 255ceb6b139SCaroline Tice 2567fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 2571ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 25830fdc8d8SChris Lattner { 2597fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2607fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2617fdf9ef1SGreg Clayton { 2627fdf9ef1SGreg Clayton 2631ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 2641ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 265b15bfc75SJim Ingham if (stop_info_sp) 26630fdc8d8SChris Lattner { 267b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 26830fdc8d8SChris Lattner if (stop_desc) 26930fdc8d8SChris Lattner { 270ceb6b139SCaroline Tice if (log) 2714838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 2721ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 27330fdc8d8SChris Lattner if (dst) 27430fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 27530fdc8d8SChris Lattner else 27630fdc8d8SChris Lattner { 27730fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 27830fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 27930fdc8d8SChris Lattner } 28030fdc8d8SChris Lattner } 28130fdc8d8SChris Lattner else 28230fdc8d8SChris Lattner { 28330fdc8d8SChris Lattner size_t stop_desc_len = 0; 284b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 28530fdc8d8SChris Lattner { 28630fdc8d8SChris Lattner case eStopReasonTrace: 28730fdc8d8SChris Lattner case eStopReasonPlanComplete: 28830fdc8d8SChris Lattner { 28930fdc8d8SChris Lattner static char trace_desc[] = "step"; 29030fdc8d8SChris Lattner stop_desc = trace_desc; 29130fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 29230fdc8d8SChris Lattner } 29330fdc8d8SChris Lattner break; 29430fdc8d8SChris Lattner 29530fdc8d8SChris Lattner case eStopReasonBreakpoint: 29630fdc8d8SChris Lattner { 29730fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 29830fdc8d8SChris Lattner stop_desc = bp_desc; 29930fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 30030fdc8d8SChris Lattner } 30130fdc8d8SChris Lattner break; 30230fdc8d8SChris Lattner 30330fdc8d8SChris Lattner case eStopReasonWatchpoint: 30430fdc8d8SChris Lattner { 30530fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 30630fdc8d8SChris Lattner stop_desc = wp_desc; 30730fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 30830fdc8d8SChris Lattner } 30930fdc8d8SChris Lattner break; 31030fdc8d8SChris Lattner 31130fdc8d8SChris Lattner case eStopReasonSignal: 31230fdc8d8SChris Lattner { 3131ac04c30SGreg Clayton stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 31430fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 31530fdc8d8SChris Lattner { 31630fdc8d8SChris Lattner static char signal_desc[] = "signal"; 31730fdc8d8SChris Lattner stop_desc = signal_desc; 31830fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner } 32130fdc8d8SChris Lattner break; 32230fdc8d8SChris Lattner 32330fdc8d8SChris Lattner case eStopReasonException: 32430fdc8d8SChris Lattner { 32530fdc8d8SChris Lattner char exc_desc[] = "exception"; 32630fdc8d8SChris Lattner stop_desc = exc_desc; 32730fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 32830fdc8d8SChris Lattner } 32930fdc8d8SChris Lattner break; 330c982c768SGreg Clayton 331c982c768SGreg Clayton default: 332c982c768SGreg Clayton break; 33330fdc8d8SChris Lattner } 33430fdc8d8SChris Lattner 33530fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 33630fdc8d8SChris Lattner { 337ceb6b139SCaroline Tice if (log) 33893aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 3391ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 340ceb6b139SCaroline Tice 34130fdc8d8SChris Lattner if (dst) 34230fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 34330fdc8d8SChris Lattner 34430fdc8d8SChris Lattner if (stop_desc_len == 0) 34530fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 34630fdc8d8SChris Lattner 34730fdc8d8SChris Lattner return stop_desc_len; 34830fdc8d8SChris Lattner } 34930fdc8d8SChris Lattner } 35030fdc8d8SChris Lattner } 35130fdc8d8SChris Lattner } 352*c9858e4dSGreg Clayton else 353*c9858e4dSGreg Clayton { 354*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 355*c9858e4dSGreg Clayton if (log) 356*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); 357*c9858e4dSGreg Clayton } 3587fdf9ef1SGreg Clayton } 35930fdc8d8SChris Lattner if (dst) 36030fdc8d8SChris Lattner *dst = 0; 36130fdc8d8SChris Lattner return 0; 36230fdc8d8SChris Lattner } 36330fdc8d8SChris Lattner 36473ca05a2SJim Ingham SBValue 36573ca05a2SJim Ingham SBThread::GetStopReturnValue () 36673ca05a2SJim Ingham { 367*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 36873ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 3697fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 3701ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 37173ca05a2SJim Ingham { 3727fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 3737fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 3747fdf9ef1SGreg Clayton { 3751ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 3761ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 37773ca05a2SJim Ingham if (stop_info_sp) 37873ca05a2SJim Ingham { 37973ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 38073ca05a2SJim Ingham } 38173ca05a2SJim Ingham } 382*c9858e4dSGreg Clayton else 383*c9858e4dSGreg Clayton { 384*c9858e4dSGreg Clayton if (log) 385*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); 386*c9858e4dSGreg Clayton } 3877fdf9ef1SGreg Clayton } 38873ca05a2SJim Ingham 38973ca05a2SJim Ingham if (log) 3901ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), 39173ca05a2SJim Ingham return_valobj_sp.get() 39273ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 39373ca05a2SJim Ingham : "<no return value>"); 39473ca05a2SJim Ingham 39573ca05a2SJim Ingham return SBValue (return_valobj_sp); 39673ca05a2SJim Ingham } 39773ca05a2SJim Ingham 39830fdc8d8SChris Lattner void 39930fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 40030fdc8d8SChris Lattner { 4017fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 40230fdc8d8SChris Lattner } 40330fdc8d8SChris Lattner 40430fdc8d8SChris Lattner 40530fdc8d8SChris Lattner lldb::tid_t 40630fdc8d8SChris Lattner SBThread::GetThreadID () const 40730fdc8d8SChris Lattner { 4087fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 40917a6ad05SGreg Clayton if (thread_sp) 4101ac04c30SGreg Clayton return thread_sp->GetID(); 4111ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner 41430fdc8d8SChris Lattner uint32_t 41530fdc8d8SChris Lattner SBThread::GetIndexID () const 41630fdc8d8SChris Lattner { 4177fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 41817a6ad05SGreg Clayton if (thread_sp) 41917a6ad05SGreg Clayton return thread_sp->GetIndexID(); 42030fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 42130fdc8d8SChris Lattner } 4221ac04c30SGreg Clayton 42330fdc8d8SChris Lattner const char * 42430fdc8d8SChris Lattner SBThread::GetName () const 42530fdc8d8SChris Lattner { 426*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4274838131bSGreg Clayton const char *name = NULL; 4287fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 4291ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 430af67cecdSGreg Clayton { 4317fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4327fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4337fdf9ef1SGreg Clayton { 4341ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 4351ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 436af67cecdSGreg Clayton } 437*c9858e4dSGreg Clayton else 438*c9858e4dSGreg Clayton { 439*c9858e4dSGreg Clayton if (log) 440*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); 441*c9858e4dSGreg Clayton } 4427fdf9ef1SGreg Clayton } 443ceb6b139SCaroline Tice 444ceb6b139SCaroline Tice if (log) 4451ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 446ceb6b139SCaroline Tice 4474838131bSGreg Clayton return name; 44830fdc8d8SChris Lattner } 44930fdc8d8SChris Lattner 45030fdc8d8SChris Lattner const char * 45130fdc8d8SChris Lattner SBThread::GetQueueName () const 45230fdc8d8SChris Lattner { 4534838131bSGreg Clayton const char *name = NULL; 4547fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 455*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4561ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 457af67cecdSGreg Clayton { 4587fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4597fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4607fdf9ef1SGreg Clayton { 4611ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 4621ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 463af67cecdSGreg Clayton } 464*c9858e4dSGreg Clayton else 465*c9858e4dSGreg Clayton { 466*c9858e4dSGreg Clayton if (log) 467*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); 468*c9858e4dSGreg Clayton } 4697fdf9ef1SGreg Clayton } 470ceb6b139SCaroline Tice 471ceb6b139SCaroline Tice if (log) 4721ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 473ceb6b139SCaroline Tice 4744838131bSGreg Clayton return name; 47530fdc8d8SChris Lattner } 47630fdc8d8SChris Lattner 47730fdc8d8SChris Lattner 47830fdc8d8SChris Lattner void 47930fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 48030fdc8d8SChris Lattner { 4812d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 482ceb6b139SCaroline Tice 4837fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 48417a6ad05SGreg Clayton 485ceb6b139SCaroline Tice if (log) 4861ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 487ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 488ceb6b139SCaroline Tice 4891ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 49030fdc8d8SChris Lattner { 4911ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 4921ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 49330fdc8d8SChris Lattner bool abort_other_plans = true; 4941ac04c30SGreg Clayton StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 49530fdc8d8SChris Lattner 49630fdc8d8SChris Lattner if (frame_sp) 49730fdc8d8SChris Lattner { 49830fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 49930fdc8d8SChris Lattner { 50030fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 5011ac04c30SGreg Clayton thread->QueueThreadPlanForStepRange (abort_other_plans, 50230fdc8d8SChris Lattner eStepTypeOver, 50330fdc8d8SChris Lattner sc.line_entry.range, 50430fdc8d8SChris Lattner sc, 505474966a4SGreg Clayton stop_other_threads, 506474966a4SGreg Clayton false); 50730fdc8d8SChris Lattner 50830fdc8d8SChris Lattner } 50930fdc8d8SChris Lattner else 51030fdc8d8SChris Lattner { 5111ac04c30SGreg Clayton thread->QueueThreadPlanForStepSingleInstruction (true, 51230fdc8d8SChris Lattner abort_other_plans, 51330fdc8d8SChris Lattner stop_other_threads); 51430fdc8d8SChris Lattner } 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner 5171ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 51830fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 5191ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 5201ac04c30SGreg Clayton Error error (process->Resume()); 5215d5028b5SGreg Clayton if (error.Success()) 5225d5028b5SGreg Clayton { 5235d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5245d5028b5SGreg Clayton // process to stop yet again! 5251ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 5261ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 5275d5028b5SGreg Clayton } 52830fdc8d8SChris Lattner } 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 53130fdc8d8SChris Lattner void 53230fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 53330fdc8d8SChris Lattner { 5342d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 535ceb6b139SCaroline Tice 5367fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 53717a6ad05SGreg Clayton 53817a6ad05SGreg Clayton if (log) 5391ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 54017a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 5411ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 54230fdc8d8SChris Lattner { 5431ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 54430fdc8d8SChris Lattner bool abort_other_plans = true; 54530fdc8d8SChris Lattner 5461ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 5471ac04c30SGreg Clayton StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 54830fdc8d8SChris Lattner 54930fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 55030fdc8d8SChris Lattner { 551474966a4SGreg Clayton bool avoid_code_without_debug_info = true; 55230fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 5531ac04c30SGreg Clayton thread->QueueThreadPlanForStepRange (abort_other_plans, 55430fdc8d8SChris Lattner eStepTypeInto, 55530fdc8d8SChris Lattner sc.line_entry.range, 55630fdc8d8SChris Lattner sc, 557474966a4SGreg Clayton stop_other_threads, 558474966a4SGreg Clayton avoid_code_without_debug_info); 55930fdc8d8SChris Lattner } 56030fdc8d8SChris Lattner else 56130fdc8d8SChris Lattner { 5621ac04c30SGreg Clayton thread->QueueThreadPlanForStepSingleInstruction (false, 56330fdc8d8SChris Lattner abort_other_plans, 56430fdc8d8SChris Lattner stop_other_threads); 56530fdc8d8SChris Lattner } 56630fdc8d8SChris Lattner 5671ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 56830fdc8d8SChris Lattner // Why do we need to set the current thread by ID here??? 5691ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 5701ac04c30SGreg Clayton Error error (process->Resume()); 5715d5028b5SGreg Clayton if (error.Success()) 5725d5028b5SGreg Clayton { 5735d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 5745d5028b5SGreg Clayton // process to stop yet again! 5751ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 5761ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 5775d5028b5SGreg Clayton } 57830fdc8d8SChris Lattner } 57930fdc8d8SChris Lattner } 58030fdc8d8SChris Lattner 58130fdc8d8SChris Lattner void 58230fdc8d8SChris Lattner SBThread::StepOut () 58330fdc8d8SChris Lattner { 5842d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 585ceb6b139SCaroline Tice 5867fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 587ceb6b139SCaroline Tice 58817a6ad05SGreg Clayton if (log) 5891ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); 59017a6ad05SGreg Clayton 5911ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 59230fdc8d8SChris Lattner { 5931ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 59430fdc8d8SChris Lattner bool abort_other_plans = true; 59530fdc8d8SChris Lattner bool stop_other_threads = true; 59630fdc8d8SChris Lattner 5971ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 5981ac04c30SGreg Clayton 5991ac04c30SGreg Clayton thread->QueueThreadPlanForStepOut (abort_other_plans, 600481cef25SGreg Clayton NULL, 601481cef25SGreg Clayton false, 602481cef25SGreg Clayton stop_other_threads, 603481cef25SGreg Clayton eVoteYes, 604481cef25SGreg Clayton eVoteNoOpinion, 605481cef25SGreg Clayton 0); 606481cef25SGreg Clayton 6071ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 6081ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 6091ac04c30SGreg Clayton Error error (process->Resume()); 610481cef25SGreg Clayton if (error.Success()) 611481cef25SGreg Clayton { 612481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 613481cef25SGreg Clayton // process to stop yet again! 6141ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 6151ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 616481cef25SGreg Clayton } 617481cef25SGreg Clayton } 618481cef25SGreg Clayton } 619481cef25SGreg Clayton 620481cef25SGreg Clayton void 621481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 622481cef25SGreg Clayton { 623481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 624481cef25SGreg Clayton 6257fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 626b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 627481cef25SGreg Clayton if (log) 628481cef25SGreg Clayton { 629481cef25SGreg Clayton SBStream frame_desc_strm; 630481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 6311ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 632481cef25SGreg Clayton } 633481cef25SGreg Clayton 6341ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 635481cef25SGreg Clayton { 6361ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 637481cef25SGreg Clayton bool abort_other_plans = true; 638481cef25SGreg Clayton bool stop_other_threads = true; 6391ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 640481cef25SGreg Clayton 6411ac04c30SGreg Clayton thread->QueueThreadPlanForStepOut (abort_other_plans, 642481cef25SGreg Clayton NULL, 643481cef25SGreg Clayton false, 644481cef25SGreg Clayton stop_other_threads, 645481cef25SGreg Clayton eVoteYes, 646481cef25SGreg Clayton eVoteNoOpinion, 647b9556accSGreg Clayton frame_sp->GetFrameIndex()); 64830fdc8d8SChris Lattner 6491ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 6501ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 6511ac04c30SGreg Clayton Error error (process->Resume()); 6525d5028b5SGreg Clayton if (error.Success()) 6535d5028b5SGreg Clayton { 6545d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 6555d5028b5SGreg Clayton // process to stop yet again! 6561ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 6571ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 6585d5028b5SGreg Clayton } 65930fdc8d8SChris Lattner } 66030fdc8d8SChris Lattner } 66130fdc8d8SChris Lattner 66230fdc8d8SChris Lattner void 66330fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 66430fdc8d8SChris Lattner { 6652d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 666ceb6b139SCaroline Tice 6677fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 6681ac04c30SGreg Clayton 669ceb6b139SCaroline Tice 67017a6ad05SGreg Clayton if (log) 6711ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); 67217a6ad05SGreg Clayton 6731ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 67430fdc8d8SChris Lattner { 6751ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 6761ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6771ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 6781ac04c30SGreg Clayton thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 6791ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 6801ac04c30SGreg Clayton Error error (process->Resume()); 6815d5028b5SGreg Clayton if (error.Success()) 6825d5028b5SGreg Clayton { 6835d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 6845d5028b5SGreg Clayton // process to stop yet again! 6851ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 6861ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 6875d5028b5SGreg Clayton } 68830fdc8d8SChris Lattner } 68930fdc8d8SChris Lattner } 69030fdc8d8SChris Lattner 69130fdc8d8SChris Lattner void 69230fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 69330fdc8d8SChris Lattner { 6942d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 695ceb6b139SCaroline Tice 6967fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 697ceb6b139SCaroline Tice 69817a6ad05SGreg Clayton if (log) 6991ac04c30SGreg Clayton log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr); 70017a6ad05SGreg Clayton 7011ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 70230fdc8d8SChris Lattner { 7031ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 70430fdc8d8SChris Lattner bool abort_other_plans = true; 70530fdc8d8SChris Lattner bool stop_other_threads = true; 70630fdc8d8SChris Lattner 707e72dfb32SGreg Clayton Address target_addr (addr); 70830fdc8d8SChris Lattner 7091ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7101ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 7111ac04c30SGreg Clayton 7121ac04c30SGreg Clayton thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 7131ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 7141ac04c30SGreg Clayton Error error (process->Resume()); 7155d5028b5SGreg Clayton if (error.Success()) 7165d5028b5SGreg Clayton { 7175d5028b5SGreg Clayton // If we are doing synchronous mode, then wait for the 7185d5028b5SGreg Clayton // process to stop yet again! 7191ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 7201ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 7215d5028b5SGreg Clayton } 72230fdc8d8SChris Lattner } 72330fdc8d8SChris Lattner } 72430fdc8d8SChris Lattner 725481cef25SGreg Clayton SBError 726481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 727481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 728481cef25SGreg Clayton uint32_t line) 729481cef25SGreg Clayton { 730481cef25SGreg Clayton SBError sb_error; 731481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 732481cef25SGreg Clayton char path[PATH_MAX]; 733481cef25SGreg Clayton 7347fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 735b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 73617a6ad05SGreg Clayton 737481cef25SGreg Clayton if (log) 738481cef25SGreg Clayton { 739481cef25SGreg Clayton SBStream frame_desc_strm; 740481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 741481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 742481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 7431ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), 744b9556accSGreg Clayton frame_sp.get(), 745481cef25SGreg Clayton frame_desc_strm.GetData(), 746481cef25SGreg Clayton path, line); 747481cef25SGreg Clayton } 748481cef25SGreg Clayton 7491ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 750481cef25SGreg Clayton { 7511ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 7521ac04c30SGreg Clayton Mutex::Locker api_locker (target->GetAPIMutex()); 7531ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 754481cef25SGreg Clayton 755481cef25SGreg Clayton if (line == 0) 756481cef25SGreg Clayton { 757481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 758481cef25SGreg Clayton return sb_error; 759481cef25SGreg Clayton } 760481cef25SGreg Clayton 761481cef25SGreg Clayton StackFrameSP frame_sp; 762b9556accSGreg Clayton if (!frame_sp) 763481cef25SGreg Clayton { 7641ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 765481cef25SGreg Clayton if (!frame_sp) 7661ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 767481cef25SGreg Clayton } 768481cef25SGreg Clayton 769481cef25SGreg Clayton SymbolContext frame_sc; 770481cef25SGreg Clayton if (!frame_sp) 771481cef25SGreg Clayton { 772481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 773481cef25SGreg Clayton return sb_error; 774481cef25SGreg Clayton } 775481cef25SGreg Clayton 776481cef25SGreg Clayton // If we have a frame, get its line 777481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 778481cef25SGreg Clayton eSymbolContextFunction | 779481cef25SGreg Clayton eSymbolContextLineEntry | 780481cef25SGreg Clayton eSymbolContextSymbol ); 781481cef25SGreg Clayton 782481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 783481cef25SGreg Clayton { 784481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 785481cef25SGreg Clayton return sb_error; 786481cef25SGreg Clayton } 787481cef25SGreg Clayton 788481cef25SGreg Clayton FileSpec step_file_spec; 789481cef25SGreg Clayton if (sb_file_spec.IsValid()) 790481cef25SGreg Clayton { 791481cef25SGreg Clayton // The file spec passed in was valid, so use it 792481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 793481cef25SGreg Clayton } 794481cef25SGreg Clayton else 795481cef25SGreg Clayton { 796481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 797481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 798481cef25SGreg Clayton else 799481cef25SGreg Clayton { 800481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 801481cef25SGreg Clayton return sb_error; 802481cef25SGreg Clayton } 803481cef25SGreg Clayton } 804481cef25SGreg Clayton 8059b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 8069b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 8079b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 8089b70ddb3SJim Ingham // error message. 8099b70ddb3SJim Ingham 8109b70ddb3SJim Ingham bool all_in_function = true; 8119b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 8129b70ddb3SJim Ingham 813481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 814481cef25SGreg Clayton const bool abort_other_plans = true; 815481cef25SGreg Clayton const bool stop_other_threads = true; 816481cef25SGreg Clayton const bool check_inlines = true; 817481cef25SGreg Clayton const bool exact = false; 818481cef25SGreg Clayton 819481cef25SGreg Clayton SymbolContextList sc_list; 8209b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 8219b70ddb3SJim Ingham line, 8229b70ddb3SJim Ingham check_inlines, 8239b70ddb3SJim Ingham exact, 8249b70ddb3SJim Ingham eSymbolContextLineEntry, 8259b70ddb3SJim Ingham sc_list); 826481cef25SGreg Clayton if (num_matches > 0) 827481cef25SGreg Clayton { 828481cef25SGreg Clayton SymbolContext sc; 829481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 830481cef25SGreg Clayton { 831481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 832481cef25SGreg Clayton { 8339b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 834481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 835481cef25SGreg Clayton { 8369b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 837481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 8389b70ddb3SJim Ingham else 8399b70ddb3SJim Ingham all_in_function = false; 840481cef25SGreg Clayton } 841481cef25SGreg Clayton } 842481cef25SGreg Clayton } 843481cef25SGreg Clayton } 844481cef25SGreg Clayton 845481cef25SGreg Clayton if (step_over_until_addrs.empty()) 846481cef25SGreg Clayton { 8479b70ddb3SJim Ingham if (all_in_function) 8489b70ddb3SJim Ingham { 849481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 850fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 851481cef25SGreg Clayton } 852481cef25SGreg Clayton else 85386edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 8549b70ddb3SJim Ingham } 8559b70ddb3SJim Ingham else 856481cef25SGreg Clayton { 8571ac04c30SGreg Clayton thread->QueueThreadPlanForStepUntil (abort_other_plans, 858481cef25SGreg Clayton &step_over_until_addrs[0], 859481cef25SGreg Clayton step_over_until_addrs.size(), 860481cef25SGreg Clayton stop_other_threads, 861481cef25SGreg Clayton frame_sp->GetFrameIndex()); 862481cef25SGreg Clayton 8631ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 8641ac04c30SGreg Clayton 8651ac04c30SGreg Clayton process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 8661ac04c30SGreg Clayton sb_error.ref() = process->Resume(); 867481cef25SGreg Clayton if (sb_error->Success()) 868481cef25SGreg Clayton { 869481cef25SGreg Clayton // If we are doing synchronous mode, then wait for the 870481cef25SGreg Clayton // process to stop yet again! 8711ac04c30SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 8721ac04c30SGreg Clayton process->WaitForProcessToStop (NULL); 873481cef25SGreg Clayton } 874481cef25SGreg Clayton } 875481cef25SGreg Clayton } 876481cef25SGreg Clayton else 877481cef25SGreg Clayton { 878481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 879481cef25SGreg Clayton } 880481cef25SGreg Clayton return sb_error; 881481cef25SGreg Clayton } 882481cef25SGreg Clayton 883481cef25SGreg Clayton 884722a0cdcSGreg Clayton bool 885722a0cdcSGreg Clayton SBThread::Suspend() 886722a0cdcSGreg Clayton { 887*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 8887fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 889*c9858e4dSGreg Clayton bool result = false; 8901ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 891722a0cdcSGreg Clayton { 892*c9858e4dSGreg Clayton Process::StopLocker stop_locker; 893*c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 894*c9858e4dSGreg Clayton { 8951ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 896*c9858e4dSGreg Clayton result = true; 897722a0cdcSGreg Clayton } 898*c9858e4dSGreg Clayton else 899*c9858e4dSGreg Clayton { 900*c9858e4dSGreg Clayton if (log) 901*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); 902*c9858e4dSGreg Clayton } 903*c9858e4dSGreg Clayton } 904*c9858e4dSGreg Clayton if (log) 905*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); 906*c9858e4dSGreg Clayton return result; 907722a0cdcSGreg Clayton } 908722a0cdcSGreg Clayton 909722a0cdcSGreg Clayton bool 910722a0cdcSGreg Clayton SBThread::Resume () 911722a0cdcSGreg Clayton { 912*c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 9137fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 914*c9858e4dSGreg Clayton bool result = false; 9151ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 916722a0cdcSGreg Clayton { 917*c9858e4dSGreg Clayton Process::StopLocker stop_locker; 918*c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 919*c9858e4dSGreg Clayton { 9201ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); 921*c9858e4dSGreg Clayton result = true; 922722a0cdcSGreg Clayton } 923*c9858e4dSGreg Clayton else 924*c9858e4dSGreg Clayton { 925*c9858e4dSGreg Clayton if (log) 926*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); 927*c9858e4dSGreg Clayton } 928*c9858e4dSGreg Clayton } 929*c9858e4dSGreg Clayton if (log) 930*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); 931*c9858e4dSGreg Clayton return result; 932722a0cdcSGreg Clayton } 933722a0cdcSGreg Clayton 934722a0cdcSGreg Clayton bool 935722a0cdcSGreg Clayton SBThread::IsSuspended() 936722a0cdcSGreg Clayton { 9377fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 9381ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 9391ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 940722a0cdcSGreg Clayton return false; 941722a0cdcSGreg Clayton } 942722a0cdcSGreg Clayton 94330fdc8d8SChris Lattner SBProcess 94430fdc8d8SChris Lattner SBThread::GetProcess () 94530fdc8d8SChris Lattner { 946ceb6b139SCaroline Tice 947b9556accSGreg Clayton SBProcess sb_process; 948b9556accSGreg Clayton ProcessSP process_sp; 9497fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 9501ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 95130fdc8d8SChris Lattner { 95230fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 9531ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 95430fdc8d8SChris Lattner } 955ceb6b139SCaroline Tice 9562d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 957ceb6b139SCaroline Tice if (log) 958ceb6b139SCaroline Tice { 959481cef25SGreg Clayton SBStream frame_desc_strm; 960b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 9611ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), 962b9556accSGreg Clayton process_sp.get(), frame_desc_strm.GetData()); 963ceb6b139SCaroline Tice } 964ceb6b139SCaroline Tice 965b9556accSGreg Clayton return sb_process; 96630fdc8d8SChris Lattner } 96730fdc8d8SChris Lattner 96830fdc8d8SChris Lattner uint32_t 96930fdc8d8SChris Lattner SBThread::GetNumFrames () 97030fdc8d8SChris Lattner { 9712d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 972ceb6b139SCaroline Tice 973ceb6b139SCaroline Tice uint32_t num_frames = 0; 9747fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 9751ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 976af67cecdSGreg Clayton { 9777fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 9787fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 9797fdf9ef1SGreg Clayton { 9801ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 9811ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 982af67cecdSGreg Clayton } 983*c9858e4dSGreg Clayton else 984*c9858e4dSGreg Clayton { 985*c9858e4dSGreg Clayton if (log) 986*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); 987*c9858e4dSGreg Clayton } 9887fdf9ef1SGreg Clayton } 989ceb6b139SCaroline Tice 990ceb6b139SCaroline Tice if (log) 9911ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); 992ceb6b139SCaroline Tice 993ceb6b139SCaroline Tice return num_frames; 99430fdc8d8SChris Lattner } 99530fdc8d8SChris Lattner 99630fdc8d8SChris Lattner SBFrame 99730fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 99830fdc8d8SChris Lattner { 9992d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1000ceb6b139SCaroline Tice 100130fdc8d8SChris Lattner SBFrame sb_frame; 1002b9556accSGreg Clayton StackFrameSP frame_sp; 10037fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10041ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1005af67cecdSGreg Clayton { 10067fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10077fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10087fdf9ef1SGreg Clayton { 10091ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 10101ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1011b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1012af67cecdSGreg Clayton } 1013*c9858e4dSGreg Clayton else 1014*c9858e4dSGreg Clayton { 1015*c9858e4dSGreg Clayton if (log) 1016*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 1017*c9858e4dSGreg Clayton } 10187fdf9ef1SGreg Clayton } 1019ceb6b139SCaroline Tice 1020ceb6b139SCaroline Tice if (log) 1021ceb6b139SCaroline Tice { 1022481cef25SGreg Clayton SBStream frame_desc_strm; 1023481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 10244838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 10251ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1026ceb6b139SCaroline Tice } 1027ceb6b139SCaroline Tice 102830fdc8d8SChris Lattner return sb_frame; 102930fdc8d8SChris Lattner } 103030fdc8d8SChris Lattner 1031f028a1fbSGreg Clayton lldb::SBFrame 1032f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1033f028a1fbSGreg Clayton { 1034f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1035f028a1fbSGreg Clayton 1036f028a1fbSGreg Clayton SBFrame sb_frame; 1037b9556accSGreg Clayton StackFrameSP frame_sp; 10387fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10391ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1040af67cecdSGreg Clayton { 10417fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10427fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10437fdf9ef1SGreg Clayton { 10441ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 10451ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1046b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1047af67cecdSGreg Clayton } 1048*c9858e4dSGreg Clayton else 1049*c9858e4dSGreg Clayton { 1050*c9858e4dSGreg Clayton if (log) 1051*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1052*c9858e4dSGreg Clayton } 10537fdf9ef1SGreg Clayton } 1054f028a1fbSGreg Clayton 1055f028a1fbSGreg Clayton if (log) 1056f028a1fbSGreg Clayton { 1057481cef25SGreg Clayton SBStream frame_desc_strm; 1058481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1059f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 10601ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 1061f028a1fbSGreg Clayton } 1062f028a1fbSGreg Clayton 1063f028a1fbSGreg Clayton return sb_frame; 1064f028a1fbSGreg Clayton } 1065f028a1fbSGreg Clayton 1066f028a1fbSGreg Clayton lldb::SBFrame 1067f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1068f028a1fbSGreg Clayton { 1069f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1070f028a1fbSGreg Clayton 1071f028a1fbSGreg Clayton SBFrame sb_frame; 1072b9556accSGreg Clayton StackFrameSP frame_sp; 10737fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10741ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1075f028a1fbSGreg Clayton { 10767fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10777fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10787fdf9ef1SGreg Clayton { 10791ac04c30SGreg Clayton Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); 10801ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 10811ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1082f028a1fbSGreg Clayton if (frame_sp) 1083f028a1fbSGreg Clayton { 10841ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1085b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1086f028a1fbSGreg Clayton } 1087f028a1fbSGreg Clayton } 1088*c9858e4dSGreg Clayton else 1089*c9858e4dSGreg Clayton { 1090*c9858e4dSGreg Clayton if (log) 1091*c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1092*c9858e4dSGreg Clayton } 10937fdf9ef1SGreg Clayton } 1094f028a1fbSGreg Clayton 1095f028a1fbSGreg Clayton if (log) 1096f028a1fbSGreg Clayton { 1097481cef25SGreg Clayton SBStream frame_desc_strm; 1098481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1099f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 11001ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1101f028a1fbSGreg Clayton } 1102f028a1fbSGreg Clayton return sb_frame; 1103f028a1fbSGreg Clayton } 1104f028a1fbSGreg Clayton 1105f028a1fbSGreg Clayton 110630fdc8d8SChris Lattner bool 110730fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 110830fdc8d8SChris Lattner { 11097fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 111030fdc8d8SChris Lattner } 111130fdc8d8SChris Lattner 111230fdc8d8SChris Lattner bool 111330fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 111430fdc8d8SChris Lattner { 11157fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 111630fdc8d8SChris Lattner } 1117dde9cff3SCaroline Tice 1118dde9cff3SCaroline Tice bool 1119ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1120ceb6b139SCaroline Tice { 1121da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1122da7bc7d0SGreg Clayton 11237fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 11241ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1125ceb6b139SCaroline Tice { 11261ac04c30SGreg Clayton strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID()); 1127ceb6b139SCaroline Tice } 1128ceb6b139SCaroline Tice else 1129da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1130ceb6b139SCaroline Tice 1131ceb6b139SCaroline Tice return true; 1132ceb6b139SCaroline Tice } 1133