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" 26b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 2730fdc8d8SChris Lattner #include "lldb/Symbol/SymbolContext.h" 2830fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h" 29f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 3030fdc8d8SChris Lattner #include "lldb/Target/Target.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInRange.h" 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner 384c5de699SEli Friedman #include "lldb/API/SBAddress.h" 394c5de699SEli Friedman #include "lldb/API/SBDebugger.h" 404f465cffSJim Ingham #include "lldb/API/SBEvent.h" 4173ca05a2SJim Ingham #include "lldb/API/SBFrame.h" 424c5de699SEli Friedman #include "lldb/API/SBProcess.h" 4373ca05a2SJim Ingham #include "lldb/API/SBValue.h" 4430fdc8d8SChris Lattner 4530fdc8d8SChris Lattner using namespace lldb; 4630fdc8d8SChris Lattner using namespace lldb_private; 4730fdc8d8SChris Lattner 484f465cffSJim Ingham const char * 494f465cffSJim Ingham SBThread::GetBroadcasterClassName () 504f465cffSJim Ingham { 514f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 524f465cffSJim Ingham } 534f465cffSJim Ingham 54cfd1acedSGreg Clayton //---------------------------------------------------------------------- 55cfd1acedSGreg Clayton // Constructors 56cfd1acedSGreg Clayton //---------------------------------------------------------------------- 5730fdc8d8SChris Lattner SBThread::SBThread () : 587fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef()) 5930fdc8d8SChris Lattner { 6030fdc8d8SChris Lattner } 6130fdc8d8SChris Lattner 6230fdc8d8SChris Lattner SBThread::SBThread (const ThreadSP& lldb_object_sp) : 637fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(lldb_object_sp)) 6430fdc8d8SChris Lattner { 6530fdc8d8SChris Lattner } 6630fdc8d8SChris Lattner 6792ef5735SGreg Clayton SBThread::SBThread (const SBThread &rhs) : 687fdf9ef1SGreg Clayton m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp)) 6930fdc8d8SChris Lattner { 707fdf9ef1SGreg Clayton 7130fdc8d8SChris Lattner } 7230fdc8d8SChris Lattner 7330fdc8d8SChris Lattner //---------------------------------------------------------------------- 74cfd1acedSGreg Clayton // Assignment operator 75cfd1acedSGreg Clayton //---------------------------------------------------------------------- 76cfd1acedSGreg Clayton 77cfd1acedSGreg Clayton const lldb::SBThread & 78cfd1acedSGreg Clayton SBThread::operator = (const SBThread &rhs) 79cfd1acedSGreg Clayton { 80cfd1acedSGreg Clayton if (this != &rhs) 817fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 82cfd1acedSGreg Clayton return *this; 83cfd1acedSGreg Clayton } 84cfd1acedSGreg Clayton 85cfd1acedSGreg Clayton //---------------------------------------------------------------------- 8630fdc8d8SChris Lattner // Destructor 8730fdc8d8SChris Lattner //---------------------------------------------------------------------- 8830fdc8d8SChris Lattner SBThread::~SBThread() 8930fdc8d8SChris Lattner { 9030fdc8d8SChris Lattner } 9130fdc8d8SChris Lattner 92b9ffa98cSJason Molenda lldb::SBQueue 93b9ffa98cSJason Molenda SBThread::GetQueue () const 94b9ffa98cSJason Molenda { 95b9ffa98cSJason Molenda SBQueue sb_queue; 96b9ffa98cSJason Molenda QueueSP queue_sp; 97b9ffa98cSJason Molenda Mutex::Locker api_locker; 98b9ffa98cSJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 99b9ffa98cSJason Molenda 100b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 101b9ffa98cSJason Molenda if (exe_ctx.HasThreadScope()) 102b9ffa98cSJason Molenda { 103b9ffa98cSJason Molenda Process::StopLocker stop_locker; 104b9ffa98cSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 105b9ffa98cSJason Molenda { 106b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 107b9ffa98cSJason Molenda if (queue_sp) 108b9ffa98cSJason Molenda { 109b9ffa98cSJason Molenda sb_queue.SetQueue (queue_sp); 110b9ffa98cSJason Molenda } 111b9ffa98cSJason Molenda } 112b9ffa98cSJason Molenda else 113b9ffa98cSJason Molenda { 114b9ffa98cSJason Molenda if (log) 115b9ffa98cSJason Molenda log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running", 116b9ffa98cSJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr())); 117b9ffa98cSJason Molenda } 118b9ffa98cSJason Molenda } 119b9ffa98cSJason Molenda 120b9ffa98cSJason Molenda if (log) 121b9ffa98cSJason Molenda log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)", 122b9ffa98cSJason Molenda static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get())); 123b9ffa98cSJason Molenda 124b9ffa98cSJason Molenda return sb_queue; 125b9ffa98cSJason Molenda } 126b9ffa98cSJason Molenda 127b9ffa98cSJason Molenda 12830fdc8d8SChris Lattner bool 12930fdc8d8SChris Lattner SBThread::IsValid() const 13030fdc8d8SChris Lattner { 1317fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 13230fdc8d8SChris Lattner } 13330fdc8d8SChris Lattner 13448e42549SGreg Clayton void 13548e42549SGreg Clayton SBThread::Clear () 13648e42549SGreg Clayton { 1377fdf9ef1SGreg Clayton m_opaque_sp->Clear(); 13848e42549SGreg Clayton } 13948e42549SGreg Clayton 14048e42549SGreg Clayton 14130fdc8d8SChris Lattner StopReason 14230fdc8d8SChris Lattner SBThread::GetStopReason() 14330fdc8d8SChris Lattner { 1445160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 145ceb6b139SCaroline Tice 146ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 1474fc6cb9cSJim Ingham Mutex::Locker api_locker; 1484fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1494fc6cb9cSJim Ingham 1501ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 15130fdc8d8SChris Lattner { 1527fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1537fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1547fdf9ef1SGreg Clayton { 15597d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 15630fdc8d8SChris Lattner } 157c9858e4dSGreg Clayton else 158c9858e4dSGreg Clayton { 159c9858e4dSGreg Clayton if (log) 160324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", 161324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 162c9858e4dSGreg Clayton } 1637fdf9ef1SGreg Clayton } 164ceb6b139SCaroline Tice 165ceb6b139SCaroline Tice if (log) 166324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReason () => %s", 167324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 168750cd175SCaroline Tice Thread::StopReasonAsCString (reason)); 169ceb6b139SCaroline Tice 170ceb6b139SCaroline Tice return reason; 17130fdc8d8SChris Lattner } 17230fdc8d8SChris Lattner 17330fdc8d8SChris Lattner size_t 1744e78f606SGreg Clayton SBThread::GetStopReasonDataCount () 1754e78f606SGreg Clayton { 1764fc6cb9cSJim Ingham Mutex::Locker api_locker; 1774fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1784fc6cb9cSJim Ingham 1791ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1804e78f606SGreg Clayton { 1817fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1827fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1837fdf9ef1SGreg Clayton { 1841ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 1854e78f606SGreg Clayton if (stop_info_sp) 1864e78f606SGreg Clayton { 1874e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 1884e78f606SGreg Clayton switch (reason) 1894e78f606SGreg Clayton { 1904e78f606SGreg Clayton case eStopReasonInvalid: 1914e78f606SGreg Clayton case eStopReasonNone: 1924e78f606SGreg Clayton case eStopReasonTrace: 19390ba8115SGreg Clayton case eStopReasonExec: 1944e78f606SGreg Clayton case eStopReasonPlanComplete: 195f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 1964e78f606SGreg Clayton // There is no data for these stop reasons. 1974e78f606SGreg Clayton return 0; 1984e78f606SGreg Clayton 1994e78f606SGreg Clayton case eStopReasonBreakpoint: 2004e78f606SGreg Clayton { 2014e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2021ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2034e78f606SGreg Clayton if (bp_site_sp) 2044e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners () * 2; 2054e78f606SGreg Clayton else 2064e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 2074e78f606SGreg Clayton } 2084e78f606SGreg Clayton break; 2094e78f606SGreg Clayton 2104e78f606SGreg Clayton case eStopReasonWatchpoint: 211290fa41bSJohnny Chen return 1; 2124e78f606SGreg Clayton 2134e78f606SGreg Clayton case eStopReasonSignal: 2144e78f606SGreg Clayton return 1; 2154e78f606SGreg Clayton 2164e78f606SGreg Clayton case eStopReasonException: 2174e78f606SGreg Clayton return 1; 2184e78f606SGreg Clayton } 2194e78f606SGreg Clayton } 2204e78f606SGreg Clayton } 221c9858e4dSGreg Clayton else 222c9858e4dSGreg Clayton { 2235160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 224c9858e4dSGreg Clayton if (log) 225324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", 226324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 227c9858e4dSGreg Clayton } 2287fdf9ef1SGreg Clayton } 2294e78f606SGreg Clayton return 0; 2304e78f606SGreg Clayton } 2314e78f606SGreg Clayton 2324e78f606SGreg Clayton uint64_t 2334e78f606SGreg Clayton SBThread::GetStopReasonDataAtIndex (uint32_t idx) 2344e78f606SGreg Clayton { 2354fc6cb9cSJim Ingham Mutex::Locker api_locker; 2364fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 2374fc6cb9cSJim Ingham 2381ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 2394e78f606SGreg Clayton { 2407fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 2417fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 2427fdf9ef1SGreg Clayton { 2431ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2441ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo (); 2454e78f606SGreg Clayton if (stop_info_sp) 2464e78f606SGreg Clayton { 2474e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 2484e78f606SGreg Clayton switch (reason) 2494e78f606SGreg Clayton { 2504e78f606SGreg Clayton case eStopReasonInvalid: 2514e78f606SGreg Clayton case eStopReasonNone: 2524e78f606SGreg Clayton case eStopReasonTrace: 25390ba8115SGreg Clayton case eStopReasonExec: 2544e78f606SGreg Clayton case eStopReasonPlanComplete: 255f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 2564e78f606SGreg Clayton // There is no data for these stop reasons. 2574e78f606SGreg Clayton return 0; 2584e78f606SGreg Clayton 2594e78f606SGreg Clayton case eStopReasonBreakpoint: 2604e78f606SGreg Clayton { 2614e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 2621ac04c30SGreg Clayton lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id)); 2634e78f606SGreg Clayton if (bp_site_sp) 2644e78f606SGreg Clayton { 2654e78f606SGreg Clayton uint32_t bp_index = idx / 2; 2664e78f606SGreg Clayton BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index)); 2674e78f606SGreg Clayton if (bp_loc_sp) 2684e78f606SGreg Clayton { 2698334e14eSGreg Clayton if (idx & 1) 2704e78f606SGreg Clayton { 2714e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2724e78f606SGreg Clayton return bp_loc_sp->GetID(); 2734e78f606SGreg Clayton } 2744e78f606SGreg Clayton else 2754e78f606SGreg Clayton { 2764e78f606SGreg Clayton // Even idx, return the breakpoint ID 2774e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2784e78f606SGreg Clayton } 2794e78f606SGreg Clayton } 2804e78f606SGreg Clayton } 2814e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 2824e78f606SGreg Clayton } 2834e78f606SGreg Clayton break; 2844e78f606SGreg Clayton 2854e78f606SGreg Clayton case eStopReasonWatchpoint: 286290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2874e78f606SGreg Clayton 2884e78f606SGreg Clayton case eStopReasonSignal: 2894e78f606SGreg Clayton return stop_info_sp->GetValue(); 2904e78f606SGreg Clayton 2914e78f606SGreg Clayton case eStopReasonException: 2924e78f606SGreg Clayton return stop_info_sp->GetValue(); 2934e78f606SGreg Clayton } 2944e78f606SGreg Clayton } 2954e78f606SGreg Clayton } 296c9858e4dSGreg Clayton else 297c9858e4dSGreg Clayton { 2985160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 299c9858e4dSGreg Clayton if (log) 300324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", 301324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 302c9858e4dSGreg Clayton } 3037fdf9ef1SGreg Clayton } 3044e78f606SGreg Clayton return 0; 3054e78f606SGreg Clayton } 3064e78f606SGreg Clayton 3074e78f606SGreg Clayton size_t 30830fdc8d8SChris Lattner SBThread::GetStopDescription (char *dst, size_t dst_len) 30930fdc8d8SChris Lattner { 3105160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 311ceb6b139SCaroline Tice 3124fc6cb9cSJim Ingham Mutex::Locker api_locker; 3134fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 3144fc6cb9cSJim Ingham 3151ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 31630fdc8d8SChris Lattner { 3177fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 3187fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 3197fdf9ef1SGreg Clayton { 3207fdf9ef1SGreg Clayton 3211ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 322b15bfc75SJim Ingham if (stop_info_sp) 32330fdc8d8SChris Lattner { 324b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 32530fdc8d8SChris Lattner if (stop_desc) 32630fdc8d8SChris Lattner { 327ceb6b139SCaroline Tice if (log) 3284838131bSGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 329324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 330324a1036SSaleem Abdulrasool stop_desc); 33130fdc8d8SChris Lattner if (dst) 33230fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc); 33330fdc8d8SChris Lattner else 33430fdc8d8SChris Lattner { 33530fdc8d8SChris Lattner // NULL dst passed in, return the length needed to contain the description 33630fdc8d8SChris Lattner return ::strlen (stop_desc) + 1; // Include the NULL byte for size 33730fdc8d8SChris Lattner } 33830fdc8d8SChris Lattner } 33930fdc8d8SChris Lattner else 34030fdc8d8SChris Lattner { 34130fdc8d8SChris Lattner size_t stop_desc_len = 0; 342b15bfc75SJim Ingham switch (stop_info_sp->GetStopReason()) 34330fdc8d8SChris Lattner { 34430fdc8d8SChris Lattner case eStopReasonTrace: 34530fdc8d8SChris Lattner case eStopReasonPlanComplete: 34630fdc8d8SChris Lattner { 34730fdc8d8SChris Lattner static char trace_desc[] = "step"; 34830fdc8d8SChris Lattner stop_desc = trace_desc; 34930fdc8d8SChris Lattner stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size 35030fdc8d8SChris Lattner } 35130fdc8d8SChris Lattner break; 35230fdc8d8SChris Lattner 35330fdc8d8SChris Lattner case eStopReasonBreakpoint: 35430fdc8d8SChris Lattner { 35530fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 35630fdc8d8SChris Lattner stop_desc = bp_desc; 35730fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 35830fdc8d8SChris Lattner } 35930fdc8d8SChris Lattner break; 36030fdc8d8SChris Lattner 36130fdc8d8SChris Lattner case eStopReasonWatchpoint: 36230fdc8d8SChris Lattner { 36330fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 36430fdc8d8SChris Lattner stop_desc = wp_desc; 36530fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 36630fdc8d8SChris Lattner } 36730fdc8d8SChris Lattner break; 36830fdc8d8SChris Lattner 36930fdc8d8SChris Lattner case eStopReasonSignal: 37030fdc8d8SChris Lattner { 3711ac04c30SGreg Clayton stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue()); 37230fdc8d8SChris Lattner if (stop_desc == NULL || stop_desc[0] == '\0') 37330fdc8d8SChris Lattner { 37430fdc8d8SChris Lattner static char signal_desc[] = "signal"; 37530fdc8d8SChris Lattner stop_desc = signal_desc; 37630fdc8d8SChris Lattner stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size 37730fdc8d8SChris Lattner } 37830fdc8d8SChris Lattner } 37930fdc8d8SChris Lattner break; 38030fdc8d8SChris Lattner 38130fdc8d8SChris Lattner case eStopReasonException: 38230fdc8d8SChris Lattner { 38330fdc8d8SChris Lattner char exc_desc[] = "exception"; 38430fdc8d8SChris Lattner stop_desc = exc_desc; 38530fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 38630fdc8d8SChris Lattner } 38730fdc8d8SChris Lattner break; 388c982c768SGreg Clayton 38990ba8115SGreg Clayton case eStopReasonExec: 39090ba8115SGreg Clayton { 39190ba8115SGreg Clayton char exc_desc[] = "exec"; 39290ba8115SGreg Clayton stop_desc = exc_desc; 39390ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 39490ba8115SGreg Clayton } 39590ba8115SGreg Clayton break; 39690ba8115SGreg Clayton 397f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 398f85defaeSAndrew Kaylor { 399f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 400f85defaeSAndrew Kaylor stop_desc = limbo_desc; 401f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 402f85defaeSAndrew Kaylor } 403f85defaeSAndrew Kaylor break; 404c982c768SGreg Clayton default: 405c982c768SGreg Clayton break; 40630fdc8d8SChris Lattner } 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner if (stop_desc && stop_desc[0]) 40930fdc8d8SChris Lattner { 410ceb6b139SCaroline Tice if (log) 41193aa84e8SGreg Clayton log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 412324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 413324a1036SSaleem Abdulrasool stop_desc); 414ceb6b139SCaroline Tice 41530fdc8d8SChris Lattner if (dst) 41630fdc8d8SChris Lattner return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner if (stop_desc_len == 0) 41930fdc8d8SChris Lattner stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte 42030fdc8d8SChris Lattner 42130fdc8d8SChris Lattner return stop_desc_len; 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner } 42430fdc8d8SChris Lattner } 42530fdc8d8SChris Lattner } 426c9858e4dSGreg Clayton else 427c9858e4dSGreg Clayton { 4285160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 429c9858e4dSGreg Clayton if (log) 430324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", 431324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 432c9858e4dSGreg Clayton } 4337fdf9ef1SGreg Clayton } 43430fdc8d8SChris Lattner if (dst) 43530fdc8d8SChris Lattner *dst = 0; 43630fdc8d8SChris Lattner return 0; 43730fdc8d8SChris Lattner } 43830fdc8d8SChris Lattner 43973ca05a2SJim Ingham SBValue 44073ca05a2SJim Ingham SBThread::GetStopReturnValue () 44173ca05a2SJim Ingham { 4425160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 44373ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 4444fc6cb9cSJim Ingham Mutex::Locker api_locker; 4454fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 4464fc6cb9cSJim Ingham 4471ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 44873ca05a2SJim Ingham { 4497fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 4507fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 4517fdf9ef1SGreg Clayton { 4521ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); 45373ca05a2SJim Ingham if (stop_info_sp) 45473ca05a2SJim Ingham { 45573ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp); 45673ca05a2SJim Ingham } 45773ca05a2SJim Ingham } 458c9858e4dSGreg Clayton else 459c9858e4dSGreg Clayton { 460c9858e4dSGreg Clayton if (log) 461324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", 462324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 463c9858e4dSGreg Clayton } 4647fdf9ef1SGreg Clayton } 46573ca05a2SJim Ingham 46673ca05a2SJim Ingham if (log) 467324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", 468324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 46973ca05a2SJim Ingham return_valobj_sp.get() 47073ca05a2SJim Ingham ? return_valobj_sp->GetValueAsCString() 47173ca05a2SJim Ingham : "<no return value>"); 47273ca05a2SJim Ingham 47373ca05a2SJim Ingham return SBValue (return_valobj_sp); 47473ca05a2SJim Ingham } 47573ca05a2SJim Ingham 47630fdc8d8SChris Lattner void 47730fdc8d8SChris Lattner SBThread::SetThread (const ThreadSP& lldb_object_sp) 47830fdc8d8SChris Lattner { 4797fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP (lldb_object_sp); 48030fdc8d8SChris Lattner } 48130fdc8d8SChris Lattner 48230fdc8d8SChris Lattner lldb::tid_t 48330fdc8d8SChris Lattner SBThread::GetThreadID () const 48430fdc8d8SChris Lattner { 4857fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 48617a6ad05SGreg Clayton if (thread_sp) 4871ac04c30SGreg Clayton return thread_sp->GetID(); 4881ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 48930fdc8d8SChris Lattner } 49030fdc8d8SChris Lattner 49130fdc8d8SChris Lattner uint32_t 49230fdc8d8SChris Lattner SBThread::GetIndexID () const 49330fdc8d8SChris Lattner { 4947fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 49517a6ad05SGreg Clayton if (thread_sp) 49617a6ad05SGreg Clayton return thread_sp->GetIndexID(); 49730fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 49830fdc8d8SChris Lattner } 4991ac04c30SGreg Clayton 50030fdc8d8SChris Lattner const char * 50130fdc8d8SChris Lattner SBThread::GetName () const 50230fdc8d8SChris Lattner { 5035160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5044838131bSGreg Clayton const char *name = NULL; 5054fc6cb9cSJim Ingham Mutex::Locker api_locker; 5064fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5074fc6cb9cSJim Ingham 5081ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 509af67cecdSGreg Clayton { 5107fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 5117fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5127fdf9ef1SGreg Clayton { 5131ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 514af67cecdSGreg Clayton } 515c9858e4dSGreg Clayton else 516c9858e4dSGreg Clayton { 517c9858e4dSGreg Clayton if (log) 518324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName() => error: process is running", 519324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 520c9858e4dSGreg Clayton } 5217fdf9ef1SGreg Clayton } 522ceb6b139SCaroline Tice 523ceb6b139SCaroline Tice if (log) 524324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetName () => %s", 525324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 526324a1036SSaleem Abdulrasool name ? name : "NULL"); 527ceb6b139SCaroline Tice 5284838131bSGreg Clayton return name; 52930fdc8d8SChris Lattner } 53030fdc8d8SChris Lattner 53130fdc8d8SChris Lattner const char * 53230fdc8d8SChris Lattner SBThread::GetQueueName () const 53330fdc8d8SChris Lattner { 5344838131bSGreg Clayton const char *name = NULL; 5354fc6cb9cSJim Ingham Mutex::Locker api_locker; 5364fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5374fc6cb9cSJim Ingham 5385160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5391ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 540af67cecdSGreg Clayton { 5417fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 5427fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5437fdf9ef1SGreg Clayton { 5441ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 545af67cecdSGreg Clayton } 546c9858e4dSGreg Clayton else 547c9858e4dSGreg Clayton { 548c9858e4dSGreg Clayton if (log) 549324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", 550324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 551c9858e4dSGreg Clayton } 5527fdf9ef1SGreg Clayton } 553ceb6b139SCaroline Tice 554ceb6b139SCaroline Tice if (log) 555324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueName () => %s", 556324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 557324a1036SSaleem Abdulrasool name ? name : "NULL"); 558ceb6b139SCaroline Tice 5594838131bSGreg Clayton return name; 56030fdc8d8SChris Lattner } 56130fdc8d8SChris Lattner 5624fdb5863SJason Molenda lldb::queue_id_t 5634fdb5863SJason Molenda SBThread::GetQueueID () const 5644fdb5863SJason Molenda { 5654fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 5664fdb5863SJason Molenda Mutex::Locker api_locker; 5674fdb5863SJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 5684fdb5863SJason Molenda 5694fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 5704fdb5863SJason Molenda if (exe_ctx.HasThreadScope()) 5714fdb5863SJason Molenda { 5724fdb5863SJason Molenda Process::StopLocker stop_locker; 5734fdb5863SJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 5744fdb5863SJason Molenda { 5754fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 5764fdb5863SJason Molenda } 5774fdb5863SJason Molenda else 5784fdb5863SJason Molenda { 5794fdb5863SJason Molenda if (log) 580324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID() => error: process is running", 581324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 5824fdb5863SJason Molenda } 5834fdb5863SJason Molenda } 5844fdb5863SJason Molenda 5854fdb5863SJason Molenda if (log) 586324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 587324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), id); 5884fdb5863SJason Molenda 5894fdb5863SJason Molenda return id; 5904fdb5863SJason Molenda } 5914fdb5863SJason Molenda 59264e7ead1SJim Ingham SBError 59364e7ead1SJim Ingham SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan) 59464e7ead1SJim Ingham { 59564e7ead1SJim Ingham SBError sb_error; 59664e7ead1SJim Ingham 59764e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 59864e7ead1SJim Ingham if (!process) 59964e7ead1SJim Ingham { 60064e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 60164e7ead1SJim Ingham return sb_error; 60264e7ead1SJim Ingham } 60364e7ead1SJim Ingham 60464e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 60564e7ead1SJim Ingham if (!thread) 60664e7ead1SJim Ingham { 60764e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 60864e7ead1SJim Ingham return sb_error; 60964e7ead1SJim Ingham } 61064e7ead1SJim Ingham 61164e7ead1SJim Ingham // User level plans should be Master Plans so they can be interrupted, other plans executed, and 61264e7ead1SJim Ingham // then a "continue" will resume the plan. 61364e7ead1SJim Ingham if (new_plan != NULL) 61464e7ead1SJim Ingham { 61564e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 61664e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 61764e7ead1SJim Ingham } 61864e7ead1SJim Ingham 61964e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 62064e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID (thread->GetID()); 62164e7ead1SJim Ingham sb_error.ref() = process->Resume(); 62264e7ead1SJim Ingham 62364e7ead1SJim Ingham if (sb_error.Success()) 62464e7ead1SJim Ingham { 62564e7ead1SJim Ingham // If we are doing synchronous mode, then wait for the 62664e7ead1SJim Ingham // process to stop yet again! 62764e7ead1SJim Ingham if (process->GetTarget().GetDebugger().GetAsyncExecution () == false) 62864e7ead1SJim Ingham process->WaitForProcessToStop (NULL); 62964e7ead1SJim Ingham } 63064e7ead1SJim Ingham 63164e7ead1SJim Ingham return sb_error; 63264e7ead1SJim Ingham } 63330fdc8d8SChris Lattner 63430fdc8d8SChris Lattner void 63530fdc8d8SChris Lattner SBThread::StepOver (lldb::RunMode stop_other_threads) 63630fdc8d8SChris Lattner { 6375160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 638ceb6b139SCaroline Tice 6394fc6cb9cSJim Ingham Mutex::Locker api_locker; 6404fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 6414fc6cb9cSJim Ingham 64217a6ad05SGreg Clayton 643ceb6b139SCaroline Tice if (log) 644324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", 645324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 646ceb6b139SCaroline Tice Thread::RunModeAsCString (stop_other_threads)); 647ceb6b139SCaroline Tice 6481ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 64930fdc8d8SChris Lattner { 6501ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6517ba6e991SJim Ingham bool abort_other_plans = false; 652b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 65330fdc8d8SChris Lattner 6544d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 65530fdc8d8SChris Lattner if (frame_sp) 65630fdc8d8SChris Lattner { 65730fdc8d8SChris Lattner if (frame_sp->HasDebugInformation ()) 65830fdc8d8SChris Lattner { 6594b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 66030fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6614d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans, 66230fdc8d8SChris Lattner sc.line_entry.range, 66330fdc8d8SChris Lattner sc, 6644b4b2478SJim Ingham stop_other_threads, 6654b4b2478SJim Ingham avoid_no_debug); 66630fdc8d8SChris Lattner } 66730fdc8d8SChris Lattner else 66830fdc8d8SChris Lattner { 6694d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true, 67030fdc8d8SChris Lattner abort_other_plans, 67130fdc8d8SChris Lattner stop_other_threads); 67230fdc8d8SChris Lattner } 67330fdc8d8SChris Lattner } 67430fdc8d8SChris Lattner 67564e7ead1SJim Ingham // This returns an error, we should use it! 6764d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 67730fdc8d8SChris Lattner } 67830fdc8d8SChris Lattner } 67930fdc8d8SChris Lattner 68030fdc8d8SChris Lattner void 68130fdc8d8SChris Lattner SBThread::StepInto (lldb::RunMode stop_other_threads) 68230fdc8d8SChris Lattner { 683c627682eSJim Ingham StepInto (NULL, stop_other_threads); 684c627682eSJim Ingham } 685c627682eSJim Ingham 686c627682eSJim Ingham void 687c627682eSJim Ingham SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads) 688c627682eSJim Ingham { 6895160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 690ceb6b139SCaroline Tice 6914fc6cb9cSJim Ingham Mutex::Locker api_locker; 6924fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 69317a6ad05SGreg Clayton 69417a6ad05SGreg Clayton if (log) 695c627682eSJim Ingham log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 696324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 697c627682eSJim Ingham target_name? target_name: "<NULL>", 69817a6ad05SGreg Clayton Thread::RunModeAsCString (stop_other_threads)); 699c627682eSJim Ingham 7001ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 70130fdc8d8SChris Lattner { 7027ba6e991SJim Ingham bool abort_other_plans = false; 70330fdc8d8SChris Lattner 7041ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 705b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 7064d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 70730fdc8d8SChris Lattner 70830fdc8d8SChris Lattner if (frame_sp && frame_sp->HasDebugInformation ()) 70930fdc8d8SChris Lattner { 7104b4b2478SJim Ingham const LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate; 7114b4b2478SJim Ingham const LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate; 71230fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 7134d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans, 71430fdc8d8SChris Lattner sc.line_entry.range, 71530fdc8d8SChris Lattner sc, 716c627682eSJim Ingham target_name, 717474966a4SGreg Clayton stop_other_threads, 7184b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 7194b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 72030fdc8d8SChris Lattner } 72130fdc8d8SChris Lattner else 72230fdc8d8SChris Lattner { 7234d56e9c1SJim Ingham new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false, 72430fdc8d8SChris Lattner abort_other_plans, 72530fdc8d8SChris Lattner stop_other_threads); 72630fdc8d8SChris Lattner } 72730fdc8d8SChris Lattner 72864e7ead1SJim Ingham // This returns an error, we should use it! 7294d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 73030fdc8d8SChris Lattner } 73130fdc8d8SChris Lattner } 73230fdc8d8SChris Lattner 73330fdc8d8SChris Lattner void 73430fdc8d8SChris Lattner SBThread::StepOut () 73530fdc8d8SChris Lattner { 7365160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 737ceb6b139SCaroline Tice 7384fc6cb9cSJim Ingham Mutex::Locker api_locker; 7394fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7404fc6cb9cSJim Ingham 741ceb6b139SCaroline Tice 74217a6ad05SGreg Clayton if (log) 743324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOut ()", 744324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 74517a6ad05SGreg Clayton 7461ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 74730fdc8d8SChris Lattner { 7487ba6e991SJim Ingham bool abort_other_plans = false; 74994b09246SJim Ingham bool stop_other_threads = false; 75030fdc8d8SChris Lattner 7511ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7521ac04c30SGreg Clayton 7534b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 7544d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 755481cef25SGreg Clayton NULL, 756481cef25SGreg Clayton false, 757481cef25SGreg Clayton stop_other_threads, 758481cef25SGreg Clayton eVoteYes, 759481cef25SGreg Clayton eVoteNoOpinion, 7604b4b2478SJim Ingham 0, 7614b4b2478SJim Ingham avoid_no_debug)); 762481cef25SGreg Clayton 76364e7ead1SJim Ingham // This returns an error, we should use it! 7644d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 765481cef25SGreg Clayton } 766481cef25SGreg Clayton } 767481cef25SGreg Clayton 768481cef25SGreg Clayton void 769481cef25SGreg Clayton SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) 770481cef25SGreg Clayton { 7715160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 772481cef25SGreg Clayton 7734fc6cb9cSJim Ingham Mutex::Locker api_locker; 7744fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 7754fc6cb9cSJim Ingham 776b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 777481cef25SGreg Clayton if (log) 778481cef25SGreg Clayton { 779481cef25SGreg Clayton SBStream frame_desc_strm; 780481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 781324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 782324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 783324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 784324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 785481cef25SGreg Clayton } 786481cef25SGreg Clayton 7871ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 788481cef25SGreg Clayton { 7897ba6e991SJim Ingham bool abort_other_plans = false; 79094b09246SJim Ingham bool stop_other_threads = false; 7911ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 792481cef25SGreg Clayton 7934d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans, 794481cef25SGreg Clayton NULL, 795481cef25SGreg Clayton false, 796481cef25SGreg Clayton stop_other_threads, 797481cef25SGreg Clayton eVoteYes, 798481cef25SGreg Clayton eVoteNoOpinion, 7994d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 80030fdc8d8SChris Lattner 80164e7ead1SJim Ingham // This returns an error, we should use it! 8024d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 80330fdc8d8SChris Lattner } 80430fdc8d8SChris Lattner } 80530fdc8d8SChris Lattner 80630fdc8d8SChris Lattner void 80730fdc8d8SChris Lattner SBThread::StepInstruction (bool step_over) 80830fdc8d8SChris Lattner { 8095160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 810ceb6b139SCaroline Tice 8114fc6cb9cSJim Ingham Mutex::Locker api_locker; 8124fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8134fc6cb9cSJim Ingham 8141ac04c30SGreg Clayton 815ceb6b139SCaroline Tice 81617a6ad05SGreg Clayton if (log) 817324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", 818324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), step_over); 81917a6ad05SGreg Clayton 8201ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 82130fdc8d8SChris Lattner { 8221ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8234d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true)); 82464e7ead1SJim Ingham 82564e7ead1SJim Ingham // This returns an error, we should use it! 8264d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 82730fdc8d8SChris Lattner } 82830fdc8d8SChris Lattner } 82930fdc8d8SChris Lattner 83030fdc8d8SChris Lattner void 83130fdc8d8SChris Lattner SBThread::RunToAddress (lldb::addr_t addr) 83230fdc8d8SChris Lattner { 8335160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 834ceb6b139SCaroline Tice 8354fc6cb9cSJim Ingham Mutex::Locker api_locker; 8364fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8374fc6cb9cSJim Ingham 838ceb6b139SCaroline Tice 83917a6ad05SGreg Clayton if (log) 840324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 841324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), addr); 84217a6ad05SGreg Clayton 8431ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 84430fdc8d8SChris Lattner { 8457ba6e991SJim Ingham bool abort_other_plans = false; 84630fdc8d8SChris Lattner bool stop_other_threads = true; 84730fdc8d8SChris Lattner 848e72dfb32SGreg Clayton Address target_addr (addr); 84930fdc8d8SChris Lattner 8501ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8511ac04c30SGreg Clayton 8524d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads)); 85364e7ead1SJim Ingham 85464e7ead1SJim Ingham // This returns an error, we should use it! 8554d56e9c1SJim Ingham ResumeNewPlan (exe_ctx, new_plan_sp.get()); 85630fdc8d8SChris Lattner } 85730fdc8d8SChris Lattner } 85830fdc8d8SChris Lattner 859481cef25SGreg Clayton SBError 860481cef25SGreg Clayton SBThread::StepOverUntil (lldb::SBFrame &sb_frame, 861481cef25SGreg Clayton lldb::SBFileSpec &sb_file_spec, 862481cef25SGreg Clayton uint32_t line) 863481cef25SGreg Clayton { 864481cef25SGreg Clayton SBError sb_error; 8655160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 866481cef25SGreg Clayton char path[PATH_MAX]; 867481cef25SGreg Clayton 8684fc6cb9cSJim Ingham Mutex::Locker api_locker; 8694fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 8704fc6cb9cSJim Ingham 871b57e4a1bSJason Molenda StackFrameSP frame_sp (sb_frame.GetFrameSP()); 87217a6ad05SGreg Clayton 873481cef25SGreg Clayton if (log) 874481cef25SGreg Clayton { 875481cef25SGreg Clayton SBStream frame_desc_strm; 876481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 877481cef25SGreg Clayton sb_file_spec->GetPath (path, sizeof(path)); 878481cef25SGreg Clayton log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)", 879324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 880324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 881324a1036SSaleem Abdulrasool frame_desc_strm.GetData(), path, line); 882481cef25SGreg Clayton } 883481cef25SGreg Clayton 8841ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 885481cef25SGreg Clayton { 8861ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 8871ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 888481cef25SGreg Clayton 889481cef25SGreg Clayton if (line == 0) 890481cef25SGreg Clayton { 891481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 892481cef25SGreg Clayton return sb_error; 893481cef25SGreg Clayton } 894481cef25SGreg Clayton 895b9556accSGreg Clayton if (!frame_sp) 896481cef25SGreg Clayton { 8971ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame (); 898481cef25SGreg Clayton if (!frame_sp) 8991ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (0); 900481cef25SGreg Clayton } 901481cef25SGreg Clayton 902481cef25SGreg Clayton SymbolContext frame_sc; 903481cef25SGreg Clayton if (!frame_sp) 904481cef25SGreg Clayton { 905481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 906481cef25SGreg Clayton return sb_error; 907481cef25SGreg Clayton } 908481cef25SGreg Clayton 909481cef25SGreg Clayton // If we have a frame, get its line 910481cef25SGreg Clayton frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit | 911481cef25SGreg Clayton eSymbolContextFunction | 912481cef25SGreg Clayton eSymbolContextLineEntry | 913481cef25SGreg Clayton eSymbolContextSymbol ); 914481cef25SGreg Clayton 915481cef25SGreg Clayton if (frame_sc.comp_unit == NULL) 916481cef25SGreg Clayton { 917481cef25SGreg Clayton sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 918481cef25SGreg Clayton return sb_error; 919481cef25SGreg Clayton } 920481cef25SGreg Clayton 921481cef25SGreg Clayton FileSpec step_file_spec; 922481cef25SGreg Clayton if (sb_file_spec.IsValid()) 923481cef25SGreg Clayton { 924481cef25SGreg Clayton // The file spec passed in was valid, so use it 925481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 926481cef25SGreg Clayton } 927481cef25SGreg Clayton else 928481cef25SGreg Clayton { 929481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 930481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 931481cef25SGreg Clayton else 932481cef25SGreg Clayton { 933481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 934481cef25SGreg Clayton return sb_error; 935481cef25SGreg Clayton } 936481cef25SGreg Clayton } 937481cef25SGreg Clayton 9389b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9399b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 9409b70ddb3SJim Ingham // function, and then if there are no addresses remaining, give an appropriate 9419b70ddb3SJim Ingham // error message. 9429b70ddb3SJim Ingham 9439b70ddb3SJim Ingham bool all_in_function = true; 9449b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9459b70ddb3SJim Ingham 946481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9477ba6e991SJim Ingham const bool abort_other_plans = false; 948c02e3344SJim Ingham const bool stop_other_threads = false; 949481cef25SGreg Clayton const bool check_inlines = true; 950481cef25SGreg Clayton const bool exact = false; 951481cef25SGreg Clayton 952481cef25SGreg Clayton SymbolContextList sc_list; 9539b70ddb3SJim Ingham const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec, 9549b70ddb3SJim Ingham line, 9559b70ddb3SJim Ingham check_inlines, 9569b70ddb3SJim Ingham exact, 9579b70ddb3SJim Ingham eSymbolContextLineEntry, 9589b70ddb3SJim Ingham sc_list); 959481cef25SGreg Clayton if (num_matches > 0) 960481cef25SGreg Clayton { 961481cef25SGreg Clayton SymbolContext sc; 962481cef25SGreg Clayton for (uint32_t i=0; i<num_matches; ++i) 963481cef25SGreg Clayton { 964481cef25SGreg Clayton if (sc_list.GetContextAtIndex(i, sc)) 965481cef25SGreg Clayton { 9669b70ddb3SJim Ingham addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 967481cef25SGreg Clayton if (step_addr != LLDB_INVALID_ADDRESS) 968481cef25SGreg Clayton { 9699b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 970481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9719b70ddb3SJim Ingham else 9729b70ddb3SJim Ingham all_in_function = false; 973481cef25SGreg Clayton } 974481cef25SGreg Clayton } 975481cef25SGreg Clayton } 976481cef25SGreg Clayton } 977481cef25SGreg Clayton 978481cef25SGreg Clayton if (step_over_until_addrs.empty()) 979481cef25SGreg Clayton { 9809b70ddb3SJim Ingham if (all_in_function) 9819b70ddb3SJim Ingham { 982481cef25SGreg Clayton step_file_spec.GetPath (path, sizeof(path)); 983fd54b368SJason Molenda sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line); 984481cef25SGreg Clayton } 985481cef25SGreg Clayton else 98686edbf41SGreg Clayton sb_error.SetErrorString ("step until target not in current function"); 9879b70ddb3SJim Ingham } 9889b70ddb3SJim Ingham else 989481cef25SGreg Clayton { 9904d56e9c1SJim Ingham ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans, 991481cef25SGreg Clayton &step_over_until_addrs[0], 992481cef25SGreg Clayton step_over_until_addrs.size(), 993481cef25SGreg Clayton stop_other_threads, 9944d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 995481cef25SGreg Clayton 9964d56e9c1SJim Ingham sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get()); 997481cef25SGreg Clayton } 998481cef25SGreg Clayton } 999481cef25SGreg Clayton else 1000481cef25SGreg Clayton { 1001481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 1002481cef25SGreg Clayton } 1003481cef25SGreg Clayton return sb_error; 1004481cef25SGreg Clayton } 1005481cef25SGreg Clayton 10064413758cSJim Ingham SBError 1007f86248d9SRichard Mitton SBThread::JumpToLine (lldb::SBFileSpec &file_spec, uint32_t line) 1008f86248d9SRichard Mitton { 1009f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1010f86248d9SRichard Mitton SBError sb_error; 1011f86248d9SRichard Mitton 1012f86248d9SRichard Mitton Mutex::Locker api_locker; 1013f86248d9SRichard Mitton ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 1014f86248d9SRichard Mitton 1015f86248d9SRichard Mitton if (log) 1016324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1017324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1018324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1019f86248d9SRichard Mitton 1020f86248d9SRichard Mitton if (!exe_ctx.HasThreadScope()) 1021f86248d9SRichard Mitton { 1022f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1023f86248d9SRichard Mitton return sb_error; 1024f86248d9SRichard Mitton } 1025f86248d9SRichard Mitton 1026f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1027f86248d9SRichard Mitton 1028f86248d9SRichard Mitton Error err = thread->JumpToLine (file_spec.get(), line, true); 1029f86248d9SRichard Mitton sb_error.SetError (err); 1030f86248d9SRichard Mitton return sb_error; 1031f86248d9SRichard Mitton } 1032f86248d9SRichard Mitton 1033f86248d9SRichard Mitton SBError 1034cb640dd8SJim Ingham SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value) 10354413758cSJim Ingham { 10364413758cSJim Ingham SBError sb_error; 10374413758cSJim Ingham 10385160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10394413758cSJim Ingham 10404413758cSJim Ingham Mutex::Locker api_locker; 10414413758cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 10424413758cSJim Ingham 10434413758cSJim Ingham 10444413758cSJim Ingham if (log) 1045324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", 1046324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1047324a1036SSaleem Abdulrasool frame.GetFrameID()); 10484413758cSJim Ingham 10494413758cSJim Ingham if (exe_ctx.HasThreadScope()) 10504413758cSJim Ingham { 10514413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1052cb640dd8SJim Ingham sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 10534413758cSJim Ingham } 10544413758cSJim Ingham 10554413758cSJim Ingham return sb_error; 10564413758cSJim Ingham } 10574413758cSJim Ingham 1058481cef25SGreg Clayton 1059722a0cdcSGreg Clayton bool 1060722a0cdcSGreg Clayton SBThread::Suspend() 1061722a0cdcSGreg Clayton { 10625160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10637fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1064c9858e4dSGreg Clayton bool result = false; 10651ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1066722a0cdcSGreg Clayton { 1067c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1068c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1069c9858e4dSGreg Clayton { 10701ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended); 1071c9858e4dSGreg Clayton result = true; 1072722a0cdcSGreg Clayton } 1073c9858e4dSGreg Clayton else 1074c9858e4dSGreg Clayton { 1075c9858e4dSGreg Clayton if (log) 1076324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => error: process is running", 1077324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1078c9858e4dSGreg Clayton } 1079c9858e4dSGreg Clayton } 1080c9858e4dSGreg Clayton if (log) 1081324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Suspend() => %i", 1082324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1083c9858e4dSGreg Clayton return result; 1084722a0cdcSGreg Clayton } 1085722a0cdcSGreg Clayton 1086722a0cdcSGreg Clayton bool 1087722a0cdcSGreg Clayton SBThread::Resume () 1088722a0cdcSGreg Clayton { 10895160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 10907fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 1091c9858e4dSGreg Clayton bool result = false; 10921ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1093722a0cdcSGreg Clayton { 1094c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1095c9858e4dSGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 1096c9858e4dSGreg Clayton { 10976c9ed91cSJim Ingham const bool override_suspend = true; 10986c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning, override_suspend); 1099c9858e4dSGreg Clayton result = true; 1100722a0cdcSGreg Clayton } 1101c9858e4dSGreg Clayton else 1102c9858e4dSGreg Clayton { 1103c9858e4dSGreg Clayton if (log) 1104324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => error: process is running", 1105324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1106c9858e4dSGreg Clayton } 1107c9858e4dSGreg Clayton } 1108c9858e4dSGreg Clayton if (log) 1109324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::Resume() => %i", 1110324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), result); 1111c9858e4dSGreg Clayton return result; 1112722a0cdcSGreg Clayton } 1113722a0cdcSGreg Clayton 1114722a0cdcSGreg Clayton bool 1115722a0cdcSGreg Clayton SBThread::IsSuspended() 1116722a0cdcSGreg Clayton { 11177fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 11181ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 11191ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended; 1120722a0cdcSGreg Clayton return false; 1121722a0cdcSGreg Clayton } 1122722a0cdcSGreg Clayton 1123a75418dbSAndrew Kaylor bool 1124a75418dbSAndrew Kaylor SBThread::IsStopped() 1125a75418dbSAndrew Kaylor { 1126a75418dbSAndrew Kaylor ExecutionContext exe_ctx (m_opaque_sp.get()); 1127a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1128a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1129a75418dbSAndrew Kaylor return false; 1130a75418dbSAndrew Kaylor } 1131a75418dbSAndrew Kaylor 113230fdc8d8SChris Lattner SBProcess 113330fdc8d8SChris Lattner SBThread::GetProcess () 113430fdc8d8SChris Lattner { 1135b9556accSGreg Clayton SBProcess sb_process; 11367fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 11371ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 113830fdc8d8SChris Lattner { 113930fdc8d8SChris Lattner // Have to go up to the target so we can get a shared pointer to our process... 11401ac04c30SGreg Clayton sb_process.SetSP (exe_ctx.GetProcessSP()); 114130fdc8d8SChris Lattner } 1142ceb6b139SCaroline Tice 11435160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1144ceb6b139SCaroline Tice if (log) 1145ceb6b139SCaroline Tice { 1146481cef25SGreg Clayton SBStream frame_desc_strm; 1147b9556accSGreg Clayton sb_process.GetDescription (frame_desc_strm); 1148324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1149324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1150324a1036SSaleem Abdulrasool static_cast<void*>(sb_process.GetSP().get()), 1151324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1152ceb6b139SCaroline Tice } 1153ceb6b139SCaroline Tice 1154b9556accSGreg Clayton return sb_process; 115530fdc8d8SChris Lattner } 115630fdc8d8SChris Lattner 115730fdc8d8SChris Lattner uint32_t 115830fdc8d8SChris Lattner SBThread::GetNumFrames () 115930fdc8d8SChris Lattner { 11605160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1161ceb6b139SCaroline Tice 1162ceb6b139SCaroline Tice uint32_t num_frames = 0; 11634fc6cb9cSJim Ingham Mutex::Locker api_locker; 11644fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 11654fc6cb9cSJim Ingham 11661ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1167af67cecdSGreg Clayton { 11687fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 11697fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 11707fdf9ef1SGreg Clayton { 11711ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1172af67cecdSGreg Clayton } 1173c9858e4dSGreg Clayton else 1174c9858e4dSGreg Clayton { 1175c9858e4dSGreg Clayton if (log) 1176324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", 1177324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1178c9858e4dSGreg Clayton } 11797fdf9ef1SGreg Clayton } 1180ceb6b139SCaroline Tice 1181ceb6b139SCaroline Tice if (log) 1182324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetNumFrames () => %u", 1183324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), num_frames); 1184ceb6b139SCaroline Tice 1185ceb6b139SCaroline Tice return num_frames; 118630fdc8d8SChris Lattner } 118730fdc8d8SChris Lattner 118830fdc8d8SChris Lattner SBFrame 118930fdc8d8SChris Lattner SBThread::GetFrameAtIndex (uint32_t idx) 119030fdc8d8SChris Lattner { 11915160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1192ceb6b139SCaroline Tice 119330fdc8d8SChris Lattner 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()) 1199af67cecdSGreg Clayton { 12007fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12017fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12027fdf9ef1SGreg Clayton { 12031ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); 1204b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1205af67cecdSGreg Clayton } 1206c9858e4dSGreg Clayton else 1207c9858e4dSGreg Clayton { 1208c9858e4dSGreg Clayton if (log) 1209324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", 1210324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1211c9858e4dSGreg Clayton } 12127fdf9ef1SGreg Clayton } 1213ceb6b139SCaroline Tice 1214ceb6b139SCaroline Tice if (log) 1215ceb6b139SCaroline Tice { 1216481cef25SGreg Clayton SBStream frame_desc_strm; 1217481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 12184838131bSGreg Clayton log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1219324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1220324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1221324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1222ceb6b139SCaroline Tice } 1223ceb6b139SCaroline Tice 122430fdc8d8SChris Lattner return sb_frame; 122530fdc8d8SChris Lattner } 122630fdc8d8SChris Lattner 1227f028a1fbSGreg Clayton lldb::SBFrame 1228f028a1fbSGreg Clayton SBThread::GetSelectedFrame () 1229f028a1fbSGreg Clayton { 12305160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1231f028a1fbSGreg Clayton 1232f028a1fbSGreg Clayton SBFrame sb_frame; 1233b57e4a1bSJason Molenda StackFrameSP frame_sp; 12344fc6cb9cSJim Ingham Mutex::Locker api_locker; 12354fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 12364fc6cb9cSJim Ingham 12371ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1238af67cecdSGreg Clayton { 12397fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12407fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12417fdf9ef1SGreg Clayton { 12421ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); 1243b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1244af67cecdSGreg Clayton } 1245c9858e4dSGreg Clayton else 1246c9858e4dSGreg Clayton { 1247c9858e4dSGreg Clayton if (log) 1248324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", 1249324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1250c9858e4dSGreg Clayton } 12517fdf9ef1SGreg Clayton } 1252f028a1fbSGreg Clayton 1253f028a1fbSGreg Clayton if (log) 1254f028a1fbSGreg Clayton { 1255481cef25SGreg Clayton SBStream frame_desc_strm; 1256481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1257f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1258324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1259324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1260324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1261f028a1fbSGreg Clayton } 1262f028a1fbSGreg Clayton 1263f028a1fbSGreg Clayton return sb_frame; 1264f028a1fbSGreg Clayton } 1265f028a1fbSGreg Clayton 1266f028a1fbSGreg Clayton lldb::SBFrame 1267f028a1fbSGreg Clayton SBThread::SetSelectedFrame (uint32_t idx) 1268f028a1fbSGreg Clayton { 12695160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1270f028a1fbSGreg Clayton 1271f028a1fbSGreg Clayton SBFrame sb_frame; 1272b57e4a1bSJason Molenda StackFrameSP frame_sp; 12734fc6cb9cSJim Ingham Mutex::Locker api_locker; 12744fc6cb9cSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 12754fc6cb9cSJim Ingham 12761ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1277f028a1fbSGreg Clayton { 12787fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 12797fdf9ef1SGreg Clayton if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 12807fdf9ef1SGreg Clayton { 12811ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 12821ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex (idx); 1283f028a1fbSGreg Clayton if (frame_sp) 1284f028a1fbSGreg Clayton { 12851ac04c30SGreg Clayton thread->SetSelectedFrame (frame_sp.get()); 1286b9556accSGreg Clayton sb_frame.SetFrameSP (frame_sp); 1287f028a1fbSGreg Clayton } 1288f028a1fbSGreg Clayton } 1289c9858e4dSGreg Clayton else 1290c9858e4dSGreg Clayton { 1291c9858e4dSGreg Clayton if (log) 1292324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", 1293324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 1294c9858e4dSGreg Clayton } 12957fdf9ef1SGreg Clayton } 1296f028a1fbSGreg Clayton 1297f028a1fbSGreg Clayton if (log) 1298f028a1fbSGreg Clayton { 1299481cef25SGreg Clayton SBStream frame_desc_strm; 1300481cef25SGreg Clayton sb_frame.GetDescription (frame_desc_strm); 1301f028a1fbSGreg Clayton log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1302324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), idx, 1303324a1036SSaleem Abdulrasool static_cast<void*>(frame_sp.get()), 1304324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1305f028a1fbSGreg Clayton } 1306f028a1fbSGreg Clayton return sb_frame; 1307f028a1fbSGreg Clayton } 1308f028a1fbSGreg Clayton 13094f465cffSJim Ingham bool 13104f465cffSJim Ingham SBThread::EventIsThreadEvent (const SBEvent &event) 13114f465cffSJim Ingham { 13124f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 13134f465cffSJim Ingham } 13144f465cffSJim Ingham 13154f465cffSJim Ingham SBFrame 13164f465cffSJim Ingham SBThread::GetStackFrameFromEvent (const SBEvent &event) 13174f465cffSJim Ingham { 13184f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent (event.get()); 13194f465cffSJim Ingham 13204f465cffSJim Ingham } 13214f465cffSJim Ingham 13224f465cffSJim Ingham SBThread 13234f465cffSJim Ingham SBThread::GetThreadFromEvent (const SBEvent &event) 13244f465cffSJim Ingham { 13254f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent (event.get()); 13264f465cffSJim Ingham } 1327f028a1fbSGreg Clayton 132830fdc8d8SChris Lattner bool 132930fdc8d8SChris Lattner SBThread::operator == (const SBThread &rhs) const 133030fdc8d8SChris Lattner { 13317fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get(); 133230fdc8d8SChris Lattner } 133330fdc8d8SChris Lattner 133430fdc8d8SChris Lattner bool 133530fdc8d8SChris Lattner SBThread::operator != (const SBThread &rhs) const 133630fdc8d8SChris Lattner { 13377fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get(); 133830fdc8d8SChris Lattner } 1339dde9cff3SCaroline Tice 1340dde9cff3SCaroline Tice bool 13414f465cffSJim Ingham SBThread::GetStatus (SBStream &status) const 13424f465cffSJim Ingham { 13434f465cffSJim Ingham Stream &strm = status.ref(); 13444f465cffSJim Ingham 13454f465cffSJim Ingham ExecutionContext exe_ctx (m_opaque_sp.get()); 13464f465cffSJim Ingham if (exe_ctx.HasThreadScope()) 13474f465cffSJim Ingham { 13484f465cffSJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 13494f465cffSJim Ingham } 13504f465cffSJim Ingham else 13514f465cffSJim Ingham strm.PutCString ("No status"); 13524f465cffSJim Ingham 13534f465cffSJim Ingham return true; 13544f465cffSJim Ingham } 13554f465cffSJim Ingham 13564f465cffSJim Ingham bool 1357ceb6b139SCaroline Tice SBThread::GetDescription (SBStream &description) const 1358ceb6b139SCaroline Tice { 1359da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1360da7bc7d0SGreg Clayton 13617fdf9ef1SGreg Clayton ExecutionContext exe_ctx (m_opaque_sp.get()); 13621ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 1363ceb6b139SCaroline Tice { 1364d01b2953SDaniel Malea strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID()); 1365ceb6b139SCaroline Tice } 1366ceb6b139SCaroline Tice else 1367da7bc7d0SGreg Clayton strm.PutCString ("No value"); 1368ceb6b139SCaroline Tice 1369ceb6b139SCaroline Tice return true; 1370ceb6b139SCaroline Tice } 13715dd4916fSJason Molenda 13725dd4916fSJason Molenda SBThread 1373008c45f1SJason Molenda SBThread::GetExtendedBacktraceThread (const char *type) 13745dd4916fSJason Molenda { 13755dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 13765dd4916fSJason Molenda Mutex::Locker api_locker; 13775dd4916fSJason Molenda ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); 13785dd4916fSJason Molenda SBThread sb_origin_thread; 13795dd4916fSJason Molenda 13805dd4916fSJason Molenda if (exe_ctx.HasThreadScope()) 13815dd4916fSJason Molenda { 13825dd4916fSJason Molenda Process::StopLocker stop_locker; 13835dd4916fSJason Molenda if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 13845dd4916fSJason Molenda { 13857a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 13865dd4916fSJason Molenda if (real_thread) 13875dd4916fSJason Molenda { 13885dd4916fSJason Molenda ConstString type_const (type); 13897a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 13907a2f7904SJason Molenda if (process) 13917a2f7904SJason Molenda { 13927a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 13935dd4916fSJason Molenda if (runtime) 13945dd4916fSJason Molenda { 1395008c45f1SJason Molenda ThreadSP new_thread_sp (runtime->GetExtendedBacktraceThread (real_thread, type_const)); 1396a6e9130dSJason Molenda if (new_thread_sp) 1397a6e9130dSJason Molenda { 13987a2f7904SJason Molenda // Save this in the Process' ExtendedThreadList so a strong pointer retains the 13997a2f7904SJason Molenda // object. 14007a2f7904SJason Molenda process->GetExtendedThreadList().AddThread (new_thread_sp); 14017a2f7904SJason Molenda sb_origin_thread.SetThread (new_thread_sp); 1402a6e9130dSJason Molenda if (log) 1403a6e9130dSJason Molenda { 1404a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1405a6e9130dSJason Molenda if (queue_name == NULL) 1406a6e9130dSJason Molenda queue_name = ""; 1407324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => new extended Thread created (%p) with queue_id 0x%" PRIx64 " queue name '%s'", 1408324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr()), 1409324a1036SSaleem Abdulrasool static_cast<void*>(new_thread_sp.get()), 1410324a1036SSaleem Abdulrasool new_thread_sp->GetQueueID(), 1411324a1036SSaleem Abdulrasool queue_name); 1412a6e9130dSJason Molenda } 1413a6e9130dSJason Molenda } 14147a2f7904SJason Molenda } 14155dd4916fSJason Molenda } 14165dd4916fSJason Molenda } 14175dd4916fSJason Molenda } 14185dd4916fSJason Molenda else 14195dd4916fSJason Molenda { 14205dd4916fSJason Molenda if (log) 1421324a1036SSaleem Abdulrasool log->Printf ("SBThread(%p)::GetExtendedBacktraceThread() => error: process is running", 1422324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 14235dd4916fSJason Molenda } 14245dd4916fSJason Molenda } 14255dd4916fSJason Molenda 1426ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1427324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a Valid thread", 1428324a1036SSaleem Abdulrasool static_cast<void*>(exe_ctx.GetThreadPtr())); 14295dd4916fSJason Molenda return sb_origin_thread; 14305dd4916fSJason Molenda } 14318ee9cb58SJason Molenda 14328ee9cb58SJason Molenda uint32_t 14338ee9cb58SJason Molenda SBThread::GetExtendedBacktraceOriginatingIndexID () 14348ee9cb58SJason Molenda { 14358ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14368ee9cb58SJason Molenda if (thread_sp) 14378ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14388ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14398ee9cb58SJason Molenda } 1440*b4892cd2SJason Molenda 1441*b4892cd2SJason Molenda bool 1442*b4892cd2SJason Molenda SBThread::SafeToCallFunctions () 1443*b4892cd2SJason Molenda { 1444*b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1445*b4892cd2SJason Molenda if (thread_sp) 1446*b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1447*b4892cd2SJason Molenda return true; 1448*b4892cd2SJason Molenda } 1449