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 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 124c5de699SEli Friedman #include "lldb/API/SBThread.h" 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner #include "lldb/API/SBSymbolContext.h" 1530fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 16dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 174e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 186611103cSGreg Clayton #include "lldb/Core/Debugger.h" 19a75418dbSAndrew Kaylor #include "lldb/Core/State.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 2130fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 235dd4916fSJason Molenda #include "lldb/Target/SystemRuntime.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Process.h" 2630fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h" 2730fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h" 28f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h" 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner 374c5de699SEli Friedman #include "lldb/API/SBAddress.h" 384c5de699SEli Friedman #include "lldb/API/SBDebugger.h" 394f465cffSJim Ingham #include "lldb/API/SBEvent.h" 4073ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 414c5de699SEli Friedman #include "lldb/API/SBProcess.h" 4273ca05a2SJim Ingham #include "lldb/API/SBValue.h" 4330fdc8d8SChris Lattner 4430fdc8d8SChris Lattner using namespace lldb; 4530fdc8d8SChris Lattner using namespace lldb_private; 4630fdc8d8SChris Lattner 474f465cffSJim Ingham const char * 484f465cffSJim Ingham SBThread::GetBroadcasterClassName () 494f465cffSJim Ingham { 504f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 514f465cffSJim Ingham } 524f465cffSJim Ingham 53cfd1acedSGreg Clayton //---------------------------------------------------------------------- 54cfd1acedSGreg Clayton // Constructors 55cfd1acedSGreg Clayton //---------------------------------------------------------------------- 5630fdc8d8SChris Lattner SBThread::SBThread () : 577fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef()) 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner } 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 627fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) 6330fdc8d8SChris Lattner { 6430fdc8d8SChris Lattner } 6530fdc8d8SChris Lattner 6692ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 677fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) 6830fdc8d8SChris Lattner { 697fdf9ef1SGreg Clayton 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner 7230fdc8d8SChris Lattner //---------------------------------------------------------------------- 73cfd1acedSGreg Clayton // Assignment operator 74cfd1acedSGreg Clayton //---------------------------------------------------------------------- 75cfd1acedSGreg Clayton 76cfd1acedSGreg Clayton const lldb::SBThread & 77cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 78cfd1acedSGreg Clayton { 79cfd1acedSGreg Clayton if (this != &rhs) 807fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 81cfd1acedSGreg Clayton return *this; 82cfd1acedSGreg Clayton } 83cfd1acedSGreg Clayton 84cfd1acedSGreg Clayton //---------------------------------------------------------------------- 8530fdc8d8SChris Lattner // Destructor 8630fdc8d8SChris Lattner //---------------------------------------------------------------------- 8730fdc8d8SChris Lattner SBThread::~SBThread() 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner } 9030fdc8d8SChris Lattner 9130fdc8d8SChris Lattner bool 9230fdc8d8SChris Lattner SBThread::IsValid() const 9330fdc8d8SChris Lattner { 947fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 9530fdc8d8SChris Lattner } 9630fdc8d8SChris Lattner 9748e42549SGreg Clayton void 9848e42549SGreg Clayton SBThread::Clear () 9948e42549SGreg Clayton { 1007fdf9ef1SGreg Clayton m_opaque_sp->Clear(); 10148e42549SGreg Clayton } 10248e42549SGreg Clayton 10348e42549SGreg Clayton 10430fdc8d8SChris Lattner StopReason 10530fdc8d8SChris Lattner SBThread::GetStopReason() 10630fdc8d8SChris Lattner { 1075160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 108ceb6b139SCaroline Tice 109ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 1104fc6cb9cSJim Ingham Mutex::Locker api_locker; 1114fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1124fc6cb9cSJim Ingham 1131ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 11430fdc8d8SChris Lattner { 1157fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1167fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1177fdf9ef1SGreg Clayton { 11897d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 11930fdc8d8SChris Lattner } 120c9858e4dSGreg Clayton else 121c9858e4dSGreg Clayton { 122c9858e4dSGreg Clayton if (log) 123c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr()); 124c9858e4dSGreg Clayton } 1257fdf9ef1SGreg Clayton } 126ceb6b139SCaroline Tice 127ceb6b139SCaroline Tice if (log) 1281ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(), 129750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 130ceb6b139SCaroline Tice 131ceb6b139SCaroline Tice return reason; 13230fdc8d8SChris Lattner } 13330fdc8d8SChris Lattner 13430fdc8d8SChris Lattner size_t 1354e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1364e78f606SGreg Clayton { 1374fc6cb9cSJim Ingham Mutex::Locker api_locker; 1384fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1394fc6cb9cSJim Ingham 1401ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1414e78f606SGreg Clayton { 1427fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1437fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1447fdf9ef1SGreg Clayton { 1451ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1464e78f606SGreg Clayton if (stop_info_sp) 1474e78f606SGreg Clayton { 1484e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1494e78f606SGreg Clayton switch (reason) 1504e78f606SGreg Clayton { 1514e78f606SGreg Clayton case eStopReasonInvalid: 1524e78f606SGreg Clayton case eStopReasonNone: 1534e78f606SGreg Clayton case eStopReasonTrace: 15490ba8115SGreg Clayton case eStopReasonExec: 1554e78f606SGreg Clayton case eStopReasonPlanComplete: 156f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 1574e78f606SGreg Clayton // There is no data for these stop reasons. 1584e78f606SGreg Clayton return 0; 1594e78f606SGreg Clayton 1604e78f606SGreg Clayton case eStopReasonBreakpoint: 1614e78f606SGreg Clayton { 1624e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1631ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 1644e78f606SGreg Clayton if (bp_site_sp) 1654e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1664e78f606SGreg Clayton else 1674e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1684e78f606SGreg Clayton } 1694e78f606SGreg Clayton break; 1704e78f606SGreg Clayton 1714e78f606SGreg Clayton case eStopReasonWatchpoint: 172290fa41bSJohnny Chen return 1; 1734e78f606SGreg Clayton 1744e78f606SGreg Clayton case eStopReasonSignal: 1754e78f606SGreg Clayton return 1; 1764e78f606SGreg Clayton 1774e78f606SGreg Clayton case eStopReasonException: 1784e78f606SGreg Clayton return 1; 1794e78f606SGreg Clayton } 1804e78f606SGreg Clayton } 1814e78f606SGreg Clayton } 182c9858e4dSGreg Clayton else 183c9858e4dSGreg Clayton { 1845160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 185c9858e4dSGreg Clayton if (log) 186c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr()); 187c9858e4dSGreg Clayton } 1887fdf9ef1SGreg Clayton } 1894e78f606SGreg Clayton return 0; 1904e78f606SGreg Clayton } 1914e78f606SGreg Clayton 1924e78f606SGreg Clayton uint64_t 1934e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1944e78f606SGreg Clayton { 1954fc6cb9cSJim Ingham Mutex::Locker api_locker; 1964fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1974fc6cb9cSJim Ingham 1981ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1994e78f606SGreg Clayton { 2007fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2017fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2027fdf9ef1SGreg Clayton { 2031ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2041ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 2054e78f606SGreg Clayton if (stop_info_sp) 2064e78f606SGreg Clayton { 2074e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 2084e78f606SGreg Clayton switch (reason) 2094e78f606SGreg Clayton { 2104e78f606SGreg Clayton case eStopReasonInvalid: 2114e78f606SGreg Clayton case eStopReasonNone: 2124e78f606SGreg Clayton case eStopReasonTrace: 21390ba8115SGreg Clayton case eStopReasonExec: 2144e78f606SGreg Clayton case eStopReasonPlanComplete: 215f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 2164e78f606SGreg Clayton // There is no data for these stop reasons. 2174e78f606SGreg Clayton return 0; 2184e78f606SGreg Clayton 2194e78f606SGreg Clayton case eStopReasonBreakpoint: 2204e78f606SGreg Clayton { 2214e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2221ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2234e78f606SGreg Clayton if (bp_site_sp) 2244e78f606SGreg Clayton { 2254e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2264e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2274e78f606SGreg Clayton if (bp_loc_sp) 2284e78f606SGreg Clayton { 2294e78f606SGreg Clayton if (bp_index & 1) 2304e78f606SGreg Clayton { 2314e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2324e78f606SGreg Clayton return bp_loc_sp->GetID(); 2334e78f606SGreg Clayton } 2344e78f606SGreg Clayton else 2354e78f606SGreg Clayton { 2364e78f606SGreg Clayton // Even idx, return the breakpoint ID 2374e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2384e78f606SGreg Clayton } 2394e78f606SGreg Clayton } 2404e78f606SGreg Clayton } 2414e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2424e78f606SGreg Clayton } 2434e78f606SGreg Clayton break; 2444e78f606SGreg Clayton 2454e78f606SGreg Clayton case eStopReasonWatchpoint: 246290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2474e78f606SGreg Clayton 2484e78f606SGreg Clayton case eStopReasonSignal: 2494e78f606SGreg Clayton return stop_info_sp->GetValue(); 2504e78f606SGreg Clayton 2514e78f606SGreg Clayton case eStopReasonException: 2524e78f606SGreg Clayton return stop_info_sp->GetValue(); 2534e78f606SGreg Clayton } 2544e78f606SGreg Clayton } 2554e78f606SGreg Clayton } 256c9858e4dSGreg Clayton else 257c9858e4dSGreg Clayton { 2585160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 259c9858e4dSGreg Clayton if (log) 260c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 261c9858e4dSGreg Clayton } 2627fdf9ef1SGreg Clayton } 2634e78f606SGreg Clayton return 0; 2644e78f606SGreg Clayton } 2654e78f606SGreg Clayton 2664e78f606SGreg Clayton size_t 26730fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 26830fdc8d8SChris Lattner { 2695160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 270ceb6b139SCaroline Tice 2714fc6cb9cSJim Ingham Mutex::Locker api_locker; 2724fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 2734fc6cb9cSJim Ingham 2741ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 27530fdc8d8SChris Lattner { 2767fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2777fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2787fdf9ef1SGreg Clayton { 2797fdf9ef1SGreg Clayton 2801ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 281b15bfc75SJim Ingham if (stop_info_sp) 28230fdc8d8SChris Lattner { 283b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 28430fdc8d8SChris Lattner if (stop_desc) 28530fdc8d8SChris Lattner { 286ceb6b139SCaroline Tice if (log) 2874838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 2881ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 28930fdc8d8SChris Lattner if (dst) 29030fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 29130fdc8d8SChris Lattner else 29230fdc8d8SChris Lattner { 29330fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 29430fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 29530fdc8d8SChris Lattner } 29630fdc8d8SChris Lattner } 29730fdc8d8SChris Lattner else 29830fdc8d8SChris Lattner { 29930fdc8d8SChris Lattner size_t stop_desc_len = 0; 300b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 30130fdc8d8SChris Lattner { 30230fdc8d8SChris Lattner case eStopReasonTrace: 30330fdc8d8SChris Lattner case eStopReasonPlanComplete: 30430fdc8d8SChris Lattner { 30530fdc8d8SChris Lattner static char trace_desc[] = "step"; 30630fdc8d8SChris Lattner stop_desc = trace_desc; 30730fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 30830fdc8d8SChris Lattner } 30930fdc8d8SChris Lattner break; 31030fdc8d8SChris Lattner 31130fdc8d8SChris Lattner case eStopReasonBreakpoint: 31230fdc8d8SChris Lattner { 31330fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 31430fdc8d8SChris Lattner stop_desc = bp_desc; 31530fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 31630fdc8d8SChris Lattner } 31730fdc8d8SChris Lattner break; 31830fdc8d8SChris Lattner 31930fdc8d8SChris Lattner case eStopReasonWatchpoint: 32030fdc8d8SChris Lattner { 32130fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 32230fdc8d8SChris Lattner stop_desc = wp_desc; 32330fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 32430fdc8d8SChris Lattner } 32530fdc8d8SChris Lattner break; 32630fdc8d8SChris Lattner 32730fdc8d8SChris Lattner case eStopReasonSignal: 32830fdc8d8SChris Lattner { 3291ac04c30SGreg Clayton stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 33030fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 33130fdc8d8SChris Lattner { 33230fdc8d8SChris Lattner static char signal_desc[] = "signal"; 33330fdc8d8SChris Lattner stop_desc = signal_desc; 33430fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 33530fdc8d8SChris Lattner } 33630fdc8d8SChris Lattner } 33730fdc8d8SChris Lattner break; 33830fdc8d8SChris Lattner 33930fdc8d8SChris Lattner case eStopReasonException: 34030fdc8d8SChris Lattner { 34130fdc8d8SChris Lattner char exc_desc[] = "exception"; 34230fdc8d8SChris Lattner stop_desc = exc_desc; 34330fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 34430fdc8d8SChris Lattner } 34530fdc8d8SChris Lattner break; 346c982c768SGreg Clayton 34790ba8115SGreg Clayton case eStopReasonExec: 34890ba8115SGreg Clayton { 34990ba8115SGreg Clayton char exc_desc[] = "exec"; 35090ba8115SGreg Clayton stop_desc = exc_desc; 35190ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 35290ba8115SGreg Clayton } 35390ba8115SGreg Clayton break; 35490ba8115SGreg Clayton 355f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 356f85defaeSAndrew Kaylor { 357f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 358f85defaeSAndrew Kaylor stop_desc = limbo_desc; 359f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 360f85defaeSAndrew Kaylor } 361f85defaeSAndrew Kaylor break; 362c982c768SGreg Clayton default: 363c982c768SGreg Clayton break; 36430fdc8d8SChris Lattner } 36530fdc8d8SChris Lattner 36630fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 36730fdc8d8SChris Lattner { 368ceb6b139SCaroline Tice if (log) 36993aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 3701ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), stop_desc); 371ceb6b139SCaroline Tice 37230fdc8d8SChris Lattner if (dst) 37330fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 37430fdc8d8SChris Lattner 37530fdc8d8SChris Lattner if (stop_desc_len == 0) 37630fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 37730fdc8d8SChris Lattner 37830fdc8d8SChris Lattner return stop_desc_len; 37930fdc8d8SChris Lattner } 38030fdc8d8SChris Lattner } 38130fdc8d8SChris Lattner } 38230fdc8d8SChris Lattner } 383c9858e4dSGreg Clayton else 384c9858e4dSGreg Clayton { 3855160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 386c9858e4dSGreg Clayton if (log) 387c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr()); 388c9858e4dSGreg Clayton } 3897fdf9ef1SGreg Clayton } 39030fdc8d8SChris Lattner if (dst) 39130fdc8d8SChris Lattner *dst = 0; 39230fdc8d8SChris Lattner return 0; 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner 39573ca05a2SJim Ingham SBValue 39673ca05a2SJim Ingham SBThread::GetStopReturnValue () 39773ca05a2SJim Ingham { 3985160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 39973ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 4004fc6cb9cSJim Ingham Mutex::Locker api_locker; 4014fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4024fc6cb9cSJim Ingham 4031ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 40473ca05a2SJim Ingham { 4057fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4067fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4077fdf9ef1SGreg Clayton { 4081ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 40973ca05a2SJim Ingham if (stop_info_sp) 41073ca05a2SJim Ingham { 41173ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 41273ca05a2SJim Ingham } 41373ca05a2SJim Ingham } 414c9858e4dSGreg Clayton else 415c9858e4dSGreg Clayton { 416c9858e4dSGreg Clayton if (log) 417c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr()); 418c9858e4dSGreg Clayton } 4197fdf9ef1SGreg Clayton } 42073ca05a2SJim Ingham 42173ca05a2SJim Ingham if (log) 4221ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(), 42373ca05a2SJim Ingham return_valobj_sp.get() 42473ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 42573ca05a2SJim Ingham : "<no return value>"); 42673ca05a2SJim Ingham 42773ca05a2SJim Ingham return SBValue (return_valobj_sp); 42873ca05a2SJim Ingham } 42973ca05a2SJim Ingham 43030fdc8d8SChris Lattner void 43130fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 43230fdc8d8SChris Lattner { 4337fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 43430fdc8d8SChris Lattner } 43530fdc8d8SChris Lattner 43630fdc8d8SChris Lattner lldb::tid_t 43730fdc8d8SChris Lattner SBThread::GetThreadID () const 43830fdc8d8SChris Lattner { 4397fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 44017a6ad05SGreg Clayton if (thread_sp) 4411ac04c30SGreg Clayton return thread_sp->GetID(); 4421ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner 44530fdc8d8SChris Lattner uint32_t 44630fdc8d8SChris Lattner SBThread::GetIndexID () const 44730fdc8d8SChris Lattner { 4487fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 44917a6ad05SGreg Clayton if (thread_sp) 45017a6ad05SGreg Clayton return thread_sp->GetIndexID(); 45130fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 45230fdc8d8SChris Lattner } 4531ac04c30SGreg Clayton 45430fdc8d8SChris Lattner const char * 45530fdc8d8SChris Lattner SBThread::GetName () const 45630fdc8d8SChris Lattner { 4575160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 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 4621ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 463af67cecdSGreg Clayton { 4647fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4657fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4667fdf9ef1SGreg Clayton { 4671ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 468af67cecdSGreg Clayton } 469c9858e4dSGreg Clayton else 470c9858e4dSGreg Clayton { 471c9858e4dSGreg Clayton if (log) 472c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr()); 473c9858e4dSGreg Clayton } 4747fdf9ef1SGreg Clayton } 475ceb6b139SCaroline Tice 476ceb6b139SCaroline Tice if (log) 4771ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 478ceb6b139SCaroline Tice 4794838131bSGreg Clayton return name; 48030fdc8d8SChris Lattner } 48130fdc8d8SChris Lattner 48230fdc8d8SChris Lattner const char * 48330fdc8d8SChris Lattner SBThread::GetQueueName () const 48430fdc8d8SChris Lattner { 4854838131bSGreg Clayton const char *name = NULL; 4864fc6cb9cSJim Ingham Mutex::Locker api_locker; 4874fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4884fc6cb9cSJim Ingham 4895160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4901ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 491af67cecdSGreg Clayton { 4927fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4937fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4947fdf9ef1SGreg Clayton { 4951ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 496af67cecdSGreg Clayton } 497c9858e4dSGreg Clayton else 498c9858e4dSGreg Clayton { 499c9858e4dSGreg Clayton if (log) 500c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr()); 501c9858e4dSGreg Clayton } 5027fdf9ef1SGreg Clayton } 503ceb6b139SCaroline Tice 504ceb6b139SCaroline Tice if (log) 5051ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL"); 506ceb6b139SCaroline Tice 5074838131bSGreg Clayton return name; 50830fdc8d8SChris Lattner } 50930fdc8d8SChris Lattner 5104fdb5863SJason Molenda lldb::queue_id_t 5114fdb5863SJason Molenda SBThread::GetQueueID () const 5124fdb5863SJason Molenda { 5134fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 5144fdb5863SJason Molenda Mutex::Locker api_locker; 5154fdb5863SJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5164fdb5863SJason Molenda 5174fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5184fdb5863SJason Molenda if (exe_ctx.HasThreadScope()) 5194fdb5863SJason Molenda { 5204fdb5863SJason Molenda Process::StopLocker stop_locker; 5214fdb5863SJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5224fdb5863SJason Molenda { 5234fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 5244fdb5863SJason Molenda } 5254fdb5863SJason Molenda else 5264fdb5863SJason Molenda { 5274fdb5863SJason Molenda if (log) 5284fdb5863SJason Molenda log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", exe_ctx.GetThreadPtr()); 5294fdb5863SJason Molenda } 5304fdb5863SJason Molenda } 5314fdb5863SJason Molenda 5324fdb5863SJason Molenda if (log) 5334fdb5863SJason Molenda log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, exe_ctx.GetThreadPtr(), id); 5344fdb5863SJason Molenda 5354fdb5863SJason Molenda return id; 5364fdb5863SJason Molenda } 5374fdb5863SJason Molenda 53864e7ead1SJim Ingham SBError 53964e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 54064e7ead1SJim Ingham { 54164e7ead1SJim Ingham SBError sb_error; 54264e7ead1SJim Ingham 54364e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 54464e7ead1SJim Ingham if (!process) 54564e7ead1SJim Ingham { 54664e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 54764e7ead1SJim Ingham return sb_error; 54864e7ead1SJim Ingham } 54964e7ead1SJim Ingham 55064e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 55164e7ead1SJim Ingham if (!thread) 55264e7ead1SJim Ingham { 55364e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 55464e7ead1SJim Ingham return sb_error; 55564e7ead1SJim Ingham } 55664e7ead1SJim Ingham 55764e7ead1SJim Ingham // User level plans should be Master Plans so they can be interrupted, other plans executed, and 55864e7ead1SJim Ingham // then a "continue" will resume the plan. 55964e7ead1SJim Ingham if (new_plan != NULL) 56064e7ead1SJim Ingham { 56164e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 56264e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 56364e7ead1SJim Ingham } 56464e7ead1SJim Ingham 56564e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 56664e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 56764e7ead1SJim Ingham sb_error.ref() = process->Resume(); 56864e7ead1SJim Ingham 56964e7ead1SJim Ingham if (sb_error.Success()) 57064e7ead1SJim Ingham { 57164e7ead1SJim Ingham // If we are doing synchronous mode, then wait for the 57264e7ead1SJim Ingham // process to stop yet again! 57364e7ead1SJim Ingham if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 57464e7ead1SJim Ingham process->WaitForProcessToStop (NULL); 57564e7ead1SJim Ingham } 57664e7ead1SJim Ingham 57764e7ead1SJim Ingham return sb_error; 57864e7ead1SJim Ingham } 57930fdc8d8SChris Lattner 58030fdc8d8SChris Lattner void 58130fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 58230fdc8d8SChris Lattner { 5835160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 584ceb6b139SCaroline Tice 5854fc6cb9cSJim Ingham Mutex::Locker api_locker; 5864fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5874fc6cb9cSJim Ingham 58817a6ad05SGreg Clayton 589ceb6b139SCaroline Tice if (log) 5901ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), 591ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 592ceb6b139SCaroline Tice 5931ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 59430fdc8d8SChris Lattner { 5951ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 5967ba6e991SJim Ingham bool abort_other_plans = false; 597b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 59830fdc8d8SChris Lattner 5994d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 60030fdc8d8SChris Lattner if (frame_sp) 60130fdc8d8SChris Lattner { 60230fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 60330fdc8d8SChris Lattner { 6044b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 60530fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6064d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 60730fdc8d8SChris Lattner sc.line_entry.range, 60830fdc8d8SChris Lattner sc, 6094b4b2478SJim Ingham stop_other_threads, 6104b4b2478SJim Ingham avoid_no_debug); 61130fdc8d8SChris Lattner } 61230fdc8d8SChris Lattner else 61330fdc8d8SChris Lattner { 6144d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 61530fdc8d8SChris Lattner abort_other_plans, 61630fdc8d8SChris Lattner stop_other_threads); 61730fdc8d8SChris Lattner } 61830fdc8d8SChris Lattner } 61930fdc8d8SChris Lattner 62064e7ead1SJim Ingham // This returns an error, we should use it! 6214d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 62230fdc8d8SChris Lattner } 62330fdc8d8SChris Lattner } 62430fdc8d8SChris Lattner 62530fdc8d8SChris Lattner void 62630fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 62730fdc8d8SChris Lattner { 628c627682eSJim Ingham StepInto (NULL, stop_other_threads); 629c627682eSJim Ingham } 630c627682eSJim Ingham 631c627682eSJim Ingham void 632c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 633c627682eSJim Ingham { 6345160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 635ceb6b139SCaroline Tice 6364fc6cb9cSJim Ingham Mutex::Locker api_locker; 6374fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 63817a6ad05SGreg Clayton 63917a6ad05SGreg Clayton if (log) 640c627682eSJim Ingham log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 641c627682eSJim Ingham exe_ctx.GetThreadPtr(), 642c627682eSJim Ingham target_name? target_name: "<NULL>", 64317a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 644c627682eSJim Ingham 6451ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 64630fdc8d8SChris Lattner { 6477ba6e991SJim Ingham bool abort_other_plans = false; 64830fdc8d8SChris Lattner 6491ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 650b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 6514d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 65230fdc8d8SChris Lattner 65330fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 65430fdc8d8SChris Lattner { 6554b4b2478SJim Ingham const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 6564b4b2478SJim Ingham const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 65730fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6584d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 65930fdc8d8SChris Lattner sc.line_entry.range, 66030fdc8d8SChris Lattner sc, 661c627682eSJim Ingham target_name, 662474966a4SGreg Clayton stop_other_threads, 6634b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 6644b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 66530fdc8d8SChris Lattner } 66630fdc8d8SChris Lattner else 66730fdc8d8SChris Lattner { 6684d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 66930fdc8d8SChris Lattner abort_other_plans, 67030fdc8d8SChris Lattner stop_other_threads); 67130fdc8d8SChris Lattner } 67230fdc8d8SChris Lattner 67364e7ead1SJim Ingham // This returns an error, we should use it! 6744d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 67530fdc8d8SChris Lattner } 67630fdc8d8SChris Lattner } 67730fdc8d8SChris Lattner 67830fdc8d8SChris Lattner void 67930fdc8d8SChris Lattner SBThread::StepOut () 68030fdc8d8SChris Lattner { 6815160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 682ceb6b139SCaroline Tice 6834fc6cb9cSJim Ingham Mutex::Locker api_locker; 6844fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6854fc6cb9cSJim Ingham 686ceb6b139SCaroline Tice 68717a6ad05SGreg Clayton if (log) 6881ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); 68917a6ad05SGreg Clayton 6901ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 69130fdc8d8SChris Lattner { 6927ba6e991SJim Ingham bool abort_other_plans = false; 69394b09246SJim Ingham bool stop_other_threads = false; 69430fdc8d8SChris Lattner 6951ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6961ac04c30SGreg Clayton 6974b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 6984d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 699481cef25SGreg Clayton NULL, 700481cef25SGreg Clayton false, 701481cef25SGreg Clayton stop_other_threads, 702481cef25SGreg Clayton eVoteYes, 703481cef25SGreg Clayton eVoteNoOpinion, 7044b4b2478SJim Ingham 0, 7054b4b2478SJim Ingham avoid_no_debug)); 706481cef25SGreg Clayton 70764e7ead1SJim Ingham // This returns an error, we should use it! 7084d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 709481cef25SGreg Clayton } 710481cef25SGreg Clayton } 711481cef25SGreg Clayton 712481cef25SGreg Clayton void 713481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 714481cef25SGreg Clayton { 7155160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 716481cef25SGreg Clayton 7174fc6cb9cSJim Ingham Mutex::Locker api_locker; 7184fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7194fc6cb9cSJim Ingham 720b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 721481cef25SGreg Clayton if (log) 722481cef25SGreg Clayton { 723481cef25SGreg Clayton SBStream frame_desc_strm; 724481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 7251ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 726481cef25SGreg Clayton } 727481cef25SGreg Clayton 7281ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 729481cef25SGreg Clayton { 7307ba6e991SJim Ingham bool abort_other_plans = false; 73194b09246SJim Ingham bool stop_other_threads = false; 7321ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 733481cef25SGreg Clayton 7344d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 735481cef25SGreg Clayton NULL, 736481cef25SGreg Clayton false, 737481cef25SGreg Clayton stop_other_threads, 738481cef25SGreg Clayton eVoteYes, 739481cef25SGreg Clayton eVoteNoOpinion, 7404d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 74130fdc8d8SChris Lattner 74264e7ead1SJim Ingham // This returns an error, we should use it! 7434d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 74430fdc8d8SChris Lattner } 74530fdc8d8SChris Lattner } 74630fdc8d8SChris Lattner 74730fdc8d8SChris Lattner void 74830fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 74930fdc8d8SChris Lattner { 7505160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 751ceb6b139SCaroline Tice 7524fc6cb9cSJim Ingham Mutex::Locker api_locker; 7534fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7544fc6cb9cSJim Ingham 7551ac04c30SGreg Clayton 756ceb6b139SCaroline Tice 75717a6ad05SGreg Clayton if (log) 7581ac04c30SGreg Clayton log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over); 75917a6ad05SGreg Clayton 7601ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 76130fdc8d8SChris Lattner { 7621ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7634d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 76464e7ead1SJim Ingham 76564e7ead1SJim Ingham // This returns an error, we should use it! 7664d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 76730fdc8d8SChris Lattner } 76830fdc8d8SChris Lattner } 76930fdc8d8SChris Lattner 77030fdc8d8SChris Lattner void 77130fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 77230fdc8d8SChris Lattner { 7735160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 774ceb6b139SCaroline Tice 7754fc6cb9cSJim Ingham Mutex::Locker api_locker; 7764fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7774fc6cb9cSJim Ingham 778ceb6b139SCaroline Tice 77917a6ad05SGreg Clayton if (log) 780d01b2953SDaniel Malea log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr); 78117a6ad05SGreg Clayton 7821ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 78330fdc8d8SChris Lattner { 7847ba6e991SJim Ingham bool abort_other_plans = false; 78530fdc8d8SChris Lattner bool stop_other_threads = true; 78630fdc8d8SChris Lattner 787e72dfb32SGreg Clayton Address target_addr (addr); 78830fdc8d8SChris Lattner 7891ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7901ac04c30SGreg Clayton 7914d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); 79264e7ead1SJim Ingham 79364e7ead1SJim Ingham // This returns an error, we should use it! 7944d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 79530fdc8d8SChris Lattner } 79630fdc8d8SChris Lattner } 79730fdc8d8SChris Lattner 798481cef25SGreg Clayton SBError 799481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 800481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 801481cef25SGreg Clayton uint32_t line) 802481cef25SGreg Clayton { 803481cef25SGreg Clayton SBError sb_error; 8045160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 805481cef25SGreg Clayton char path[PATH_MAX]; 806481cef25SGreg Clayton 8074fc6cb9cSJim Ingham Mutex::Locker api_locker; 8084fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8094fc6cb9cSJim Ingham 810b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 81117a6ad05SGreg Clayton 812481cef25SGreg Clayton if (log) 813481cef25SGreg Clayton { 814481cef25SGreg Clayton SBStream frame_desc_strm; 815481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 816481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 817481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 8181ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), 819b9556accSGreg Clayton frame_sp.get(), 820481cef25SGreg Clayton frame_desc_strm.GetData(), 821481cef25SGreg Clayton path, line); 822481cef25SGreg Clayton } 823481cef25SGreg Clayton 8241ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 825481cef25SGreg Clayton { 8261ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 8271ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 828481cef25SGreg Clayton 829481cef25SGreg Clayton if (line == 0) 830481cef25SGreg Clayton { 831481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 832481cef25SGreg Clayton return sb_error; 833481cef25SGreg Clayton } 834481cef25SGreg Clayton 835b9556accSGreg Clayton if (!frame_sp) 836481cef25SGreg Clayton { 8371ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 838481cef25SGreg Clayton if (!frame_sp) 8391ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 840481cef25SGreg Clayton } 841481cef25SGreg Clayton 842481cef25SGreg Clayton SymbolContext frame_sc; 843481cef25SGreg Clayton if (!frame_sp) 844481cef25SGreg Clayton { 845481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 846481cef25SGreg Clayton return sb_error; 847481cef25SGreg Clayton } 848481cef25SGreg Clayton 849481cef25SGreg Clayton // If we have a frame, get its line 850481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 851481cef25SGreg Clayton eSymbolContextFunction | 852481cef25SGreg Clayton eSymbolContextLineEntry | 853481cef25SGreg Clayton eSymbolContextSymbol ); 854481cef25SGreg Clayton 855481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 856481cef25SGreg Clayton { 857481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 858481cef25SGreg Clayton return sb_error; 859481cef25SGreg Clayton } 860481cef25SGreg Clayton 861481cef25SGreg Clayton FileSpec step_file_spec; 862481cef25SGreg Clayton if (sb_file_spec.IsValid()) 863481cef25SGreg Clayton { 864481cef25SGreg Clayton // The file spec passed in was valid, so use it 865481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 866481cef25SGreg Clayton } 867481cef25SGreg Clayton else 868481cef25SGreg Clayton { 869481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 870481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 871481cef25SGreg Clayton else 872481cef25SGreg Clayton { 873481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 874481cef25SGreg Clayton return sb_error; 875481cef25SGreg Clayton } 876481cef25SGreg Clayton } 877481cef25SGreg Clayton 8789b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 8799b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 8809b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 8819b70ddb3SJim Ingham // error message. 8829b70ddb3SJim Ingham 8839b70ddb3SJim Ingham bool all_in_function = true; 8849b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 8859b70ddb3SJim Ingham 886481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 8877ba6e991SJim Ingham const bool abort_other_plans = false; 888c02e3344SJim Ingham const bool stop_other_threads = false; 889481cef25SGreg Clayton const bool check_inlines = true; 890481cef25SGreg Clayton const bool exact = false; 891481cef25SGreg Clayton 892481cef25SGreg Clayton SymbolContextList sc_list; 8939b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 8949b70ddb3SJim Ingham line, 8959b70ddb3SJim Ingham check_inlines, 8969b70ddb3SJim Ingham exact, 8979b70ddb3SJim Ingham eSymbolContextLineEntry, 8989b70ddb3SJim Ingham sc_list); 899481cef25SGreg Clayton if (num_matches > 0) 900481cef25SGreg Clayton { 901481cef25SGreg Clayton SymbolContext sc; 902481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 903481cef25SGreg Clayton { 904481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 905481cef25SGreg Clayton { 9069b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 907481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 908481cef25SGreg Clayton { 9099b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 910481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9119b70ddb3SJim Ingham else 9129b70ddb3SJim Ingham all_in_function = false; 913481cef25SGreg Clayton } 914481cef25SGreg Clayton } 915481cef25SGreg Clayton } 916481cef25SGreg Clayton } 917481cef25SGreg Clayton 918481cef25SGreg Clayton if (step_over_until_addrs.empty()) 919481cef25SGreg Clayton { 9209b70ddb3SJim Ingham if (all_in_function) 9219b70ddb3SJim Ingham { 922481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 923fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 924481cef25SGreg Clayton } 925481cef25SGreg Clayton else 92686edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 9279b70ddb3SJim Ingham } 9289b70ddb3SJim Ingham else 929481cef25SGreg Clayton { 9304d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 931481cef25SGreg Clayton &step_over_until_addrs[0], 932481cef25SGreg Clayton step_over_until_addrs.size(), 933481cef25SGreg Clayton stop_other_threads, 9344d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 935481cef25SGreg Clayton 9364d56e9c1SJim Ingham sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 937481cef25SGreg Clayton } 938481cef25SGreg Clayton } 939481cef25SGreg Clayton else 940481cef25SGreg Clayton { 941481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 942481cef25SGreg Clayton } 943481cef25SGreg Clayton return sb_error; 944481cef25SGreg Clayton } 945481cef25SGreg Clayton 9464413758cSJim Ingham SBError 947f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 948f86248d9SRichard Mitton { 949f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 950f86248d9SRichard Mitton SBError sb_error; 951f86248d9SRichard Mitton 952f86248d9SRichard Mitton Mutex::Locker api_locker; 953f86248d9SRichard Mitton ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 954f86248d9SRichard Mitton 955f86248d9SRichard Mitton if (log) 956f86248d9SRichard Mitton log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", exe_ctx.GetThreadPtr(), file_spec->GetPath().c_str(), line); 957f86248d9SRichard Mitton 958f86248d9SRichard Mitton if (!exe_ctx.HasThreadScope()) 959f86248d9SRichard Mitton { 960f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 961f86248d9SRichard Mitton return sb_error; 962f86248d9SRichard Mitton } 963f86248d9SRichard Mitton 964f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 965f86248d9SRichard Mitton 966f86248d9SRichard Mitton Error err = thread->JumpToLine (file_spec.get(), line, true); 967f86248d9SRichard Mitton sb_error.SetError (err); 968f86248d9SRichard Mitton return sb_error; 969f86248d9SRichard Mitton } 970f86248d9SRichard Mitton 971f86248d9SRichard Mitton SBError 972cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 9734413758cSJim Ingham { 9744413758cSJim Ingham SBError sb_error; 9754413758cSJim Ingham 9765160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 9774413758cSJim Ingham 9784413758cSJim Ingham Mutex::Locker api_locker; 9794413758cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 9804413758cSJim Ingham 9814413758cSJim Ingham 9824413758cSJim Ingham if (log) 983cb640dd8SJim Ingham log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID()); 9844413758cSJim Ingham 9854413758cSJim Ingham if (exe_ctx.HasThreadScope()) 9864413758cSJim Ingham { 9874413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 988cb640dd8SJim Ingham sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 9894413758cSJim Ingham } 9904413758cSJim Ingham 9914413758cSJim Ingham return sb_error; 9924413758cSJim Ingham } 9934413758cSJim Ingham 994481cef25SGreg Clayton 995722a0cdcSGreg Clayton bool 996722a0cdcSGreg Clayton SBThread::Suspend() 997722a0cdcSGreg Clayton { 9985160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 9997fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1000c9858e4dSGreg Clayton bool result = false; 10011ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1002722a0cdcSGreg Clayton { 1003c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1004c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1005c9858e4dSGreg Clayton { 10061ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1007c9858e4dSGreg Clayton result = true; 1008722a0cdcSGreg Clayton } 1009c9858e4dSGreg Clayton else 1010c9858e4dSGreg Clayton { 1011c9858e4dSGreg Clayton if (log) 1012c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr()); 1013c9858e4dSGreg Clayton } 1014c9858e4dSGreg Clayton } 1015c9858e4dSGreg Clayton if (log) 1016c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result); 1017c9858e4dSGreg Clayton return result; 1018722a0cdcSGreg Clayton } 1019722a0cdcSGreg Clayton 1020722a0cdcSGreg Clayton bool 1021722a0cdcSGreg Clayton SBThread::Resume () 1022722a0cdcSGreg Clayton { 10235160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10247fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1025c9858e4dSGreg Clayton bool result = false; 10261ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1027722a0cdcSGreg Clayton { 1028c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1029c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1030c9858e4dSGreg Clayton { 1031*6c9ed91cSJim Ingham const bool override_suspend = true; 1032*6c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1033c9858e4dSGreg Clayton result = true; 1034722a0cdcSGreg Clayton } 1035c9858e4dSGreg Clayton else 1036c9858e4dSGreg Clayton { 1037c9858e4dSGreg Clayton if (log) 1038c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr()); 1039c9858e4dSGreg Clayton } 1040c9858e4dSGreg Clayton } 1041c9858e4dSGreg Clayton if (log) 1042c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result); 1043c9858e4dSGreg Clayton return result; 1044722a0cdcSGreg Clayton } 1045722a0cdcSGreg Clayton 1046722a0cdcSGreg Clayton bool 1047722a0cdcSGreg Clayton SBThread::IsSuspended() 1048722a0cdcSGreg Clayton { 10497fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10501ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 10511ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1052722a0cdcSGreg Clayton return false; 1053722a0cdcSGreg Clayton } 1054722a0cdcSGreg Clayton 1055a75418dbSAndrew Kaylor bool 1056a75418dbSAndrew Kaylor SBThread::IsStopped() 1057a75418dbSAndrew Kaylor { 1058a75418dbSAndrew Kaylor ExecutionContext exe_ctx (m_opaque_sp.get()); 1059a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1060a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1061a75418dbSAndrew Kaylor return false; 1062a75418dbSAndrew Kaylor } 1063a75418dbSAndrew Kaylor 106430fdc8d8SChris Lattner SBProcess 106530fdc8d8SChris Lattner SBThread::GetProcess () 106630fdc8d8SChris Lattner { 1067b9556accSGreg Clayton SBProcess sb_process; 10687fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10691ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 107030fdc8d8SChris Lattner { 107130fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 10721ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 107330fdc8d8SChris Lattner } 1074ceb6b139SCaroline Tice 10755160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1076ceb6b139SCaroline Tice if (log) 1077ceb6b139SCaroline Tice { 1078481cef25SGreg Clayton SBStream frame_desc_strm; 1079b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 10801ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(), 10810a2df227SEnrico Granata sb_process.GetSP().get(), frame_desc_strm.GetData()); 1082ceb6b139SCaroline Tice } 1083ceb6b139SCaroline Tice 1084b9556accSGreg Clayton return sb_process; 108530fdc8d8SChris Lattner } 108630fdc8d8SChris Lattner 108730fdc8d8SChris Lattner uint32_t 108830fdc8d8SChris Lattner SBThread::GetNumFrames () 108930fdc8d8SChris Lattner { 10905160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1091ceb6b139SCaroline Tice 1092ceb6b139SCaroline Tice uint32_t num_frames = 0; 10934fc6cb9cSJim Ingham Mutex::Locker api_locker; 10944fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10954fc6cb9cSJim Ingham 10961ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1097af67cecdSGreg Clayton { 10987fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 10997fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11007fdf9ef1SGreg Clayton { 11011ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1102af67cecdSGreg Clayton } 1103c9858e4dSGreg Clayton else 1104c9858e4dSGreg Clayton { 1105c9858e4dSGreg Clayton if (log) 1106c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr()); 1107c9858e4dSGreg Clayton } 11087fdf9ef1SGreg Clayton } 1109ceb6b139SCaroline Tice 1110ceb6b139SCaroline Tice if (log) 11111ac04c30SGreg Clayton log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames); 1112ceb6b139SCaroline Tice 1113ceb6b139SCaroline Tice return num_frames; 111430fdc8d8SChris Lattner } 111530fdc8d8SChris Lattner 111630fdc8d8SChris Lattner SBFrame 111730fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 111830fdc8d8SChris Lattner { 11195160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1120ceb6b139SCaroline Tice 112130fdc8d8SChris Lattner SBFrame sb_frame; 1122b57e4a1bSJason Molenda StackFrameSP frame_sp; 11234fc6cb9cSJim Ingham Mutex::Locker api_locker; 11244fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11254fc6cb9cSJim Ingham 11261ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1127af67cecdSGreg Clayton { 11287fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11297fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11307fdf9ef1SGreg Clayton { 11311ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1132b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1133af67cecdSGreg Clayton } 1134c9858e4dSGreg Clayton else 1135c9858e4dSGreg Clayton { 1136c9858e4dSGreg Clayton if (log) 1137c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr()); 1138c9858e4dSGreg Clayton } 11397fdf9ef1SGreg Clayton } 1140ceb6b139SCaroline Tice 1141ceb6b139SCaroline Tice if (log) 1142ceb6b139SCaroline Tice { 1143481cef25SGreg Clayton SBStream frame_desc_strm; 1144481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 11454838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 11461ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1147ceb6b139SCaroline Tice } 1148ceb6b139SCaroline Tice 114930fdc8d8SChris Lattner return sb_frame; 115030fdc8d8SChris Lattner } 115130fdc8d8SChris Lattner 1152f028a1fbSGreg Clayton lldb::SBFrame 1153f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1154f028a1fbSGreg Clayton { 11555160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1156f028a1fbSGreg Clayton 1157f028a1fbSGreg Clayton SBFrame sb_frame; 1158b57e4a1bSJason Molenda StackFrameSP frame_sp; 11594fc6cb9cSJim Ingham Mutex::Locker api_locker; 11604fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11614fc6cb9cSJim Ingham 11621ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1163af67cecdSGreg Clayton { 11647fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11657fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11667fdf9ef1SGreg Clayton { 11671ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1168b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1169af67cecdSGreg Clayton } 1170c9858e4dSGreg Clayton else 1171c9858e4dSGreg Clayton { 1172c9858e4dSGreg Clayton if (log) 1173c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1174c9858e4dSGreg Clayton } 11757fdf9ef1SGreg Clayton } 1176f028a1fbSGreg Clayton 1177f028a1fbSGreg Clayton if (log) 1178f028a1fbSGreg Clayton { 1179481cef25SGreg Clayton SBStream frame_desc_strm; 1180481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1181f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 11821ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData()); 1183f028a1fbSGreg Clayton } 1184f028a1fbSGreg Clayton 1185f028a1fbSGreg Clayton return sb_frame; 1186f028a1fbSGreg Clayton } 1187f028a1fbSGreg Clayton 1188f028a1fbSGreg Clayton lldb::SBFrame 1189f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1190f028a1fbSGreg Clayton { 11915160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1192f028a1fbSGreg Clayton 1193f028a1fbSGreg Clayton SBFrame sb_frame; 1194b57e4a1bSJason Molenda StackFrameSP frame_sp; 11954fc6cb9cSJim Ingham Mutex::Locker api_locker; 11964fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11974fc6cb9cSJim Ingham 11981ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1199f028a1fbSGreg Clayton { 12007fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12017fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12027fdf9ef1SGreg Clayton { 12031ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 12041ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1205f028a1fbSGreg Clayton if (frame_sp) 1206f028a1fbSGreg Clayton { 12071ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1208b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1209f028a1fbSGreg Clayton } 1210f028a1fbSGreg Clayton } 1211c9858e4dSGreg Clayton else 1212c9858e4dSGreg Clayton { 1213c9858e4dSGreg Clayton if (log) 1214c9858e4dSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr()); 1215c9858e4dSGreg Clayton } 12167fdf9ef1SGreg Clayton } 1217f028a1fbSGreg Clayton 1218f028a1fbSGreg Clayton if (log) 1219f028a1fbSGreg Clayton { 1220481cef25SGreg Clayton SBStream frame_desc_strm; 1221481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1222f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 12231ac04c30SGreg Clayton exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData()); 1224f028a1fbSGreg Clayton } 1225f028a1fbSGreg Clayton return sb_frame; 1226f028a1fbSGreg Clayton } 1227f028a1fbSGreg Clayton 12284f465cffSJim Ingham bool 12294f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event) 12304f465cffSJim Ingham { 12314f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 12324f465cffSJim Ingham } 12334f465cffSJim Ingham 12344f465cffSJim Ingham SBFrame 12354f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event) 12364f465cffSJim Ingham { 12374f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 12384f465cffSJim Ingham 12394f465cffSJim Ingham } 12404f465cffSJim Ingham 12414f465cffSJim Ingham SBThread 12424f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event) 12434f465cffSJim Ingham { 12444f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 12454f465cffSJim Ingham } 1246f028a1fbSGreg Clayton 124730fdc8d8SChris Lattner bool 124830fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 124930fdc8d8SChris Lattner { 12507fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 125130fdc8d8SChris Lattner } 125230fdc8d8SChris Lattner 125330fdc8d8SChris Lattner bool 125430fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 125530fdc8d8SChris Lattner { 12567fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 125730fdc8d8SChris Lattner } 1258dde9cff3SCaroline Tice 1259dde9cff3SCaroline Tice bool 12604f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const 12614f465cffSJim Ingham { 12624f465cffSJim Ingham Stream &strm = status.ref(); 12634f465cffSJim Ingham 12644f465cffSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get()); 12654f465cffSJim Ingham if (exe_ctx.HasThreadScope()) 12664f465cffSJim Ingham { 12674f465cffSJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 12684f465cffSJim Ingham } 12694f465cffSJim Ingham else 12704f465cffSJim Ingham strm.PutCString ("No status"); 12714f465cffSJim Ingham 12724f465cffSJim Ingham return true; 12734f465cffSJim Ingham } 12744f465cffSJim Ingham 12754f465cffSJim Ingham bool 1276ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1277ceb6b139SCaroline Tice { 1278da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1279da7bc7d0SGreg Clayton 12807fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 12811ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1282ceb6b139SCaroline Tice { 1283d01b2953SDaniel Malea strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1284ceb6b139SCaroline Tice } 1285ceb6b139SCaroline Tice else 1286da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1287ceb6b139SCaroline Tice 1288ceb6b139SCaroline Tice return true; 1289ceb6b139SCaroline Tice } 12905dd4916fSJason Molenda 12915dd4916fSJason Molenda SBThread 1292008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type) 12935dd4916fSJason Molenda { 12945dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 12955dd4916fSJason Molenda Mutex::Locker api_locker; 12965dd4916fSJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 12975dd4916fSJason Molenda SBThread sb_origin_thread; 12985dd4916fSJason Molenda 12995dd4916fSJason Molenda if (exe_ctx.HasThreadScope()) 13005dd4916fSJason Molenda { 13015dd4916fSJason Molenda Process::StopLocker stop_locker; 13025dd4916fSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 13035dd4916fSJason Molenda { 13047a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 13055dd4916fSJason Molenda if (real_thread) 13065dd4916fSJason Molenda { 13075dd4916fSJason Molenda ConstString type_const (type); 13087a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 13097a2f7904SJason Molenda if (process) 13107a2f7904SJason Molenda { 13117a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 13125dd4916fSJason Molenda if (runtime) 13135dd4916fSJason Molenda { 1314008c45f1SJason Molenda ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1315a6e9130dSJason Molenda if (new_thread_sp) 1316a6e9130dSJason Molenda { 13177a2f7904SJason Molenda // Save this in the Process' ExtendedThreadList so a strong pointer retains the 13187a2f7904SJason Molenda // object. 13197a2f7904SJason Molenda process->GetExtendedThreadList().AddThread (new_thread_sp); 13207a2f7904SJason Molenda sb_origin_thread.SetThread (new_thread_sp); 1321a6e9130dSJason Molenda if (log) 1322a6e9130dSJason Molenda { 1323a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1324a6e9130dSJason Molenda if (queue_name == NULL) 1325a6e9130dSJason Molenda queue_name = ""; 1326a6e9130dSJason Molenda log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", exe_ctx.GetThreadPtr(), new_thread_sp.get(), new_thread_sp->GetQueueID(), queue_name); 1327a6e9130dSJason Molenda } 1328a6e9130dSJason Molenda } 13297a2f7904SJason Molenda } 13305dd4916fSJason Molenda } 13315dd4916fSJason Molenda } 13325dd4916fSJason Molenda } 13335dd4916fSJason Molenda else 13345dd4916fSJason Molenda { 13355dd4916fSJason Molenda if (log) 1336a6e9130dSJason Molenda log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", exe_ctx.GetThreadPtr()); 13375dd4916fSJason Molenda } 13385dd4916fSJason Molenda } 13395dd4916fSJason Molenda 1340ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1341ac605f4aSJason Molenda { 1342ac605f4aSJason Molenda log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", exe_ctx.GetThreadPtr()); 1343ac605f4aSJason Molenda } 13445dd4916fSJason Molenda return sb_origin_thread; 13455dd4916fSJason Molenda } 13468ee9cb58SJason Molenda 13478ee9cb58SJason Molenda uint32_t 13488ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID () 13498ee9cb58SJason Molenda { 13508ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13518ee9cb58SJason Molenda if (thread_sp) 13528ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 13538ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 13548ee9cb58SJason Molenda } 1355