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; 994fc6cb9cSJim Ingham Mutex::Locker api_locker; 1004fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1014fc6cb9cSJim Ingham 1021ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 10330fdc8d8SChris Lattner { 1047fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1057fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1067fdf9ef1SGreg Clayton { 1071ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 108b15bfc75SJim Ingham if (stop_info_sp) 109ceb6b139SCaroline Tice reason = stop_info_sp->GetStopReason(); 11030fdc8d8SChris Lattner } 111c9858e4dSGreg Clayton else 112c9858e4dSGreg Clayton { 113c9858e4dSGreg Clayton if (log) 114c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); 115c9858e4dSGreg Clayton } 1167fdf9ef1SGreg Clayton } 117ceb6b139SCaroline Tice 118ceb6b139SCaroline Tice if (log) 1191ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), 120750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 121ceb6b139SCaroline Tice 122ceb6b139SCaroline Tice return reason; 12330fdc8d8SChris Lattner } 12430fdc8d8SChris Lattner 12530fdc8d8SChris Lattner size_t 1264e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1274e78f606SGreg Clayton { 1284fc6cb9cSJim Ingham Mutex::Locker api_locker; 1294fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1304fc6cb9cSJim Ingham 1311ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1324e78f606SGreg Clayton { 1337fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1347fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1357fdf9ef1SGreg Clayton { 1361ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1374e78f606SGreg Clayton if (stop_info_sp) 1384e78f606SGreg Clayton { 1394e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1404e78f606SGreg Clayton switch (reason) 1414e78f606SGreg Clayton { 1424e78f606SGreg Clayton case eStopReasonInvalid: 1434e78f606SGreg Clayton case eStopReasonNone: 1444e78f606SGreg Clayton case eStopReasonTrace: 1454e78f606SGreg Clayton case eStopReasonPlanComplete: 1464e78f606SGreg Clayton // There is no data for these stop reasons. 1474e78f606SGreg Clayton return 0; 1484e78f606SGreg Clayton 1494e78f606SGreg Clayton case eStopReasonBreakpoint: 1504e78f606SGreg Clayton { 1514e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1521ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 1534e78f606SGreg Clayton if (bp_site_sp) 1544e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1554e78f606SGreg Clayton else 1564e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1574e78f606SGreg Clayton } 1584e78f606SGreg Clayton break; 1594e78f606SGreg Clayton 1604e78f606SGreg Clayton case eStopReasonWatchpoint: 161290fa41bSJohnny Chen return 1; 1624e78f606SGreg Clayton 1634e78f606SGreg Clayton case eStopReasonSignal: 1644e78f606SGreg Clayton return 1; 1654e78f606SGreg Clayton 1664e78f606SGreg Clayton case eStopReasonException: 1674e78f606SGreg Clayton return 1; 1684e78f606SGreg Clayton } 1694e78f606SGreg Clayton } 1704e78f606SGreg Clayton } 171c9858e4dSGreg Clayton else 172c9858e4dSGreg Clayton { 173c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 174c9858e4dSGreg Clayton if (log) 175c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); 176c9858e4dSGreg Clayton } 1777fdf9ef1SGreg Clayton } 1784e78f606SGreg Clayton return 0; 1794e78f606SGreg Clayton } 1804e78f606SGreg Clayton 1814e78f606SGreg Clayton uint64_t 1824e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1834e78f606SGreg Clayton { 1844fc6cb9cSJim Ingham Mutex::Locker api_locker; 1854fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1864fc6cb9cSJim Ingham 1871ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1884e78f606SGreg Clayton { 1897fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1907fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1917fdf9ef1SGreg Clayton { 1921ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 1931ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 1944e78f606SGreg Clayton if (stop_info_sp) 1954e78f606SGreg Clayton { 1964e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1974e78f606SGreg Clayton switch (reason) 1984e78f606SGreg Clayton { 1994e78f606SGreg Clayton case eStopReasonInvalid: 2004e78f606SGreg Clayton case eStopReasonNone: 2014e78f606SGreg Clayton case eStopReasonTrace: 2024e78f606SGreg Clayton case eStopReasonPlanComplete: 2034e78f606SGreg Clayton // There is no data for these stop reasons. 2044e78f606SGreg Clayton return 0; 2054e78f606SGreg Clayton 2064e78f606SGreg Clayton case eStopReasonBreakpoint: 2074e78f606SGreg Clayton { 2084e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2091ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2104e78f606SGreg Clayton if (bp_site_sp) 2114e78f606SGreg Clayton { 2124e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2134e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2144e78f606SGreg Clayton if (bp_loc_sp) 2154e78f606SGreg Clayton { 2164e78f606SGreg Clayton if (bp_index & 1) 2174e78f606SGreg Clayton { 2184e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2194e78f606SGreg Clayton return bp_loc_sp->GetID(); 2204e78f606SGreg Clayton } 2214e78f606SGreg Clayton else 2224e78f606SGreg Clayton { 2234e78f606SGreg Clayton // Even idx, return the breakpoint ID 2244e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2254e78f606SGreg Clayton } 2264e78f606SGreg Clayton } 2274e78f606SGreg Clayton } 2284e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2294e78f606SGreg Clayton } 2304e78f606SGreg Clayton break; 2314e78f606SGreg Clayton 2324e78f606SGreg Clayton case eStopReasonWatchpoint: 233290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2344e78f606SGreg Clayton 2354e78f606SGreg Clayton case eStopReasonSignal: 2364e78f606SGreg Clayton return stop_info_sp->GetValue(); 2374e78f606SGreg Clayton 2384e78f606SGreg Clayton case eStopReasonException: 2394e78f606SGreg Clayton return stop_info_sp->GetValue(); 2404e78f606SGreg Clayton } 2414e78f606SGreg Clayton } 2424e78f606SGreg Clayton } 243c9858e4dSGreg Clayton else 244c9858e4dSGreg Clayton { 245c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 246c9858e4dSGreg Clayton if (log) 247c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 248c9858e4dSGreg Clayton } 2497fdf9ef1SGreg Clayton } 2504e78f606SGreg Clayton return 0; 2514e78f606SGreg Clayton } 2524e78f606SGreg Clayton 2534e78f606SGreg Clayton size_t 25430fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 25530fdc8d8SChris Lattner { 2562d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 257ceb6b139SCaroline Tice 2584fc6cb9cSJim Ingham Mutex::Locker api_locker; 2594fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 2604fc6cb9cSJim Ingham 2611ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 26230fdc8d8SChris Lattner { 2637fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2647fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2657fdf9ef1SGreg Clayton { 2667fdf9ef1SGreg Clayton 2671ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 268b15bfc75SJim Ingham if (stop_info_sp) 26930fdc8d8SChris Lattner { 270b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 27130fdc8d8SChris Lattner if (stop_desc) 27230fdc8d8SChris Lattner { 273ceb6b139SCaroline Tice if (log) 2744838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 2751ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 27630fdc8d8SChris Lattner if (dst) 27730fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 27830fdc8d8SChris Lattner else 27930fdc8d8SChris Lattner { 28030fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 28130fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 28230fdc8d8SChris Lattner } 28330fdc8d8SChris Lattner } 28430fdc8d8SChris Lattner else 28530fdc8d8SChris Lattner { 28630fdc8d8SChris Lattner size_t stop_desc_len = 0; 287b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 28830fdc8d8SChris Lattner { 28930fdc8d8SChris Lattner case eStopReasonTrace: 29030fdc8d8SChris Lattner case eStopReasonPlanComplete: 29130fdc8d8SChris Lattner { 29230fdc8d8SChris Lattner static char trace_desc[] = "step"; 29330fdc8d8SChris Lattner stop_desc = trace_desc; 29430fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner break; 29730fdc8d8SChris Lattner 29830fdc8d8SChris Lattner case eStopReasonBreakpoint: 29930fdc8d8SChris Lattner { 30030fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 30130fdc8d8SChris Lattner stop_desc = bp_desc; 30230fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 30330fdc8d8SChris Lattner } 30430fdc8d8SChris Lattner break; 30530fdc8d8SChris Lattner 30630fdc8d8SChris Lattner case eStopReasonWatchpoint: 30730fdc8d8SChris Lattner { 30830fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 30930fdc8d8SChris Lattner stop_desc = wp_desc; 31030fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 31130fdc8d8SChris Lattner } 31230fdc8d8SChris Lattner break; 31330fdc8d8SChris Lattner 31430fdc8d8SChris Lattner case eStopReasonSignal: 31530fdc8d8SChris Lattner { 3161ac04c30SGreg Clayton stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 31730fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 31830fdc8d8SChris Lattner { 31930fdc8d8SChris Lattner static char signal_desc[] = "signal"; 32030fdc8d8SChris Lattner stop_desc = signal_desc; 32130fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 32230fdc8d8SChris Lattner } 32330fdc8d8SChris Lattner } 32430fdc8d8SChris Lattner break; 32530fdc8d8SChris Lattner 32630fdc8d8SChris Lattner case eStopReasonException: 32730fdc8d8SChris Lattner { 32830fdc8d8SChris Lattner char exc_desc[] = "exception"; 32930fdc8d8SChris Lattner stop_desc = exc_desc; 33030fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 33130fdc8d8SChris Lattner } 33230fdc8d8SChris Lattner break; 333c982c768SGreg Clayton 334c982c768SGreg Clayton default: 335c982c768SGreg Clayton break; 33630fdc8d8SChris Lattner } 33730fdc8d8SChris Lattner 33830fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 33930fdc8d8SChris Lattner { 340ceb6b139SCaroline Tice if (log) 34193aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 3421ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 343ceb6b139SCaroline Tice 34430fdc8d8SChris Lattner if (dst) 34530fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 34630fdc8d8SChris Lattner 34730fdc8d8SChris Lattner if (stop_desc_len == 0) 34830fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 34930fdc8d8SChris Lattner 35030fdc8d8SChris Lattner return stop_desc_len; 35130fdc8d8SChris Lattner } 35230fdc8d8SChris Lattner } 35330fdc8d8SChris Lattner } 35430fdc8d8SChris Lattner } 355c9858e4dSGreg Clayton else 356c9858e4dSGreg Clayton { 357c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 358c9858e4dSGreg Clayton if (log) 359c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); 360c9858e4dSGreg Clayton } 3617fdf9ef1SGreg Clayton } 36230fdc8d8SChris Lattner if (dst) 36330fdc8d8SChris Lattner *dst = 0; 36430fdc8d8SChris Lattner return 0; 36530fdc8d8SChris Lattner } 36630fdc8d8SChris Lattner 36773ca05a2SJim Ingham SBValue 36873ca05a2SJim Ingham SBThread::GetStopReturnValue () 36973ca05a2SJim Ingham { 370c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 37173ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 3724fc6cb9cSJim Ingham Mutex::Locker api_locker; 3734fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 3744fc6cb9cSJim Ingham 3751ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 37673ca05a2SJim Ingham { 3777fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 3787fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 3797fdf9ef1SGreg Clayton { 3801ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 38173ca05a2SJim Ingham if (stop_info_sp) 38273ca05a2SJim Ingham { 38373ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 38473ca05a2SJim Ingham } 38573ca05a2SJim Ingham } 386c9858e4dSGreg Clayton else 387c9858e4dSGreg Clayton { 388c9858e4dSGreg Clayton if (log) 389c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); 390c9858e4dSGreg Clayton } 3917fdf9ef1SGreg Clayton } 39273ca05a2SJim Ingham 39373ca05a2SJim Ingham if (log) 3941ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), 39573ca05a2SJim Ingham return_valobj_sp.get() 39673ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 39773ca05a2SJim Ingham : "<no return value>"); 39873ca05a2SJim Ingham 39973ca05a2SJim Ingham return SBValue (return_valobj_sp); 40073ca05a2SJim Ingham } 40173ca05a2SJim Ingham 40230fdc8d8SChris Lattner void 40330fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 40430fdc8d8SChris Lattner { 4057fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 40630fdc8d8SChris Lattner } 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner 40930fdc8d8SChris Lattner lldb::tid_t 41030fdc8d8SChris Lattner SBThread::GetThreadID () const 41130fdc8d8SChris Lattner { 4127fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 41317a6ad05SGreg Clayton if (thread_sp) 4141ac04c30SGreg Clayton return thread_sp->GetID(); 4151ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 41630fdc8d8SChris Lattner } 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner uint32_t 41930fdc8d8SChris Lattner SBThread::GetIndexID () const 42030fdc8d8SChris Lattner { 4217fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 42217a6ad05SGreg Clayton if (thread_sp) 42317a6ad05SGreg Clayton return thread_sp->GetIndexID(); 42430fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 42530fdc8d8SChris Lattner } 4261ac04c30SGreg Clayton 42730fdc8d8SChris Lattner const char * 42830fdc8d8SChris Lattner SBThread::GetName () const 42930fdc8d8SChris Lattner { 430c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4314838131bSGreg Clayton const char *name = NULL; 4324fc6cb9cSJim Ingham Mutex::Locker api_locker; 4334fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4344fc6cb9cSJim Ingham 4351ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 436af67cecdSGreg Clayton { 4377fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4387fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4397fdf9ef1SGreg Clayton { 4401ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 441af67cecdSGreg Clayton } 442c9858e4dSGreg Clayton else 443c9858e4dSGreg Clayton { 444c9858e4dSGreg Clayton if (log) 445c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); 446c9858e4dSGreg Clayton } 4477fdf9ef1SGreg Clayton } 448ceb6b139SCaroline Tice 449ceb6b139SCaroline Tice if (log) 4501ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 451ceb6b139SCaroline Tice 4524838131bSGreg Clayton return name; 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner 45530fdc8d8SChris Lattner const char * 45630fdc8d8SChris Lattner SBThread::GetQueueName () const 45730fdc8d8SChris Lattner { 4584838131bSGreg Clayton const char *name = NULL; 4594fc6cb9cSJim Ingham Mutex::Locker api_locker; 4604fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4614fc6cb9cSJim Ingham 462c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4631ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 464af67cecdSGreg Clayton { 4657fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4667fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4677fdf9ef1SGreg Clayton { 4681ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 469af67cecdSGreg Clayton } 470c9858e4dSGreg Clayton else 471c9858e4dSGreg Clayton { 472c9858e4dSGreg Clayton if (log) 473c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); 474c9858e4dSGreg Clayton } 4757fdf9ef1SGreg Clayton } 476ceb6b139SCaroline Tice 477ceb6b139SCaroline Tice if (log) 4781ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 479ceb6b139SCaroline Tice 4804838131bSGreg Clayton return name; 48130fdc8d8SChris Lattner } 48230fdc8d8SChris Lattner 48364e7ead1SJim Ingham SBError 48464e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 48564e7ead1SJim Ingham { 48664e7ead1SJim Ingham SBError sb_error; 48764e7ead1SJim Ingham 48864e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 48964e7ead1SJim Ingham if (!process) 49064e7ead1SJim Ingham { 49164e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 49264e7ead1SJim Ingham return sb_error; 49364e7ead1SJim Ingham } 49464e7ead1SJim Ingham 49564e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 49664e7ead1SJim Ingham if (!thread) 49764e7ead1SJim Ingham { 49864e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 49964e7ead1SJim Ingham return sb_error; 50064e7ead1SJim Ingham } 50164e7ead1SJim Ingham 50264e7ead1SJim Ingham // User level plans should be Master Plans so they can be interrupted, other plans executed, and 50364e7ead1SJim Ingham // then a "continue" will resume the plan. 50464e7ead1SJim Ingham if (new_plan != NULL) 50564e7ead1SJim Ingham { 50664e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 50764e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 50864e7ead1SJim Ingham } 50964e7ead1SJim Ingham 51064e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 51164e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 51264e7ead1SJim Ingham sb_error.ref() = process->Resume(); 51364e7ead1SJim Ingham 51464e7ead1SJim Ingham if (sb_error.Success()) 51564e7ead1SJim Ingham { 51664e7ead1SJim Ingham // If we are doing synchronous mode, then wait for the 51764e7ead1SJim Ingham // process to stop yet again! 51864e7ead1SJim Ingham if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 51964e7ead1SJim Ingham process->WaitForProcessToStop (NULL); 52064e7ead1SJim Ingham } 52164e7ead1SJim Ingham 52264e7ead1SJim Ingham return sb_error; 52364e7ead1SJim Ingham } 52430fdc8d8SChris Lattner 52530fdc8d8SChris Lattner void 52630fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 52730fdc8d8SChris Lattner { 5282d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 529ceb6b139SCaroline Tice 5304fc6cb9cSJim Ingham Mutex::Locker api_locker; 5314fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5324fc6cb9cSJim Ingham 53317a6ad05SGreg Clayton 534ceb6b139SCaroline Tice if (log) 5351ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 536ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 537ceb6b139SCaroline Tice 5381ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 53930fdc8d8SChris Lattner { 5401ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 5417ba6e991SJim Ingham bool abort_other_plans = false; 5421ac04c30SGreg Clayton StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 54364e7ead1SJim Ingham ThreadPlan *new_plan = NULL; 54430fdc8d8SChris Lattner 54530fdc8d8SChris Lattner if (frame_sp) 54630fdc8d8SChris Lattner { 54730fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 54830fdc8d8SChris Lattner { 54930fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 55064e7ead1SJim Ingham new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 55130fdc8d8SChris Lattner eStepTypeOver, 55230fdc8d8SChris Lattner sc.line_entry.range, 55330fdc8d8SChris Lattner sc, 554474966a4SGreg Clayton stop_other_threads, 555474966a4SGreg Clayton false); 55630fdc8d8SChris Lattner 55730fdc8d8SChris Lattner } 55830fdc8d8SChris Lattner else 55930fdc8d8SChris Lattner { 56064e7ead1SJim Ingham new_plan = thread->QueueThreadPlanForStepSingleInstruction (true, 56130fdc8d8SChris Lattner abort_other_plans, 56230fdc8d8SChris Lattner stop_other_threads); 56330fdc8d8SChris Lattner } 56430fdc8d8SChris Lattner } 56530fdc8d8SChris Lattner 56664e7ead1SJim Ingham // This returns an error, we should use it! 56764e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 56830fdc8d8SChris Lattner } 56930fdc8d8SChris Lattner } 57030fdc8d8SChris Lattner 57130fdc8d8SChris Lattner void 57230fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 57330fdc8d8SChris Lattner { 5742d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 575ceb6b139SCaroline Tice 5764fc6cb9cSJim Ingham Mutex::Locker api_locker; 5774fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 57817a6ad05SGreg Clayton 57917a6ad05SGreg Clayton if (log) 5801ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 58117a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 5821ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 58330fdc8d8SChris Lattner { 5847ba6e991SJim Ingham bool abort_other_plans = false; 58530fdc8d8SChris Lattner 5861ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 5871ac04c30SGreg Clayton StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 58864e7ead1SJim Ingham ThreadPlan *new_plan = NULL; 58930fdc8d8SChris Lattner 59030fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 59130fdc8d8SChris Lattner { 592474966a4SGreg Clayton bool avoid_code_without_debug_info = true; 59330fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 59464e7ead1SJim Ingham new_plan = thread->QueueThreadPlanForStepRange (abort_other_plans, 59530fdc8d8SChris Lattner eStepTypeInto, 59630fdc8d8SChris Lattner sc.line_entry.range, 59730fdc8d8SChris Lattner sc, 598474966a4SGreg Clayton stop_other_threads, 599474966a4SGreg Clayton avoid_code_without_debug_info); 60030fdc8d8SChris Lattner } 60130fdc8d8SChris Lattner else 60230fdc8d8SChris Lattner { 60364e7ead1SJim Ingham new_plan = thread->QueueThreadPlanForStepSingleInstruction (false, 60430fdc8d8SChris Lattner abort_other_plans, 60530fdc8d8SChris Lattner stop_other_threads); 60630fdc8d8SChris Lattner } 60730fdc8d8SChris Lattner 60864e7ead1SJim Ingham // This returns an error, we should use it! 60964e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 61030fdc8d8SChris Lattner } 61130fdc8d8SChris Lattner } 61230fdc8d8SChris Lattner 61330fdc8d8SChris Lattner void 61430fdc8d8SChris Lattner SBThread::StepOut () 61530fdc8d8SChris Lattner { 6162d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 617ceb6b139SCaroline Tice 6184fc6cb9cSJim Ingham Mutex::Locker api_locker; 6194fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6204fc6cb9cSJim Ingham 621ceb6b139SCaroline Tice 62217a6ad05SGreg Clayton if (log) 6231ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); 62417a6ad05SGreg Clayton 6251ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 62630fdc8d8SChris Lattner { 6277ba6e991SJim Ingham bool abort_other_plans = false; 62830fdc8d8SChris Lattner bool stop_other_threads = true; 62930fdc8d8SChris Lattner 6301ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6311ac04c30SGreg Clayton 63264e7ead1SJim Ingham ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 633481cef25SGreg Clayton NULL, 634481cef25SGreg Clayton false, 635481cef25SGreg Clayton stop_other_threads, 636481cef25SGreg Clayton eVoteYes, 637481cef25SGreg Clayton eVoteNoOpinion, 638481cef25SGreg Clayton 0); 639481cef25SGreg Clayton 64064e7ead1SJim Ingham // This returns an error, we should use it! 64164e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 642481cef25SGreg Clayton } 643481cef25SGreg Clayton } 644481cef25SGreg Clayton 645481cef25SGreg Clayton void 646481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 647481cef25SGreg Clayton { 648481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 649481cef25SGreg Clayton 6504fc6cb9cSJim Ingham Mutex::Locker api_locker; 6514fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6524fc6cb9cSJim Ingham 653b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 654481cef25SGreg Clayton if (log) 655481cef25SGreg Clayton { 656481cef25SGreg Clayton SBStream frame_desc_strm; 657481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 6581ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 659481cef25SGreg Clayton } 660481cef25SGreg Clayton 6611ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 662481cef25SGreg Clayton { 6637ba6e991SJim Ingham bool abort_other_plans = false; 664481cef25SGreg Clayton bool stop_other_threads = true; 6651ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 666481cef25SGreg Clayton 66764e7ead1SJim Ingham ThreadPlan *new_plan = thread->QueueThreadPlanForStepOut (abort_other_plans, 668481cef25SGreg Clayton NULL, 669481cef25SGreg Clayton false, 670481cef25SGreg Clayton stop_other_threads, 671481cef25SGreg Clayton eVoteYes, 672481cef25SGreg Clayton eVoteNoOpinion, 673b9556accSGreg Clayton frame_sp->GetFrameIndex()); 67430fdc8d8SChris Lattner 67564e7ead1SJim Ingham // This returns an error, we should use it! 67664e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 67730fdc8d8SChris Lattner } 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner 68030fdc8d8SChris Lattner void 68130fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 68230fdc8d8SChris Lattner { 6832d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 684ceb6b139SCaroline Tice 6854fc6cb9cSJim Ingham Mutex::Locker api_locker; 6864fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6874fc6cb9cSJim Ingham 6881ac04c30SGreg Clayton 689ceb6b139SCaroline Tice 69017a6ad05SGreg Clayton if (log) 6911ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); 69217a6ad05SGreg Clayton 6931ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 69430fdc8d8SChris Lattner { 6951ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 69664e7ead1SJim Ingham ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true); 69764e7ead1SJim Ingham 69864e7ead1SJim Ingham // This returns an error, we should use it! 69964e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 70030fdc8d8SChris Lattner } 70130fdc8d8SChris Lattner } 70230fdc8d8SChris Lattner 70330fdc8d8SChris Lattner void 70430fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 70530fdc8d8SChris Lattner { 7062d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 707ceb6b139SCaroline Tice 7084fc6cb9cSJim Ingham Mutex::Locker api_locker; 7094fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7104fc6cb9cSJim Ingham 711ceb6b139SCaroline Tice 71217a6ad05SGreg Clayton if (log) 7131ac04c30SGreg Clayton log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr); 71417a6ad05SGreg Clayton 7151ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 71630fdc8d8SChris Lattner { 7177ba6e991SJim Ingham bool abort_other_plans = false; 71830fdc8d8SChris Lattner bool stop_other_threads = true; 71930fdc8d8SChris Lattner 720e72dfb32SGreg Clayton Address target_addr (addr); 72130fdc8d8SChris Lattner 7221ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7231ac04c30SGreg Clayton 72464e7ead1SJim Ingham ThreadPlan *new_plan = thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads); 72564e7ead1SJim Ingham 72664e7ead1SJim Ingham // This returns an error, we should use it! 72764e7ead1SJim Ingham ResumeNewPlan (exe_ctx, new_plan); 72830fdc8d8SChris Lattner } 72930fdc8d8SChris Lattner } 73030fdc8d8SChris Lattner 731481cef25SGreg Clayton SBError 732481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 733481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 734481cef25SGreg Clayton uint32_t line) 735481cef25SGreg Clayton { 736481cef25SGreg Clayton SBError sb_error; 737481cef25SGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 738481cef25SGreg Clayton char path[PATH_MAX]; 739481cef25SGreg Clayton 7404fc6cb9cSJim Ingham Mutex::Locker api_locker; 7414fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7424fc6cb9cSJim Ingham 743b9556accSGreg Clayton StackFrameSP frame_sp (sb_frame.GetFrameSP()); 74417a6ad05SGreg Clayton 745481cef25SGreg Clayton if (log) 746481cef25SGreg Clayton { 747481cef25SGreg Clayton SBStream frame_desc_strm; 748481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 749481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 750481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 7511ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), 752b9556accSGreg Clayton frame_sp.get(), 753481cef25SGreg Clayton frame_desc_strm.GetData(), 754481cef25SGreg Clayton path, line); 755481cef25SGreg Clayton } 756481cef25SGreg Clayton 7571ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 758481cef25SGreg Clayton { 7591ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 7601ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 761481cef25SGreg Clayton 762481cef25SGreg Clayton if (line == 0) 763481cef25SGreg Clayton { 764481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 765481cef25SGreg Clayton return sb_error; 766481cef25SGreg Clayton } 767481cef25SGreg Clayton 768481cef25SGreg Clayton StackFrameSP frame_sp; 769b9556accSGreg Clayton if (!frame_sp) 770481cef25SGreg Clayton { 7711ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 772481cef25SGreg Clayton if (!frame_sp) 7731ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 774481cef25SGreg Clayton } 775481cef25SGreg Clayton 776481cef25SGreg Clayton SymbolContext frame_sc; 777481cef25SGreg Clayton if (!frame_sp) 778481cef25SGreg Clayton { 779481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 780481cef25SGreg Clayton return sb_error; 781481cef25SGreg Clayton } 782481cef25SGreg Clayton 783481cef25SGreg Clayton // If we have a frame, get its line 784481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 785481cef25SGreg Clayton eSymbolContextFunction | 786481cef25SGreg Clayton eSymbolContextLineEntry | 787481cef25SGreg Clayton eSymbolContextSymbol ); 788481cef25SGreg Clayton 789481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 790481cef25SGreg Clayton { 791481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 792481cef25SGreg Clayton return sb_error; 793481cef25SGreg Clayton } 794481cef25SGreg Clayton 795481cef25SGreg Clayton FileSpec step_file_spec; 796481cef25SGreg Clayton if (sb_file_spec.IsValid()) 797481cef25SGreg Clayton { 798481cef25SGreg Clayton // The file spec passed in was valid, so use it 799481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 800481cef25SGreg Clayton } 801481cef25SGreg Clayton else 802481cef25SGreg Clayton { 803481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 804481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 805481cef25SGreg Clayton else 806481cef25SGreg Clayton { 807481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 808481cef25SGreg Clayton return sb_error; 809481cef25SGreg Clayton } 810481cef25SGreg Clayton } 811481cef25SGreg Clayton 8129b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 8139b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 8149b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 8159b70ddb3SJim Ingham // error message. 8169b70ddb3SJim Ingham 8179b70ddb3SJim Ingham bool all_in_function = true; 8189b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 8199b70ddb3SJim Ingham 820481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 8217ba6e991SJim Ingham const bool abort_other_plans = false; 822481cef25SGreg Clayton const bool stop_other_threads = true; 823481cef25SGreg Clayton const bool check_inlines = true; 824481cef25SGreg Clayton const bool exact = false; 825481cef25SGreg Clayton 826481cef25SGreg Clayton SymbolContextList sc_list; 8279b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 8289b70ddb3SJim Ingham line, 8299b70ddb3SJim Ingham check_inlines, 8309b70ddb3SJim Ingham exact, 8319b70ddb3SJim Ingham eSymbolContextLineEntry, 8329b70ddb3SJim Ingham sc_list); 833481cef25SGreg Clayton if (num_matches > 0) 834481cef25SGreg Clayton { 835481cef25SGreg Clayton SymbolContext sc; 836481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 837481cef25SGreg Clayton { 838481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 839481cef25SGreg Clayton { 8409b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 841481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 842481cef25SGreg Clayton { 8439b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 844481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 8459b70ddb3SJim Ingham else 8469b70ddb3SJim Ingham all_in_function = false; 847481cef25SGreg Clayton } 848481cef25SGreg Clayton } 849481cef25SGreg Clayton } 850481cef25SGreg Clayton } 851481cef25SGreg Clayton 852481cef25SGreg Clayton if (step_over_until_addrs.empty()) 853481cef25SGreg Clayton { 8549b70ddb3SJim Ingham if (all_in_function) 8559b70ddb3SJim Ingham { 856481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 857fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 858481cef25SGreg Clayton } 859481cef25SGreg Clayton else 86086edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 8619b70ddb3SJim Ingham } 8629b70ddb3SJim Ingham else 863481cef25SGreg Clayton { 86464e7ead1SJim Ingham ThreadPlan *new_plan = thread->QueueThreadPlanForStepUntil (abort_other_plans, 865481cef25SGreg Clayton &step_over_until_addrs[0], 866481cef25SGreg Clayton step_over_until_addrs.size(), 867481cef25SGreg Clayton stop_other_threads, 868481cef25SGreg Clayton frame_sp->GetFrameIndex()); 869481cef25SGreg Clayton 87064e7ead1SJim Ingham sb_error = ResumeNewPlan (exe_ctx, new_plan); 871481cef25SGreg Clayton } 872481cef25SGreg Clayton } 873481cef25SGreg Clayton else 874481cef25SGreg Clayton { 875481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 876481cef25SGreg Clayton } 877481cef25SGreg Clayton return sb_error; 878481cef25SGreg Clayton } 879481cef25SGreg Clayton 8804413758cSJim Ingham SBError 881*cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 8824413758cSJim Ingham { 8834413758cSJim Ingham SBError sb_error; 8844413758cSJim Ingham 8854413758cSJim Ingham LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 8864413758cSJim Ingham 8874413758cSJim Ingham Mutex::Locker api_locker; 8884413758cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8894413758cSJim Ingham 8904413758cSJim Ingham 8914413758cSJim Ingham if (log) 892*cb640dd8SJim Ingham log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID()); 8934413758cSJim Ingham 8944413758cSJim Ingham if (exe_ctx.HasThreadScope()) 8954413758cSJim Ingham { 8964413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 897*cb640dd8SJim Ingham sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 8984413758cSJim Ingham } 8994413758cSJim Ingham 9004413758cSJim Ingham return sb_error; 9014413758cSJim Ingham } 9024413758cSJim Ingham 903481cef25SGreg Clayton 904722a0cdcSGreg Clayton bool 905722a0cdcSGreg Clayton SBThread::Suspend() 906722a0cdcSGreg Clayton { 907c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 9087fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 909c9858e4dSGreg Clayton bool result = false; 9101ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 911722a0cdcSGreg Clayton { 912c9858e4dSGreg Clayton Process::StopLocker stop_locker; 913c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 914c9858e4dSGreg Clayton { 9151ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 916c9858e4dSGreg Clayton result = true; 917722a0cdcSGreg Clayton } 918c9858e4dSGreg Clayton else 919c9858e4dSGreg Clayton { 920c9858e4dSGreg Clayton if (log) 921c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); 922c9858e4dSGreg Clayton } 923c9858e4dSGreg Clayton } 924c9858e4dSGreg Clayton if (log) 925c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); 926c9858e4dSGreg Clayton return result; 927722a0cdcSGreg Clayton } 928722a0cdcSGreg Clayton 929722a0cdcSGreg Clayton bool 930722a0cdcSGreg Clayton SBThread::Resume () 931722a0cdcSGreg Clayton { 932c9858e4dSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 9337fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 934c9858e4dSGreg Clayton bool result = false; 9351ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 936722a0cdcSGreg Clayton { 937c9858e4dSGreg Clayton Process::StopLocker stop_locker; 938c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 939c9858e4dSGreg Clayton { 9401ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning); 941c9858e4dSGreg Clayton result = true; 942722a0cdcSGreg Clayton } 943c9858e4dSGreg Clayton else 944c9858e4dSGreg Clayton { 945c9858e4dSGreg Clayton if (log) 946c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); 947c9858e4dSGreg Clayton } 948c9858e4dSGreg Clayton } 949c9858e4dSGreg Clayton if (log) 950c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); 951c9858e4dSGreg Clayton return result; 952722a0cdcSGreg Clayton } 953722a0cdcSGreg Clayton 954722a0cdcSGreg Clayton bool 955722a0cdcSGreg Clayton SBThread::IsSuspended() 956722a0cdcSGreg Clayton { 9577fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 9581ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 9591ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 960722a0cdcSGreg Clayton return false; 961722a0cdcSGreg Clayton } 962722a0cdcSGreg Clayton 96330fdc8d8SChris Lattner SBProcess 96430fdc8d8SChris Lattner SBThread::GetProcess () 96530fdc8d8SChris Lattner { 966ceb6b139SCaroline Tice 967b9556accSGreg Clayton SBProcess sb_process; 968b9556accSGreg Clayton ProcessSP process_sp; 9697fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 9701ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 97130fdc8d8SChris Lattner { 97230fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 9731ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 97430fdc8d8SChris Lattner } 975ceb6b139SCaroline Tice 9762d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 977ceb6b139SCaroline Tice if (log) 978ceb6b139SCaroline Tice { 979481cef25SGreg Clayton SBStream frame_desc_strm; 980b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 9811ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), 982b9556accSGreg Clayton process_sp.get(), frame_desc_strm.GetData()); 983ceb6b139SCaroline Tice } 984ceb6b139SCaroline Tice 985b9556accSGreg Clayton return sb_process; 98630fdc8d8SChris Lattner } 98730fdc8d8SChris Lattner 98830fdc8d8SChris Lattner uint32_t 98930fdc8d8SChris Lattner SBThread::GetNumFrames () 99030fdc8d8SChris Lattner { 9912d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 992ceb6b139SCaroline Tice 993ceb6b139SCaroline Tice uint32_t num_frames = 0; 9944fc6cb9cSJim Ingham Mutex::Locker api_locker; 9954fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 9964fc6cb9cSJim Ingham 9971ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 998af67cecdSGreg Clayton { 9997fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10007fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10017fdf9ef1SGreg Clayton { 10021ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1003af67cecdSGreg Clayton } 1004c9858e4dSGreg Clayton else 1005c9858e4dSGreg Clayton { 1006c9858e4dSGreg Clayton if (log) 1007c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); 1008c9858e4dSGreg Clayton } 10097fdf9ef1SGreg Clayton } 1010ceb6b139SCaroline Tice 1011ceb6b139SCaroline Tice if (log) 10121ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); 1013ceb6b139SCaroline Tice 1014ceb6b139SCaroline Tice return num_frames; 101530fdc8d8SChris Lattner } 101630fdc8d8SChris Lattner 101730fdc8d8SChris Lattner SBFrame 101830fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 101930fdc8d8SChris Lattner { 10202d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1021ceb6b139SCaroline Tice 102230fdc8d8SChris Lattner SBFrame sb_frame; 1023b9556accSGreg Clayton StackFrameSP frame_sp; 10244fc6cb9cSJim Ingham Mutex::Locker api_locker; 10254fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10264fc6cb9cSJim Ingham 10271ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1028af67cecdSGreg Clayton { 10297fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10307fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10317fdf9ef1SGreg Clayton { 10321ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1033b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1034af67cecdSGreg Clayton } 1035c9858e4dSGreg Clayton else 1036c9858e4dSGreg Clayton { 1037c9858e4dSGreg Clayton if (log) 1038c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 1039c9858e4dSGreg Clayton } 10407fdf9ef1SGreg Clayton } 1041ceb6b139SCaroline Tice 1042ceb6b139SCaroline Tice if (log) 1043ceb6b139SCaroline Tice { 1044481cef25SGreg Clayton SBStream frame_desc_strm; 1045481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 10464838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 10471ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1048ceb6b139SCaroline Tice } 1049ceb6b139SCaroline Tice 105030fdc8d8SChris Lattner return sb_frame; 105130fdc8d8SChris Lattner } 105230fdc8d8SChris Lattner 1053f028a1fbSGreg Clayton lldb::SBFrame 1054f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1055f028a1fbSGreg Clayton { 1056f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1057f028a1fbSGreg Clayton 1058f028a1fbSGreg Clayton SBFrame sb_frame; 1059b9556accSGreg Clayton StackFrameSP frame_sp; 10604fc6cb9cSJim Ingham Mutex::Locker api_locker; 10614fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10624fc6cb9cSJim Ingham 10631ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1064af67cecdSGreg Clayton { 10657fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10667fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 10677fdf9ef1SGreg Clayton { 10681ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1069b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1070af67cecdSGreg Clayton } 1071c9858e4dSGreg Clayton else 1072c9858e4dSGreg Clayton { 1073c9858e4dSGreg Clayton if (log) 1074c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1075c9858e4dSGreg Clayton } 10767fdf9ef1SGreg Clayton } 1077f028a1fbSGreg Clayton 1078f028a1fbSGreg Clayton if (log) 1079f028a1fbSGreg Clayton { 1080481cef25SGreg Clayton SBStream frame_desc_strm; 1081481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1082f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 10831ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 1084f028a1fbSGreg Clayton } 1085f028a1fbSGreg Clayton 1086f028a1fbSGreg Clayton return sb_frame; 1087f028a1fbSGreg Clayton } 1088f028a1fbSGreg Clayton 1089f028a1fbSGreg Clayton lldb::SBFrame 1090f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1091f028a1fbSGreg Clayton { 1092f028a1fbSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1093f028a1fbSGreg Clayton 1094f028a1fbSGreg Clayton SBFrame sb_frame; 1095b9556accSGreg Clayton StackFrameSP frame_sp; 10964fc6cb9cSJim Ingham Mutex::Locker api_locker; 10974fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10984fc6cb9cSJim Ingham 10991ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1100f028a1fbSGreg Clayton { 11017fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11027fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11037fdf9ef1SGreg Clayton { 11041ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 11051ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1106f028a1fbSGreg Clayton if (frame_sp) 1107f028a1fbSGreg Clayton { 11081ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1109b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1110f028a1fbSGreg Clayton } 1111f028a1fbSGreg Clayton } 1112c9858e4dSGreg Clayton else 1113c9858e4dSGreg Clayton { 1114c9858e4dSGreg Clayton if (log) 1115c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1116c9858e4dSGreg Clayton } 11177fdf9ef1SGreg Clayton } 1118f028a1fbSGreg Clayton 1119f028a1fbSGreg Clayton if (log) 1120f028a1fbSGreg Clayton { 1121481cef25SGreg Clayton SBStream frame_desc_strm; 1122481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1123f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 11241ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1125f028a1fbSGreg Clayton } 1126f028a1fbSGreg Clayton return sb_frame; 1127f028a1fbSGreg Clayton } 1128f028a1fbSGreg Clayton 1129f028a1fbSGreg Clayton 113030fdc8d8SChris Lattner bool 113130fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 113230fdc8d8SChris Lattner { 11337fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 113430fdc8d8SChris Lattner } 113530fdc8d8SChris Lattner 113630fdc8d8SChris Lattner bool 113730fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 113830fdc8d8SChris Lattner { 11397fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 114030fdc8d8SChris Lattner } 1141dde9cff3SCaroline Tice 1142dde9cff3SCaroline Tice bool 1143ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1144ceb6b139SCaroline Tice { 1145da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1146da7bc7d0SGreg Clayton 11477fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 11481ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1149ceb6b139SCaroline Tice { 11501ac04c30SGreg Clayton strm.Printf("SBThread: tid = 0x%4.4llx", exe_ctx.GetThreadPtr()->GetID()); 1151ceb6b139SCaroline Tice } 1152ceb6b139SCaroline Tice else 1153da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1154ceb6b139SCaroline Tice 1155ceb6b139SCaroline Tice return true; 1156ceb6b139SCaroline Tice } 1157