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) 123324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", 124324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 125c9858e4dSGreg Clayton } 1267fdf9ef1SGreg Clayton } 127ceb6b139SCaroline Tice 128ceb6b139SCaroline Tice if (log) 129324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason () => %s", 130324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 131750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 132ceb6b139SCaroline Tice 133ceb6b139SCaroline Tice return reason; 13430fdc8d8SChris Lattner } 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner size_t 1374e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1384e78f606SGreg Clayton { 1394fc6cb9cSJim Ingham Mutex::Locker api_locker; 1404fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1414fc6cb9cSJim Ingham 1421ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1434e78f606SGreg Clayton { 1447fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1457fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1467fdf9ef1SGreg Clayton { 1471ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1484e78f606SGreg Clayton if (stop_info_sp) 1494e78f606SGreg Clayton { 1504e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1514e78f606SGreg Clayton switch (reason) 1524e78f606SGreg Clayton { 1534e78f606SGreg Clayton case eStopReasonInvalid: 1544e78f606SGreg Clayton case eStopReasonNone: 1554e78f606SGreg Clayton case eStopReasonTrace: 15690ba8115SGreg Clayton case eStopReasonExec: 1574e78f606SGreg Clayton case eStopReasonPlanComplete: 158f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 1594e78f606SGreg Clayton // There is no data for these stop reasons. 1604e78f606SGreg Clayton return 0; 1614e78f606SGreg Clayton 1624e78f606SGreg Clayton case eStopReasonBreakpoint: 1634e78f606SGreg Clayton { 1644e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 1651ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 1664e78f606SGreg Clayton if (bp_site_sp) 1674e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 1684e78f606SGreg Clayton else 1694e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 1704e78f606SGreg Clayton } 1714e78f606SGreg Clayton break; 1724e78f606SGreg Clayton 1734e78f606SGreg Clayton case eStopReasonWatchpoint: 174290fa41bSJohnny Chen return 1; 1754e78f606SGreg Clayton 1764e78f606SGreg Clayton case eStopReasonSignal: 1774e78f606SGreg Clayton return 1; 1784e78f606SGreg Clayton 1794e78f606SGreg Clayton case eStopReasonException: 1804e78f606SGreg Clayton return 1; 1814e78f606SGreg Clayton } 1824e78f606SGreg Clayton } 1834e78f606SGreg Clayton } 184c9858e4dSGreg Clayton else 185c9858e4dSGreg Clayton { 1865160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 187c9858e4dSGreg Clayton if (log) 188324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", 189324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 190c9858e4dSGreg Clayton } 1917fdf9ef1SGreg Clayton } 1924e78f606SGreg Clayton return 0; 1934e78f606SGreg Clayton } 1944e78f606SGreg Clayton 1954e78f606SGreg Clayton uint64_t 1964e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 1974e78f606SGreg Clayton { 1984fc6cb9cSJim Ingham Mutex::Locker api_locker; 1994fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 2004fc6cb9cSJim Ingham 2011ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 2024e78f606SGreg Clayton { 2037fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2047fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2057fdf9ef1SGreg Clayton { 2061ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2071ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 2084e78f606SGreg Clayton if (stop_info_sp) 2094e78f606SGreg Clayton { 2104e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 2114e78f606SGreg Clayton switch (reason) 2124e78f606SGreg Clayton { 2134e78f606SGreg Clayton case eStopReasonInvalid: 2144e78f606SGreg Clayton case eStopReasonNone: 2154e78f606SGreg Clayton case eStopReasonTrace: 21690ba8115SGreg Clayton case eStopReasonExec: 2174e78f606SGreg Clayton case eStopReasonPlanComplete: 218f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 2194e78f606SGreg Clayton // There is no data for these stop reasons. 2204e78f606SGreg Clayton return 0; 2214e78f606SGreg Clayton 2224e78f606SGreg Clayton case eStopReasonBreakpoint: 2234e78f606SGreg Clayton { 2244e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2251ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2264e78f606SGreg Clayton if (bp_site_sp) 2274e78f606SGreg Clayton { 2284e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2294e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2304e78f606SGreg Clayton if (bp_loc_sp) 2314e78f606SGreg Clayton { 232*8334e14eSGreg Clayton if (idx & 1) 2334e78f606SGreg Clayton { 2344e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2354e78f606SGreg Clayton return bp_loc_sp->GetID(); 2364e78f606SGreg Clayton } 2374e78f606SGreg Clayton else 2384e78f606SGreg Clayton { 2394e78f606SGreg Clayton // Even idx, return the breakpoint ID 2404e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2414e78f606SGreg Clayton } 2424e78f606SGreg Clayton } 2434e78f606SGreg Clayton } 2444e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2454e78f606SGreg Clayton } 2464e78f606SGreg Clayton break; 2474e78f606SGreg Clayton 2484e78f606SGreg Clayton case eStopReasonWatchpoint: 249290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2504e78f606SGreg Clayton 2514e78f606SGreg Clayton case eStopReasonSignal: 2524e78f606SGreg Clayton return stop_info_sp->GetValue(); 2534e78f606SGreg Clayton 2544e78f606SGreg Clayton case eStopReasonException: 2554e78f606SGreg Clayton return stop_info_sp->GetValue(); 2564e78f606SGreg Clayton } 2574e78f606SGreg Clayton } 2584e78f606SGreg Clayton } 259c9858e4dSGreg Clayton else 260c9858e4dSGreg Clayton { 2615160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 262c9858e4dSGreg Clayton if (log) 263324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", 264324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 265c9858e4dSGreg Clayton } 2667fdf9ef1SGreg Clayton } 2674e78f606SGreg Clayton return 0; 2684e78f606SGreg Clayton } 2694e78f606SGreg Clayton 2704e78f606SGreg Clayton size_t 27130fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 27230fdc8d8SChris Lattner { 2735160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 274ceb6b139SCaroline Tice 2754fc6cb9cSJim Ingham Mutex::Locker api_locker; 2764fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 2774fc6cb9cSJim Ingham 2781ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 27930fdc8d8SChris Lattner { 2807fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2817fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2827fdf9ef1SGreg Clayton { 2837fdf9ef1SGreg Clayton 2841ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 285b15bfc75SJim Ingham if (stop_info_sp) 28630fdc8d8SChris Lattner { 287b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 28830fdc8d8SChris Lattner if (stop_desc) 28930fdc8d8SChris Lattner { 290ceb6b139SCaroline Tice if (log) 2914838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 292324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 293324a1036SSaleem Abdulrasool stop_desc); 29430fdc8d8SChris Lattner if (dst) 29530fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 29630fdc8d8SChris Lattner else 29730fdc8d8SChris Lattner { 29830fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 29930fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 30030fdc8d8SChris Lattner } 30130fdc8d8SChris Lattner } 30230fdc8d8SChris Lattner else 30330fdc8d8SChris Lattner { 30430fdc8d8SChris Lattner size_t stop_desc_len = 0; 305b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 30630fdc8d8SChris Lattner { 30730fdc8d8SChris Lattner case eStopReasonTrace: 30830fdc8d8SChris Lattner case eStopReasonPlanComplete: 30930fdc8d8SChris Lattner { 31030fdc8d8SChris Lattner static char trace_desc[] = "step"; 31130fdc8d8SChris Lattner stop_desc = trace_desc; 31230fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 31330fdc8d8SChris Lattner } 31430fdc8d8SChris Lattner break; 31530fdc8d8SChris Lattner 31630fdc8d8SChris Lattner case eStopReasonBreakpoint: 31730fdc8d8SChris Lattner { 31830fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 31930fdc8d8SChris Lattner stop_desc = bp_desc; 32030fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 32130fdc8d8SChris Lattner } 32230fdc8d8SChris Lattner break; 32330fdc8d8SChris Lattner 32430fdc8d8SChris Lattner case eStopReasonWatchpoint: 32530fdc8d8SChris Lattner { 32630fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 32730fdc8d8SChris Lattner stop_desc = wp_desc; 32830fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 32930fdc8d8SChris Lattner } 33030fdc8d8SChris Lattner break; 33130fdc8d8SChris Lattner 33230fdc8d8SChris Lattner case eStopReasonSignal: 33330fdc8d8SChris Lattner { 3341ac04c30SGreg Clayton stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 33530fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 33630fdc8d8SChris Lattner { 33730fdc8d8SChris Lattner static char signal_desc[] = "signal"; 33830fdc8d8SChris Lattner stop_desc = signal_desc; 33930fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 34030fdc8d8SChris Lattner } 34130fdc8d8SChris Lattner } 34230fdc8d8SChris Lattner break; 34330fdc8d8SChris Lattner 34430fdc8d8SChris Lattner case eStopReasonException: 34530fdc8d8SChris Lattner { 34630fdc8d8SChris Lattner char exc_desc[] = "exception"; 34730fdc8d8SChris Lattner stop_desc = exc_desc; 34830fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 34930fdc8d8SChris Lattner } 35030fdc8d8SChris Lattner break; 351c982c768SGreg Clayton 35290ba8115SGreg Clayton case eStopReasonExec: 35390ba8115SGreg Clayton { 35490ba8115SGreg Clayton char exc_desc[] = "exec"; 35590ba8115SGreg Clayton stop_desc = exc_desc; 35690ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 35790ba8115SGreg Clayton } 35890ba8115SGreg Clayton break; 35990ba8115SGreg Clayton 360f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 361f85defaeSAndrew Kaylor { 362f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 363f85defaeSAndrew Kaylor stop_desc = limbo_desc; 364f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 365f85defaeSAndrew Kaylor } 366f85defaeSAndrew Kaylor break; 367c982c768SGreg Clayton default: 368c982c768SGreg Clayton break; 36930fdc8d8SChris Lattner } 37030fdc8d8SChris Lattner 37130fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 37230fdc8d8SChris Lattner { 373ceb6b139SCaroline Tice if (log) 37493aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 375324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 376324a1036SSaleem Abdulrasool stop_desc); 377ceb6b139SCaroline Tice 37830fdc8d8SChris Lattner if (dst) 37930fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 38030fdc8d8SChris Lattner 38130fdc8d8SChris Lattner if (stop_desc_len == 0) 38230fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 38330fdc8d8SChris Lattner 38430fdc8d8SChris Lattner return stop_desc_len; 38530fdc8d8SChris Lattner } 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner } 38830fdc8d8SChris Lattner } 389c9858e4dSGreg Clayton else 390c9858e4dSGreg Clayton { 3915160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 392c9858e4dSGreg Clayton if (log) 393324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", 394324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 395c9858e4dSGreg Clayton } 3967fdf9ef1SGreg Clayton } 39730fdc8d8SChris Lattner if (dst) 39830fdc8d8SChris Lattner *dst = 0; 39930fdc8d8SChris Lattner return 0; 40030fdc8d8SChris Lattner } 40130fdc8d8SChris Lattner 40273ca05a2SJim Ingham SBValue 40373ca05a2SJim Ingham SBThread::GetStopReturnValue () 40473ca05a2SJim Ingham { 4055160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 40673ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 4074fc6cb9cSJim Ingham Mutex::Locker api_locker; 4084fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4094fc6cb9cSJim Ingham 4101ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 41173ca05a2SJim Ingham { 4127fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4137fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4147fdf9ef1SGreg Clayton { 4151ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 41673ca05a2SJim Ingham if (stop_info_sp) 41773ca05a2SJim Ingham { 41873ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 41973ca05a2SJim Ingham } 42073ca05a2SJim Ingham } 421c9858e4dSGreg Clayton else 422c9858e4dSGreg Clayton { 423c9858e4dSGreg Clayton if (log) 424324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", 425324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 426c9858e4dSGreg Clayton } 4277fdf9ef1SGreg Clayton } 42873ca05a2SJim Ingham 42973ca05a2SJim Ingham if (log) 430324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", 431324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 43273ca05a2SJim Ingham return_valobj_sp.get() 43373ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 43473ca05a2SJim Ingham : "<no return value>"); 43573ca05a2SJim Ingham 43673ca05a2SJim Ingham return SBValue (return_valobj_sp); 43773ca05a2SJim Ingham } 43873ca05a2SJim Ingham 43930fdc8d8SChris Lattner void 44030fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 44130fdc8d8SChris Lattner { 4427fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner 44530fdc8d8SChris Lattner lldb::tid_t 44630fdc8d8SChris Lattner SBThread::GetThreadID () const 44730fdc8d8SChris Lattner { 4487fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 44917a6ad05SGreg Clayton if (thread_sp) 4501ac04c30SGreg Clayton return thread_sp->GetID(); 4511ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 45230fdc8d8SChris Lattner } 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner uint32_t 45530fdc8d8SChris Lattner SBThread::GetIndexID () const 45630fdc8d8SChris Lattner { 4577fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 45817a6ad05SGreg Clayton if (thread_sp) 45917a6ad05SGreg Clayton return thread_sp->GetIndexID(); 46030fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 46130fdc8d8SChris Lattner } 4621ac04c30SGreg Clayton 46330fdc8d8SChris Lattner const char * 46430fdc8d8SChris Lattner SBThread::GetName () const 46530fdc8d8SChris Lattner { 4665160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 4674838131bSGreg Clayton const char *name = NULL; 4684fc6cb9cSJim Ingham Mutex::Locker api_locker; 4694fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4704fc6cb9cSJim Ingham 4711ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 472af67cecdSGreg Clayton { 4737fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4747fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4757fdf9ef1SGreg Clayton { 4761ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 477af67cecdSGreg Clayton } 478c9858e4dSGreg Clayton else 479c9858e4dSGreg Clayton { 480c9858e4dSGreg Clayton if (log) 481324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName() => error: process is running", 482324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 483c9858e4dSGreg Clayton } 4847fdf9ef1SGreg Clayton } 485ceb6b139SCaroline Tice 486ceb6b139SCaroline Tice if (log) 487324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName () => %s", 488324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 489324a1036SSaleem Abdulrasool name ? name : "NULL"); 490ceb6b139SCaroline Tice 4914838131bSGreg Clayton return name; 49230fdc8d8SChris Lattner } 49330fdc8d8SChris Lattner 49430fdc8d8SChris Lattner const char * 49530fdc8d8SChris Lattner SBThread::GetQueueName () const 49630fdc8d8SChris Lattner { 4974838131bSGreg Clayton const char *name = NULL; 4984fc6cb9cSJim Ingham Mutex::Locker api_locker; 4994fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5004fc6cb9cSJim Ingham 5015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5021ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 503af67cecdSGreg Clayton { 5047fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 5057fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5067fdf9ef1SGreg Clayton { 5071ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 508af67cecdSGreg Clayton } 509c9858e4dSGreg Clayton else 510c9858e4dSGreg Clayton { 511c9858e4dSGreg Clayton if (log) 512324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", 513324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 514c9858e4dSGreg Clayton } 5157fdf9ef1SGreg Clayton } 516ceb6b139SCaroline Tice 517ceb6b139SCaroline Tice if (log) 518324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName () => %s", 519324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 520324a1036SSaleem Abdulrasool name ? name : "NULL"); 521ceb6b139SCaroline Tice 5224838131bSGreg Clayton return name; 52330fdc8d8SChris Lattner } 52430fdc8d8SChris Lattner 5254fdb5863SJason Molenda lldb::queue_id_t 5264fdb5863SJason Molenda SBThread::GetQueueID () const 5274fdb5863SJason Molenda { 5284fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 5294fdb5863SJason Molenda Mutex::Locker api_locker; 5304fdb5863SJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5314fdb5863SJason Molenda 5324fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5334fdb5863SJason Molenda if (exe_ctx.HasThreadScope()) 5344fdb5863SJason Molenda { 5354fdb5863SJason Molenda Process::StopLocker stop_locker; 5364fdb5863SJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5374fdb5863SJason Molenda { 5384fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 5394fdb5863SJason Molenda } 5404fdb5863SJason Molenda else 5414fdb5863SJason Molenda { 5424fdb5863SJason Molenda if (log) 543324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", 544324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 5454fdb5863SJason Molenda } 5464fdb5863SJason Molenda } 5474fdb5863SJason Molenda 5484fdb5863SJason Molenda if (log) 549324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 550324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), id); 5514fdb5863SJason Molenda 5524fdb5863SJason Molenda return id; 5534fdb5863SJason Molenda } 5544fdb5863SJason Molenda 55564e7ead1SJim Ingham SBError 55664e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 55764e7ead1SJim Ingham { 55864e7ead1SJim Ingham SBError sb_error; 55964e7ead1SJim Ingham 56064e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 56164e7ead1SJim Ingham if (!process) 56264e7ead1SJim Ingham { 56364e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 56464e7ead1SJim Ingham return sb_error; 56564e7ead1SJim Ingham } 56664e7ead1SJim Ingham 56764e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 56864e7ead1SJim Ingham if (!thread) 56964e7ead1SJim Ingham { 57064e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 57164e7ead1SJim Ingham return sb_error; 57264e7ead1SJim Ingham } 57364e7ead1SJim Ingham 57464e7ead1SJim Ingham // User level plans should be Master Plans so they can be interrupted, other plans executed, and 57564e7ead1SJim Ingham // then a "continue" will resume the plan. 57664e7ead1SJim Ingham if (new_plan != NULL) 57764e7ead1SJim Ingham { 57864e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 57964e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 58064e7ead1SJim Ingham } 58164e7ead1SJim Ingham 58264e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 58364e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 58464e7ead1SJim Ingham sb_error.ref() = process->Resume(); 58564e7ead1SJim Ingham 58664e7ead1SJim Ingham if (sb_error.Success()) 58764e7ead1SJim Ingham { 58864e7ead1SJim Ingham // If we are doing synchronous mode, then wait for the 58964e7ead1SJim Ingham // process to stop yet again! 59064e7ead1SJim Ingham if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 59164e7ead1SJim Ingham process->WaitForProcessToStop (NULL); 59264e7ead1SJim Ingham } 59364e7ead1SJim Ingham 59464e7ead1SJim Ingham return sb_error; 59564e7ead1SJim Ingham } 59630fdc8d8SChris Lattner 59730fdc8d8SChris Lattner void 59830fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 59930fdc8d8SChris Lattner { 6005160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 601ceb6b139SCaroline Tice 6024fc6cb9cSJim Ingham Mutex::Locker api_locker; 6034fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6044fc6cb9cSJim Ingham 60517a6ad05SGreg Clayton 606ceb6b139SCaroline Tice if (log) 607324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", 608324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 609ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 610ceb6b139SCaroline Tice 6111ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 61230fdc8d8SChris Lattner { 6131ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6147ba6e991SJim Ingham bool abort_other_plans = false; 615b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 61630fdc8d8SChris Lattner 6174d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 61830fdc8d8SChris Lattner if (frame_sp) 61930fdc8d8SChris Lattner { 62030fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 62130fdc8d8SChris Lattner { 6224b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 62330fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6244d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 62530fdc8d8SChris Lattner sc.line_entry.range, 62630fdc8d8SChris Lattner sc, 6274b4b2478SJim Ingham stop_other_threads, 6284b4b2478SJim Ingham avoid_no_debug); 62930fdc8d8SChris Lattner } 63030fdc8d8SChris Lattner else 63130fdc8d8SChris Lattner { 6324d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 63330fdc8d8SChris Lattner abort_other_plans, 63430fdc8d8SChris Lattner stop_other_threads); 63530fdc8d8SChris Lattner } 63630fdc8d8SChris Lattner } 63730fdc8d8SChris Lattner 63864e7ead1SJim Ingham // This returns an error, we should use it! 6394d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 64030fdc8d8SChris Lattner } 64130fdc8d8SChris Lattner } 64230fdc8d8SChris Lattner 64330fdc8d8SChris Lattner void 64430fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 64530fdc8d8SChris Lattner { 646c627682eSJim Ingham StepInto (NULL, stop_other_threads); 647c627682eSJim Ingham } 648c627682eSJim Ingham 649c627682eSJim Ingham void 650c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 651c627682eSJim Ingham { 6525160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 653ceb6b139SCaroline Tice 6544fc6cb9cSJim Ingham Mutex::Locker api_locker; 6554fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 65617a6ad05SGreg Clayton 65717a6ad05SGreg Clayton if (log) 658c627682eSJim Ingham log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 659324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 660c627682eSJim Ingham target_name? target_name: "<NULL>", 66117a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 662c627682eSJim Ingham 6631ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 66430fdc8d8SChris Lattner { 6657ba6e991SJim Ingham bool abort_other_plans = false; 66630fdc8d8SChris Lattner 6671ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 668b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 6694d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 67030fdc8d8SChris Lattner 67130fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 67230fdc8d8SChris Lattner { 6734b4b2478SJim Ingham const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 6744b4b2478SJim Ingham const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 67530fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6764d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 67730fdc8d8SChris Lattner sc.line_entry.range, 67830fdc8d8SChris Lattner sc, 679c627682eSJim Ingham target_name, 680474966a4SGreg Clayton stop_other_threads, 6814b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 6824b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 68330fdc8d8SChris Lattner } 68430fdc8d8SChris Lattner else 68530fdc8d8SChris Lattner { 6864d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 68730fdc8d8SChris Lattner abort_other_plans, 68830fdc8d8SChris Lattner stop_other_threads); 68930fdc8d8SChris Lattner } 69030fdc8d8SChris Lattner 69164e7ead1SJim Ingham // This returns an error, we should use it! 6924d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 69330fdc8d8SChris Lattner } 69430fdc8d8SChris Lattner } 69530fdc8d8SChris Lattner 69630fdc8d8SChris Lattner void 69730fdc8d8SChris Lattner SBThread::StepOut () 69830fdc8d8SChris Lattner { 6995160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 700ceb6b139SCaroline Tice 7014fc6cb9cSJim Ingham Mutex::Locker api_locker; 7024fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7034fc6cb9cSJim Ingham 704ceb6b139SCaroline Tice 70517a6ad05SGreg Clayton if (log) 706324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOut ()", 707324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 70817a6ad05SGreg Clayton 7091ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 71030fdc8d8SChris Lattner { 7117ba6e991SJim Ingham bool abort_other_plans = false; 71294b09246SJim Ingham bool stop_other_threads = false; 71330fdc8d8SChris Lattner 7141ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7151ac04c30SGreg Clayton 7164b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 7174d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 718481cef25SGreg Clayton NULL, 719481cef25SGreg Clayton false, 720481cef25SGreg Clayton stop_other_threads, 721481cef25SGreg Clayton eVoteYes, 722481cef25SGreg Clayton eVoteNoOpinion, 7234b4b2478SJim Ingham 0, 7244b4b2478SJim Ingham avoid_no_debug)); 725481cef25SGreg Clayton 72664e7ead1SJim Ingham // This returns an error, we should use it! 7274d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 728481cef25SGreg Clayton } 729481cef25SGreg Clayton } 730481cef25SGreg Clayton 731481cef25SGreg Clayton void 732481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 733481cef25SGreg Clayton { 7345160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 735481cef25SGreg Clayton 7364fc6cb9cSJim Ingham Mutex::Locker api_locker; 7374fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7384fc6cb9cSJim Ingham 739b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 740481cef25SGreg Clayton if (log) 741481cef25SGreg Clayton { 742481cef25SGreg Clayton SBStream frame_desc_strm; 743481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 744324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 745324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 746324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 747324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 748481cef25SGreg Clayton } 749481cef25SGreg Clayton 7501ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 751481cef25SGreg Clayton { 7527ba6e991SJim Ingham bool abort_other_plans = false; 75394b09246SJim Ingham bool stop_other_threads = false; 7541ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 755481cef25SGreg Clayton 7564d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 757481cef25SGreg Clayton NULL, 758481cef25SGreg Clayton false, 759481cef25SGreg Clayton stop_other_threads, 760481cef25SGreg Clayton eVoteYes, 761481cef25SGreg Clayton eVoteNoOpinion, 7624d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 76330fdc8d8SChris Lattner 76464e7ead1SJim Ingham // This returns an error, we should use it! 7654d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 76630fdc8d8SChris Lattner } 76730fdc8d8SChris Lattner } 76830fdc8d8SChris Lattner 76930fdc8d8SChris Lattner void 77030fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 77130fdc8d8SChris Lattner { 7725160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 773ceb6b139SCaroline Tice 7744fc6cb9cSJim Ingham Mutex::Locker api_locker; 7754fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7764fc6cb9cSJim Ingham 7771ac04c30SGreg Clayton 778ceb6b139SCaroline Tice 77917a6ad05SGreg Clayton if (log) 780324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", 781324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), step_over); 78217a6ad05SGreg Clayton 7831ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 78430fdc8d8SChris Lattner { 7851ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7864d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 78764e7ead1SJim Ingham 78864e7ead1SJim Ingham // This returns an error, we should use it! 7894d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 79030fdc8d8SChris Lattner } 79130fdc8d8SChris Lattner } 79230fdc8d8SChris Lattner 79330fdc8d8SChris Lattner void 79430fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 79530fdc8d8SChris Lattner { 7965160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 797ceb6b139SCaroline Tice 7984fc6cb9cSJim Ingham Mutex::Locker api_locker; 7994fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8004fc6cb9cSJim Ingham 801ceb6b139SCaroline Tice 80217a6ad05SGreg Clayton if (log) 803324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 804324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), addr); 80517a6ad05SGreg Clayton 8061ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 80730fdc8d8SChris Lattner { 8087ba6e991SJim Ingham bool abort_other_plans = false; 80930fdc8d8SChris Lattner bool stop_other_threads = true; 81030fdc8d8SChris Lattner 811e72dfb32SGreg Clayton Address target_addr (addr); 81230fdc8d8SChris Lattner 8131ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8141ac04c30SGreg Clayton 8154d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); 81664e7ead1SJim Ingham 81764e7ead1SJim Ingham // This returns an error, we should use it! 8184d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 81930fdc8d8SChris Lattner } 82030fdc8d8SChris Lattner } 82130fdc8d8SChris Lattner 822481cef25SGreg Clayton SBError 823481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 824481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 825481cef25SGreg Clayton uint32_t line) 826481cef25SGreg Clayton { 827481cef25SGreg Clayton SBError sb_error; 8285160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 829481cef25SGreg Clayton char path[PATH_MAX]; 830481cef25SGreg Clayton 8314fc6cb9cSJim Ingham Mutex::Locker api_locker; 8324fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8334fc6cb9cSJim Ingham 834b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 83517a6ad05SGreg Clayton 836481cef25SGreg Clayton if (log) 837481cef25SGreg Clayton { 838481cef25SGreg Clayton SBStream frame_desc_strm; 839481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 840481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 841481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 842324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 843324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 844324a1036SSaleem Abdulrasool frame_desc_strm.GetData(), path, line); 845481cef25SGreg Clayton } 846481cef25SGreg Clayton 8471ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 848481cef25SGreg Clayton { 8491ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 8501ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 851481cef25SGreg Clayton 852481cef25SGreg Clayton if (line == 0) 853481cef25SGreg Clayton { 854481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 855481cef25SGreg Clayton return sb_error; 856481cef25SGreg Clayton } 857481cef25SGreg Clayton 858b9556accSGreg Clayton if (!frame_sp) 859481cef25SGreg Clayton { 8601ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 861481cef25SGreg Clayton if (!frame_sp) 8621ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 863481cef25SGreg Clayton } 864481cef25SGreg Clayton 865481cef25SGreg Clayton SymbolContext frame_sc; 866481cef25SGreg Clayton if (!frame_sp) 867481cef25SGreg Clayton { 868481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 869481cef25SGreg Clayton return sb_error; 870481cef25SGreg Clayton } 871481cef25SGreg Clayton 872481cef25SGreg Clayton // If we have a frame, get its line 873481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 874481cef25SGreg Clayton eSymbolContextFunction | 875481cef25SGreg Clayton eSymbolContextLineEntry | 876481cef25SGreg Clayton eSymbolContextSymbol ); 877481cef25SGreg Clayton 878481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 879481cef25SGreg Clayton { 880481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 881481cef25SGreg Clayton return sb_error; 882481cef25SGreg Clayton } 883481cef25SGreg Clayton 884481cef25SGreg Clayton FileSpec step_file_spec; 885481cef25SGreg Clayton if (sb_file_spec.IsValid()) 886481cef25SGreg Clayton { 887481cef25SGreg Clayton // The file spec passed in was valid, so use it 888481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 889481cef25SGreg Clayton } 890481cef25SGreg Clayton else 891481cef25SGreg Clayton { 892481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 893481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 894481cef25SGreg Clayton else 895481cef25SGreg Clayton { 896481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 897481cef25SGreg Clayton return sb_error; 898481cef25SGreg Clayton } 899481cef25SGreg Clayton } 900481cef25SGreg Clayton 9019b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9029b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 9039b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 9049b70ddb3SJim Ingham // error message. 9059b70ddb3SJim Ingham 9069b70ddb3SJim Ingham bool all_in_function = true; 9079b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9089b70ddb3SJim Ingham 909481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9107ba6e991SJim Ingham const bool abort_other_plans = false; 911c02e3344SJim Ingham const bool stop_other_threads = false; 912481cef25SGreg Clayton const bool check_inlines = true; 913481cef25SGreg Clayton const bool exact = false; 914481cef25SGreg Clayton 915481cef25SGreg Clayton SymbolContextList sc_list; 9169b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 9179b70ddb3SJim Ingham line, 9189b70ddb3SJim Ingham check_inlines, 9199b70ddb3SJim Ingham exact, 9209b70ddb3SJim Ingham eSymbolContextLineEntry, 9219b70ddb3SJim Ingham sc_list); 922481cef25SGreg Clayton if (num_matches > 0) 923481cef25SGreg Clayton { 924481cef25SGreg Clayton SymbolContext sc; 925481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 926481cef25SGreg Clayton { 927481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 928481cef25SGreg Clayton { 9299b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 930481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 931481cef25SGreg Clayton { 9329b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 933481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9349b70ddb3SJim Ingham else 9359b70ddb3SJim Ingham all_in_function = false; 936481cef25SGreg Clayton } 937481cef25SGreg Clayton } 938481cef25SGreg Clayton } 939481cef25SGreg Clayton } 940481cef25SGreg Clayton 941481cef25SGreg Clayton if (step_over_until_addrs.empty()) 942481cef25SGreg Clayton { 9439b70ddb3SJim Ingham if (all_in_function) 9449b70ddb3SJim Ingham { 945481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 946fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 947481cef25SGreg Clayton } 948481cef25SGreg Clayton else 94986edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 9509b70ddb3SJim Ingham } 9519b70ddb3SJim Ingham else 952481cef25SGreg Clayton { 9534d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 954481cef25SGreg Clayton &step_over_until_addrs[0], 955481cef25SGreg Clayton step_over_until_addrs.size(), 956481cef25SGreg Clayton stop_other_threads, 9574d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 958481cef25SGreg Clayton 9594d56e9c1SJim Ingham sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 960481cef25SGreg Clayton } 961481cef25SGreg Clayton } 962481cef25SGreg Clayton else 963481cef25SGreg Clayton { 964481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 965481cef25SGreg Clayton } 966481cef25SGreg Clayton return sb_error; 967481cef25SGreg Clayton } 968481cef25SGreg Clayton 9694413758cSJim Ingham SBError 970f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 971f86248d9SRichard Mitton { 972f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 973f86248d9SRichard Mitton SBError sb_error; 974f86248d9SRichard Mitton 975f86248d9SRichard Mitton Mutex::Locker api_locker; 976f86248d9SRichard Mitton ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 977f86248d9SRichard Mitton 978f86248d9SRichard Mitton if (log) 979324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", 980324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 981324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 982f86248d9SRichard Mitton 983f86248d9SRichard Mitton if (!exe_ctx.HasThreadScope()) 984f86248d9SRichard Mitton { 985f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 986f86248d9SRichard Mitton return sb_error; 987f86248d9SRichard Mitton } 988f86248d9SRichard Mitton 989f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 990f86248d9SRichard Mitton 991f86248d9SRichard Mitton Error err = thread->JumpToLine (file_spec.get(), line, true); 992f86248d9SRichard Mitton sb_error.SetError (err); 993f86248d9SRichard Mitton return sb_error; 994f86248d9SRichard Mitton } 995f86248d9SRichard Mitton 996f86248d9SRichard Mitton SBError 997cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 9984413758cSJim Ingham { 9994413758cSJim Ingham SBError sb_error; 10004413758cSJim Ingham 10015160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10024413758cSJim Ingham 10034413758cSJim Ingham Mutex::Locker api_locker; 10044413758cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10054413758cSJim Ingham 10064413758cSJim Ingham 10074413758cSJim Ingham if (log) 1008324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", 1009324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1010324a1036SSaleem Abdulrasool frame.GetFrameID()); 10114413758cSJim Ingham 10124413758cSJim Ingham if (exe_ctx.HasThreadScope()) 10134413758cSJim Ingham { 10144413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1015cb640dd8SJim Ingham sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 10164413758cSJim Ingham } 10174413758cSJim Ingham 10184413758cSJim Ingham return sb_error; 10194413758cSJim Ingham } 10204413758cSJim Ingham 1021481cef25SGreg Clayton 1022722a0cdcSGreg Clayton bool 1023722a0cdcSGreg Clayton SBThread::Suspend() 1024722a0cdcSGreg Clayton { 10255160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10267fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1027c9858e4dSGreg Clayton bool result = false; 10281ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1029722a0cdcSGreg Clayton { 1030c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1031c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1032c9858e4dSGreg Clayton { 10331ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1034c9858e4dSGreg Clayton result = true; 1035722a0cdcSGreg Clayton } 1036c9858e4dSGreg Clayton else 1037c9858e4dSGreg Clayton { 1038c9858e4dSGreg Clayton if (log) 1039324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => error: process is running", 1040324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1041c9858e4dSGreg Clayton } 1042c9858e4dSGreg Clayton } 1043c9858e4dSGreg Clayton if (log) 1044324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => %i", 1045324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1046c9858e4dSGreg Clayton return result; 1047722a0cdcSGreg Clayton } 1048722a0cdcSGreg Clayton 1049722a0cdcSGreg Clayton bool 1050722a0cdcSGreg Clayton SBThread::Resume () 1051722a0cdcSGreg Clayton { 10525160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10537fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1054c9858e4dSGreg Clayton bool result = false; 10551ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1056722a0cdcSGreg Clayton { 1057c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1058c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1059c9858e4dSGreg Clayton { 10606c9ed91cSJim Ingham const bool override_suspend = true; 10616c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1062c9858e4dSGreg Clayton result = true; 1063722a0cdcSGreg Clayton } 1064c9858e4dSGreg Clayton else 1065c9858e4dSGreg Clayton { 1066c9858e4dSGreg Clayton if (log) 1067324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => error: process is running", 1068324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1069c9858e4dSGreg Clayton } 1070c9858e4dSGreg Clayton } 1071c9858e4dSGreg Clayton if (log) 1072324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => %i", 1073324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1074c9858e4dSGreg Clayton return result; 1075722a0cdcSGreg Clayton } 1076722a0cdcSGreg Clayton 1077722a0cdcSGreg Clayton bool 1078722a0cdcSGreg Clayton SBThread::IsSuspended() 1079722a0cdcSGreg Clayton { 10807fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 10811ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 10821ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1083722a0cdcSGreg Clayton return false; 1084722a0cdcSGreg Clayton } 1085722a0cdcSGreg Clayton 1086a75418dbSAndrew Kaylor bool 1087a75418dbSAndrew Kaylor SBThread::IsStopped() 1088a75418dbSAndrew Kaylor { 1089a75418dbSAndrew Kaylor ExecutionContext exe_ctx (m_opaque_sp.get()); 1090a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1091a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1092a75418dbSAndrew Kaylor return false; 1093a75418dbSAndrew Kaylor } 1094a75418dbSAndrew Kaylor 109530fdc8d8SChris Lattner SBProcess 109630fdc8d8SChris Lattner SBThread::GetProcess () 109730fdc8d8SChris Lattner { 1098b9556accSGreg Clayton SBProcess sb_process; 10997fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 11001ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 110130fdc8d8SChris Lattner { 110230fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 11031ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 110430fdc8d8SChris Lattner } 1105ceb6b139SCaroline Tice 11065160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1107ceb6b139SCaroline Tice if (log) 1108ceb6b139SCaroline Tice { 1109481cef25SGreg Clayton SBStream frame_desc_strm; 1110b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 1111324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1112324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1113324a1036SSaleem Abdulrasool static_cast<void*>(sb_process.GetSP().get()), 1114324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1115ceb6b139SCaroline Tice } 1116ceb6b139SCaroline Tice 1117b9556accSGreg Clayton return sb_process; 111830fdc8d8SChris Lattner } 111930fdc8d8SChris Lattner 112030fdc8d8SChris Lattner uint32_t 112130fdc8d8SChris Lattner SBThread::GetNumFrames () 112230fdc8d8SChris Lattner { 11235160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1124ceb6b139SCaroline Tice 1125ceb6b139SCaroline Tice uint32_t num_frames = 0; 11264fc6cb9cSJim Ingham Mutex::Locker api_locker; 11274fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11284fc6cb9cSJim Ingham 11291ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1130af67cecdSGreg Clayton { 11317fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11327fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11337fdf9ef1SGreg Clayton { 11341ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1135af67cecdSGreg Clayton } 1136c9858e4dSGreg Clayton else 1137c9858e4dSGreg Clayton { 1138c9858e4dSGreg Clayton if (log) 1139324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", 1140324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1141c9858e4dSGreg Clayton } 11427fdf9ef1SGreg Clayton } 1143ceb6b139SCaroline Tice 1144ceb6b139SCaroline Tice if (log) 1145324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames () => %u", 1146324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames); 1147ceb6b139SCaroline Tice 1148ceb6b139SCaroline Tice return num_frames; 114930fdc8d8SChris Lattner } 115030fdc8d8SChris Lattner 115130fdc8d8SChris Lattner SBFrame 115230fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 115330fdc8d8SChris Lattner { 11545160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1155ceb6b139SCaroline Tice 115630fdc8d8SChris Lattner SBFrame sb_frame; 1157b57e4a1bSJason Molenda StackFrameSP frame_sp; 11584fc6cb9cSJim Ingham Mutex::Locker api_locker; 11594fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11604fc6cb9cSJim Ingham 11611ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1162af67cecdSGreg Clayton { 11637fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11647fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11657fdf9ef1SGreg Clayton { 11661ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1167b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1168af67cecdSGreg Clayton } 1169c9858e4dSGreg Clayton else 1170c9858e4dSGreg Clayton { 1171c9858e4dSGreg Clayton if (log) 1172324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", 1173324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1174c9858e4dSGreg Clayton } 11757fdf9ef1SGreg Clayton } 1176ceb6b139SCaroline Tice 1177ceb6b139SCaroline Tice if (log) 1178ceb6b139SCaroline Tice { 1179481cef25SGreg Clayton SBStream frame_desc_strm; 1180481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 11814838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1182324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1183324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1184324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1185ceb6b139SCaroline Tice } 1186ceb6b139SCaroline Tice 118730fdc8d8SChris Lattner return sb_frame; 118830fdc8d8SChris Lattner } 118930fdc8d8SChris Lattner 1190f028a1fbSGreg Clayton lldb::SBFrame 1191f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1192f028a1fbSGreg Clayton { 11935160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1194f028a1fbSGreg Clayton 1195f028a1fbSGreg Clayton SBFrame sb_frame; 1196b57e4a1bSJason Molenda StackFrameSP frame_sp; 11974fc6cb9cSJim Ingham Mutex::Locker api_locker; 11984fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11994fc6cb9cSJim Ingham 12001ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1201af67cecdSGreg Clayton { 12027fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12037fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12047fdf9ef1SGreg Clayton { 12051ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1206b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1207af67cecdSGreg Clayton } 1208c9858e4dSGreg Clayton else 1209c9858e4dSGreg Clayton { 1210c9858e4dSGreg Clayton if (log) 1211324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", 1212324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1213c9858e4dSGreg Clayton } 12147fdf9ef1SGreg Clayton } 1215f028a1fbSGreg Clayton 1216f028a1fbSGreg Clayton if (log) 1217f028a1fbSGreg Clayton { 1218481cef25SGreg Clayton SBStream frame_desc_strm; 1219481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1220f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1221324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1222324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1223324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1224f028a1fbSGreg Clayton } 1225f028a1fbSGreg Clayton 1226f028a1fbSGreg Clayton return sb_frame; 1227f028a1fbSGreg Clayton } 1228f028a1fbSGreg Clayton 1229f028a1fbSGreg Clayton lldb::SBFrame 1230f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1231f028a1fbSGreg Clayton { 12325160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1233f028a1fbSGreg Clayton 1234f028a1fbSGreg Clayton SBFrame sb_frame; 1235b57e4a1bSJason Molenda StackFrameSP frame_sp; 12364fc6cb9cSJim Ingham Mutex::Locker api_locker; 12374fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 12384fc6cb9cSJim Ingham 12391ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1240f028a1fbSGreg Clayton { 12417fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12427fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12437fdf9ef1SGreg Clayton { 12441ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 12451ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1246f028a1fbSGreg Clayton if (frame_sp) 1247f028a1fbSGreg Clayton { 12481ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1249b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1250f028a1fbSGreg Clayton } 1251f028a1fbSGreg Clayton } 1252c9858e4dSGreg Clayton else 1253c9858e4dSGreg Clayton { 1254c9858e4dSGreg Clayton if (log) 1255324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", 1256324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1257c9858e4dSGreg Clayton } 12587fdf9ef1SGreg Clayton } 1259f028a1fbSGreg Clayton 1260f028a1fbSGreg Clayton if (log) 1261f028a1fbSGreg Clayton { 1262481cef25SGreg Clayton SBStream frame_desc_strm; 1263481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1264f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1265324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1266324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1267324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1268f028a1fbSGreg Clayton } 1269f028a1fbSGreg Clayton return sb_frame; 1270f028a1fbSGreg Clayton } 1271f028a1fbSGreg Clayton 12724f465cffSJim Ingham bool 12734f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event) 12744f465cffSJim Ingham { 12754f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 12764f465cffSJim Ingham } 12774f465cffSJim Ingham 12784f465cffSJim Ingham SBFrame 12794f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event) 12804f465cffSJim Ingham { 12814f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 12824f465cffSJim Ingham 12834f465cffSJim Ingham } 12844f465cffSJim Ingham 12854f465cffSJim Ingham SBThread 12864f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event) 12874f465cffSJim Ingham { 12884f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 12894f465cffSJim Ingham } 1290f028a1fbSGreg Clayton 129130fdc8d8SChris Lattner bool 129230fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 129330fdc8d8SChris Lattner { 12947fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 129530fdc8d8SChris Lattner } 129630fdc8d8SChris Lattner 129730fdc8d8SChris Lattner bool 129830fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 129930fdc8d8SChris Lattner { 13007fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 130130fdc8d8SChris Lattner } 1302dde9cff3SCaroline Tice 1303dde9cff3SCaroline Tice bool 13044f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const 13054f465cffSJim Ingham { 13064f465cffSJim Ingham Stream &strm = status.ref(); 13074f465cffSJim Ingham 13084f465cffSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get()); 13094f465cffSJim Ingham if (exe_ctx.HasThreadScope()) 13104f465cffSJim Ingham { 13114f465cffSJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 13124f465cffSJim Ingham } 13134f465cffSJim Ingham else 13144f465cffSJim Ingham strm.PutCString ("No status"); 13154f465cffSJim Ingham 13164f465cffSJim Ingham return true; 13174f465cffSJim Ingham } 13184f465cffSJim Ingham 13194f465cffSJim Ingham bool 1320ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1321ceb6b139SCaroline Tice { 1322da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1323da7bc7d0SGreg Clayton 13247fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 13251ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1326ceb6b139SCaroline Tice { 1327d01b2953SDaniel Malea strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1328ceb6b139SCaroline Tice } 1329ceb6b139SCaroline Tice else 1330da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1331ceb6b139SCaroline Tice 1332ceb6b139SCaroline Tice return true; 1333ceb6b139SCaroline Tice } 13345dd4916fSJason Molenda 13355dd4916fSJason Molenda SBThread 1336008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type) 13375dd4916fSJason Molenda { 13385dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 13395dd4916fSJason Molenda Mutex::Locker api_locker; 13405dd4916fSJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 13415dd4916fSJason Molenda SBThread sb_origin_thread; 13425dd4916fSJason Molenda 13435dd4916fSJason Molenda if (exe_ctx.HasThreadScope()) 13445dd4916fSJason Molenda { 13455dd4916fSJason Molenda Process::StopLocker stop_locker; 13465dd4916fSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 13475dd4916fSJason Molenda { 13487a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 13495dd4916fSJason Molenda if (real_thread) 13505dd4916fSJason Molenda { 13515dd4916fSJason Molenda ConstString type_const (type); 13527a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 13537a2f7904SJason Molenda if (process) 13547a2f7904SJason Molenda { 13557a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 13565dd4916fSJason Molenda if (runtime) 13575dd4916fSJason Molenda { 1358008c45f1SJason Molenda ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1359a6e9130dSJason Molenda if (new_thread_sp) 1360a6e9130dSJason Molenda { 13617a2f7904SJason Molenda // Save this in the Process' ExtendedThreadList so a strong pointer retains the 13627a2f7904SJason Molenda // object. 13637a2f7904SJason Molenda process->GetExtendedThreadList().AddThread (new_thread_sp); 13647a2f7904SJason Molenda sb_origin_thread.SetThread (new_thread_sp); 1365a6e9130dSJason Molenda if (log) 1366a6e9130dSJason Molenda { 1367a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1368a6e9130dSJason Molenda if (queue_name == NULL) 1369a6e9130dSJason Molenda queue_name = ""; 1370324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", 1371324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1372324a1036SSaleem Abdulrasool static_cast<void*>(new_thread_sp.get()), 1373324a1036SSaleem Abdulrasool new_thread_sp->GetQueueID(), 1374324a1036SSaleem Abdulrasool queue_name); 1375a6e9130dSJason Molenda } 1376a6e9130dSJason Molenda } 13777a2f7904SJason Molenda } 13785dd4916fSJason Molenda } 13795dd4916fSJason Molenda } 13805dd4916fSJason Molenda } 13815dd4916fSJason Molenda else 13825dd4916fSJason Molenda { 13835dd4916fSJason Molenda if (log) 1384324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", 1385324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 13865dd4916fSJason Molenda } 13875dd4916fSJason Molenda } 13885dd4916fSJason Molenda 1389ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1390324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", 1391324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 13925dd4916fSJason Molenda return sb_origin_thread; 13935dd4916fSJason Molenda } 13948ee9cb58SJason Molenda 13958ee9cb58SJason Molenda uint32_t 13968ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID () 13978ee9cb58SJason Molenda { 13988ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13998ee9cb58SJason Molenda if (thread_sp) 14008ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14018ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14028ee9cb58SJason Molenda } 1403