130fdc8d8SChris Lattner //===-- SBThread.cpp --------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 104c5de699SEli Friedman #include "lldb/API/SBThread.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner #include "lldb/API/SBFileSpec.h" 13dde9cff3SCaroline Tice #include "lldb/API/SBStream.h" 14*b9c1b51eSKate Stone #include "lldb/API/SBSymbolContext.h" 154e78f606SGreg Clayton #include "lldb/Breakpoint/BreakpointLocation.h" 166611103cSGreg Clayton #include "lldb/Core/Debugger.h" 17a75418dbSAndrew Kaylor #include "lldb/Core/State.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Stream.h" 1930fdc8d8SChris Lattner #include "lldb/Core/StreamFile.h" 20705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 21a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h" 226611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2393749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h" 24*b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h" 2530fdc8d8SChris Lattner #include "lldb/Target/Process.h" 26b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 27f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 28*b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h" 2930fdc8d8SChris Lattner #include "lldb/Target/Target.h" 30*b9c1b51eSKate Stone #include "lldb/Target/Thread.h" 3130fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 32*b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3530fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 36*b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h" 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" 436a831436SKuba Brecka #include "lldb/API/SBThreadCollection.h" 442bdbfd50SJim Ingham #include "lldb/API/SBThreadPlan.h" 4573ca05a2SJim Ingham #include "lldb/API/SBValue.h" 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner using namespace lldb; 4830fdc8d8SChris Lattner using namespace lldb_private; 4930fdc8d8SChris Lattner 50*b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() { 514f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 524f465cffSJim Ingham } 534f465cffSJim Ingham 54cfd1acedSGreg Clayton //---------------------------------------------------------------------- 55cfd1acedSGreg Clayton // Constructors 56cfd1acedSGreg Clayton //---------------------------------------------------------------------- 57*b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {} 5830fdc8d8SChris Lattner 59*b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp) 60*b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {} 6130fdc8d8SChris Lattner 62*b9c1b51eSKate Stone SBThread::SBThread(const SBThread &rhs) 63*b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {} 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner //---------------------------------------------------------------------- 66cfd1acedSGreg Clayton // Assignment operator 67cfd1acedSGreg Clayton //---------------------------------------------------------------------- 68cfd1acedSGreg Clayton 69*b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { 70cfd1acedSGreg Clayton if (this != &rhs) 717fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 72cfd1acedSGreg Clayton return *this; 73cfd1acedSGreg Clayton } 74cfd1acedSGreg Clayton 75cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7630fdc8d8SChris Lattner // Destructor 7730fdc8d8SChris Lattner //---------------------------------------------------------------------- 78*b9c1b51eSKate Stone SBThread::~SBThread() {} 7930fdc8d8SChris Lattner 80*b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const { 81b9ffa98cSJason Molenda SBQueue sb_queue; 82b9ffa98cSJason Molenda QueueSP queue_sp; 83bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 84bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 85b9ffa98cSJason Molenda 86b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 87*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 88b9ffa98cSJason Molenda Process::StopLocker stop_locker; 89*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 90b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 91*b9c1b51eSKate Stone if (queue_sp) { 92b9ffa98cSJason Molenda sb_queue.SetQueue(queue_sp); 93b9ffa98cSJason Molenda } 94*b9c1b51eSKate Stone } else { 95b9ffa98cSJason Molenda if (log) 96358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue() => error: process is running", 97b9ffa98cSJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 98b9ffa98cSJason Molenda } 99b9ffa98cSJason Molenda } 100b9ffa98cSJason Molenda 101b9ffa98cSJason Molenda if (log) 102358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)", 103*b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), 104*b9c1b51eSKate Stone static_cast<void *>(queue_sp.get())); 105b9ffa98cSJason Molenda 106b9ffa98cSJason Molenda return sb_queue; 107b9ffa98cSJason Molenda } 108b9ffa98cSJason Molenda 109*b9c1b51eSKate Stone bool SBThread::IsValid() const { 110bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 111bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1127fa7dc36SJim Ingham 1137fa7dc36SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 1147fa7dc36SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 115*b9c1b51eSKate Stone if (target && process) { 1167fa7dc36SJim Ingham Process::StopLocker stop_locker; 1177fa7dc36SJim Ingham if (stop_locker.TryLock(&process->GetRunLock())) 1187fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 11930fdc8d8SChris Lattner } 1207fa7dc36SJim Ingham // Without a valid target & process, this thread can't be valid. 1217fa7dc36SJim Ingham return false; 1227fa7dc36SJim Ingham } 12330fdc8d8SChris Lattner 124*b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); } 12548e42549SGreg Clayton 126*b9c1b51eSKate Stone StopReason SBThread::GetStopReason() { 1275160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 128ceb6b139SCaroline Tice 129ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 130bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 131bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1324fc6cb9cSJim Ingham 133*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1347fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 135*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13697d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 137*b9c1b51eSKate Stone } else { 138c9858e4dSGreg Clayton if (log) 139*b9c1b51eSKate Stone log->Printf( 140*b9c1b51eSKate Stone "SBThread(%p)::GetStopReason() => error: process is running", 141324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 142c9858e4dSGreg Clayton } 1437fdf9ef1SGreg Clayton } 144ceb6b139SCaroline Tice 145ceb6b139SCaroline Tice if (log) 146324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReason () => %s", 147324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 148750cd175SCaroline Tice Thread::StopReasonAsCString(reason)); 149ceb6b139SCaroline Tice 150ceb6b139SCaroline Tice return reason; 15130fdc8d8SChris Lattner } 15230fdc8d8SChris Lattner 153*b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() { 154bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 155bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1564fc6cb9cSJim Ingham 157*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1587fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 159*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1601ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 161*b9c1b51eSKate Stone if (stop_info_sp) { 1624e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 163*b9c1b51eSKate Stone switch (reason) { 1644e78f606SGreg Clayton case eStopReasonInvalid: 1654e78f606SGreg Clayton case eStopReasonNone: 1664e78f606SGreg Clayton case eStopReasonTrace: 16790ba8115SGreg Clayton case eStopReasonExec: 1684e78f606SGreg Clayton case eStopReasonPlanComplete: 169f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 170afdf842bSKuba Brecka case eStopReasonInstrumentation: 1714e78f606SGreg Clayton // There is no data for these stop reasons. 1724e78f606SGreg Clayton return 0; 1734e78f606SGreg Clayton 174*b9c1b51eSKate Stone case eStopReasonBreakpoint: { 1754e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 176*b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 177*b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 178*b9c1b51eSKate Stone site_id)); 1794e78f606SGreg Clayton if (bp_site_sp) 1804e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners() * 2; 1814e78f606SGreg Clayton else 1824e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 183*b9c1b51eSKate Stone } break; 1844e78f606SGreg Clayton 1854e78f606SGreg Clayton case eStopReasonWatchpoint: 186290fa41bSJohnny Chen return 1; 1874e78f606SGreg Clayton 1884e78f606SGreg Clayton case eStopReasonSignal: 1894e78f606SGreg Clayton return 1; 1904e78f606SGreg Clayton 1914e78f606SGreg Clayton case eStopReasonException: 1924e78f606SGreg Clayton return 1; 1934e78f606SGreg Clayton } 1944e78f606SGreg Clayton } 195*b9c1b51eSKate Stone } else { 1965160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 197c9858e4dSGreg Clayton if (log) 198*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process " 199*b9c1b51eSKate Stone "is running", 200324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 201c9858e4dSGreg Clayton } 2027fdf9ef1SGreg Clayton } 2034e78f606SGreg Clayton return 0; 2044e78f606SGreg Clayton } 2054e78f606SGreg Clayton 206*b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { 207bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 208bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2094fc6cb9cSJim Ingham 210*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 2117fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 212*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 2131ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2141ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo(); 215*b9c1b51eSKate Stone if (stop_info_sp) { 2164e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 217*b9c1b51eSKate Stone switch (reason) { 2184e78f606SGreg Clayton case eStopReasonInvalid: 2194e78f606SGreg Clayton case eStopReasonNone: 2204e78f606SGreg Clayton case eStopReasonTrace: 22190ba8115SGreg Clayton case eStopReasonExec: 2224e78f606SGreg Clayton case eStopReasonPlanComplete: 223f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 224afdf842bSKuba Brecka case eStopReasonInstrumentation: 2254e78f606SGreg Clayton // There is no data for these stop reasons. 2264e78f606SGreg Clayton return 0; 2274e78f606SGreg Clayton 228*b9c1b51eSKate Stone case eStopReasonBreakpoint: { 2294e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 230*b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 231*b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 232*b9c1b51eSKate Stone site_id)); 233*b9c1b51eSKate Stone if (bp_site_sp) { 2344e78f606SGreg Clayton uint32_t bp_index = idx / 2; 235*b9c1b51eSKate Stone BreakpointLocationSP bp_loc_sp( 236*b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(bp_index)); 237*b9c1b51eSKate Stone if (bp_loc_sp) { 238*b9c1b51eSKate Stone if (idx & 1) { 2394e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2404e78f606SGreg Clayton return bp_loc_sp->GetID(); 241*b9c1b51eSKate Stone } else { 2424e78f606SGreg Clayton // Even idx, return the breakpoint ID 2434e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2444e78f606SGreg Clayton } 2454e78f606SGreg Clayton } 2464e78f606SGreg Clayton } 2474e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 248*b9c1b51eSKate Stone } break; 2494e78f606SGreg Clayton 2504e78f606SGreg Clayton case eStopReasonWatchpoint: 251290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2524e78f606SGreg Clayton 2534e78f606SGreg Clayton case eStopReasonSignal: 2544e78f606SGreg Clayton return stop_info_sp->GetValue(); 2554e78f606SGreg Clayton 2564e78f606SGreg Clayton case eStopReasonException: 2574e78f606SGreg Clayton return stop_info_sp->GetValue(); 2584e78f606SGreg Clayton } 2594e78f606SGreg Clayton } 260*b9c1b51eSKate Stone } else { 2615160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 262c9858e4dSGreg Clayton if (log) 263*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: " 264*b9c1b51eSKate Stone "process is running", 265324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 266c9858e4dSGreg Clayton } 2677fdf9ef1SGreg Clayton } 2684e78f606SGreg Clayton return 0; 2694e78f606SGreg Clayton } 2704e78f606SGreg Clayton 271*b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { 272afdf842bSKuba Brecka Stream &strm = stream.ref(); 273afdf842bSKuba Brecka 274b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 275b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 276b2e7d28eSJim Ingham 277afdf842bSKuba Brecka if (!exe_ctx.HasThreadScope()) 278afdf842bSKuba Brecka return false; 279afdf842bSKuba Brecka 280afdf842bSKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 281afdf842bSKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 282afdf842bSKuba Brecka if (!info) 283afdf842bSKuba Brecka return false; 284afdf842bSKuba Brecka 285afdf842bSKuba Brecka info->Dump(strm); 286afdf842bSKuba Brecka 287afdf842bSKuba Brecka return true; 288afdf842bSKuba Brecka } 289afdf842bSKuba Brecka 2906a831436SKuba Brecka SBThreadCollection 291*b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { 2926a831436SKuba Brecka ThreadCollectionSP threads; 2936a831436SKuba Brecka threads.reset(new ThreadCollection()); 2946a831436SKuba Brecka 2956a831436SKuba Brecka // We currently only support ThreadSanitizer. 2966a831436SKuba Brecka if (type != eInstrumentationRuntimeTypeThreadSanitizer) 2976a831436SKuba Brecka return threads; 2986a831436SKuba Brecka 299b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 300b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 301b2e7d28eSJim Ingham 3026a831436SKuba Brecka if (!exe_ctx.HasThreadScope()) 3031aad8fb7SKuba Brecka return threads; 3046a831436SKuba Brecka 3056a831436SKuba Brecka ProcessSP process_sp = exe_ctx.GetProcessSP(); 3066a831436SKuba Brecka 3076a831436SKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3086a831436SKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3096a831436SKuba Brecka if (!info) 3106a831436SKuba Brecka return threads; 3116a831436SKuba Brecka 312*b9c1b51eSKate Stone return process_sp->GetInstrumentationRuntime(type) 313*b9c1b51eSKate Stone ->GetBacktracesFromExtendedStopInfo(info); 3146a831436SKuba Brecka } 3156a831436SKuba Brecka 316*b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { 3175160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 318ceb6b139SCaroline Tice 319bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 320bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3214fc6cb9cSJim Ingham 322*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 3237fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 324*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 3257fdf9ef1SGreg Clayton 3261ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 327*b9c1b51eSKate Stone if (stop_info_sp) { 328b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 329*b9c1b51eSKate Stone if (stop_desc) { 330ceb6b139SCaroline Tice if (log) 331*b9c1b51eSKate Stone log->Printf( 332*b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 333*b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 33430fdc8d8SChris Lattner if (dst) 33530fdc8d8SChris Lattner return ::snprintf(dst, dst_len, "%s", stop_desc); 336*b9c1b51eSKate Stone else { 337*b9c1b51eSKate Stone // NULL dst passed in, return the length needed to contain the 338*b9c1b51eSKate Stone // description 33930fdc8d8SChris Lattner return ::strlen(stop_desc) + 1; // Include the NULL byte for size 34030fdc8d8SChris Lattner } 341*b9c1b51eSKate Stone } else { 34230fdc8d8SChris Lattner size_t stop_desc_len = 0; 343*b9c1b51eSKate Stone switch (stop_info_sp->GetStopReason()) { 34430fdc8d8SChris Lattner case eStopReasonTrace: 345*b9c1b51eSKate Stone case eStopReasonPlanComplete: { 34630fdc8d8SChris Lattner static char trace_desc[] = "step"; 34730fdc8d8SChris Lattner stop_desc = trace_desc; 348*b9c1b51eSKate Stone stop_desc_len = 349*b9c1b51eSKate Stone sizeof(trace_desc); // Include the NULL byte for size 350*b9c1b51eSKate Stone } break; 35130fdc8d8SChris Lattner 352*b9c1b51eSKate Stone case eStopReasonBreakpoint: { 35330fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 35430fdc8d8SChris Lattner stop_desc = bp_desc; 35530fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 356*b9c1b51eSKate Stone } break; 35730fdc8d8SChris Lattner 358*b9c1b51eSKate Stone case eStopReasonWatchpoint: { 35930fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 36030fdc8d8SChris Lattner stop_desc = wp_desc; 36130fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 362*b9c1b51eSKate Stone } break; 36330fdc8d8SChris Lattner 364*b9c1b51eSKate Stone case eStopReasonSignal: { 365*b9c1b51eSKate Stone stop_desc = 366*b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( 367*b9c1b51eSKate Stone stop_info_sp->GetValue()); 368*b9c1b51eSKate Stone if (stop_desc == NULL || stop_desc[0] == '\0') { 36930fdc8d8SChris Lattner static char signal_desc[] = "signal"; 37030fdc8d8SChris Lattner stop_desc = signal_desc; 371*b9c1b51eSKate Stone stop_desc_len = 372*b9c1b51eSKate Stone sizeof(signal_desc); // Include the NULL byte for size 37330fdc8d8SChris Lattner } 374*b9c1b51eSKate Stone } break; 37530fdc8d8SChris Lattner 376*b9c1b51eSKate Stone case eStopReasonException: { 37730fdc8d8SChris Lattner char exc_desc[] = "exception"; 37830fdc8d8SChris Lattner stop_desc = exc_desc; 37930fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 380*b9c1b51eSKate Stone } break; 381c982c768SGreg Clayton 382*b9c1b51eSKate Stone case eStopReasonExec: { 38390ba8115SGreg Clayton char exc_desc[] = "exec"; 38490ba8115SGreg Clayton stop_desc = exc_desc; 38590ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 386*b9c1b51eSKate Stone } break; 38790ba8115SGreg Clayton 388*b9c1b51eSKate Stone case eStopReasonThreadExiting: { 389f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 390f85defaeSAndrew Kaylor stop_desc = limbo_desc; 391f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 392*b9c1b51eSKate Stone } break; 393c982c768SGreg Clayton default: 394c982c768SGreg Clayton break; 39530fdc8d8SChris Lattner } 39630fdc8d8SChris Lattner 397*b9c1b51eSKate Stone if (stop_desc && stop_desc[0]) { 398ceb6b139SCaroline Tice if (log) 399*b9c1b51eSKate Stone log->Printf( 400*b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 401*b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 402ceb6b139SCaroline Tice 40330fdc8d8SChris Lattner if (dst) 404*b9c1b51eSKate Stone return ::snprintf(dst, dst_len, "%s", stop_desc) + 405*b9c1b51eSKate Stone 1; // Include the NULL byte 40630fdc8d8SChris Lattner 40730fdc8d8SChris Lattner if (stop_desc_len == 0) 40830fdc8d8SChris Lattner stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte 40930fdc8d8SChris Lattner 41030fdc8d8SChris Lattner return stop_desc_len; 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner } 414*b9c1b51eSKate Stone } else { 4155160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 416c9858e4dSGreg Clayton if (log) 417*b9c1b51eSKate Stone log->Printf( 418*b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription() => error: process is running", 419324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 420c9858e4dSGreg Clayton } 4217fdf9ef1SGreg Clayton } 42230fdc8d8SChris Lattner if (dst) 42330fdc8d8SChris Lattner *dst = 0; 42430fdc8d8SChris Lattner return 0; 42530fdc8d8SChris Lattner } 42630fdc8d8SChris Lattner 427*b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() { 4285160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 42973ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 430bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 431bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4324fc6cb9cSJim Ingham 433*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4347fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 435*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4361ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 437*b9c1b51eSKate Stone if (stop_info_sp) { 43873ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); 43973ca05a2SJim Ingham } 440*b9c1b51eSKate Stone } else { 441c9858e4dSGreg Clayton if (log) 442*b9c1b51eSKate Stone log->Printf( 443*b9c1b51eSKate Stone "SBThread(%p)::GetStopReturnValue() => error: process is running", 444324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 445c9858e4dSGreg Clayton } 4467fdf9ef1SGreg Clayton } 44773ca05a2SJim Ingham 44873ca05a2SJim Ingham if (log) 449324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReturnValue () => %s", 450324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 451*b9c1b51eSKate Stone return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString() 45273ca05a2SJim Ingham : "<no return value>"); 45373ca05a2SJim Ingham 45473ca05a2SJim Ingham return SBValue(return_valobj_sp); 45573ca05a2SJim Ingham } 45673ca05a2SJim Ingham 457*b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 4587fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP(lldb_object_sp); 45930fdc8d8SChris Lattner } 46030fdc8d8SChris Lattner 461*b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const { 4627fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 46317a6ad05SGreg Clayton if (thread_sp) 4641ac04c30SGreg Clayton return thread_sp->GetID(); 4651ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 46630fdc8d8SChris Lattner } 46730fdc8d8SChris Lattner 468*b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const { 4697fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 47017a6ad05SGreg Clayton if (thread_sp) 47117a6ad05SGreg Clayton return thread_sp->GetIndexID(); 47230fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 47330fdc8d8SChris Lattner } 4741ac04c30SGreg Clayton 475*b9c1b51eSKate Stone const char *SBThread::GetName() const { 4765160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 4774838131bSGreg Clayton const char *name = NULL; 478bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 479bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4804fc6cb9cSJim Ingham 481*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4827fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 483*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4841ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 485*b9c1b51eSKate Stone } else { 486c9858e4dSGreg Clayton if (log) 487324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName() => error: process is running", 488324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 489c9858e4dSGreg Clayton } 4907fdf9ef1SGreg Clayton } 491ceb6b139SCaroline Tice 492ceb6b139SCaroline Tice if (log) 493324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName () => %s", 494324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 495324a1036SSaleem Abdulrasool name ? name : "NULL"); 496ceb6b139SCaroline Tice 4974838131bSGreg Clayton return name; 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner 500*b9c1b51eSKate Stone const char *SBThread::GetQueueName() const { 5014838131bSGreg Clayton const char *name = NULL; 502bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 503bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5044fc6cb9cSJim Ingham 5055160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 506*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5077fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 508*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5091ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 510*b9c1b51eSKate Stone } else { 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 525*b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const { 5264fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 527bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 528bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5294fdb5863SJason Molenda 5304fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 531*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5324fdb5863SJason Molenda Process::StopLocker stop_locker; 533*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5344fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 535*b9c1b51eSKate Stone } else { 5364fdb5863SJason Molenda if (log) 537324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID() => error: process is running", 538324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 5394fdb5863SJason Molenda } 5404fdb5863SJason Molenda } 5414fdb5863SJason Molenda 5424fdb5863SJason Molenda if (log) 543324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 544324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), id); 5454fdb5863SJason Molenda 5464fdb5863SJason Molenda return id; 5474fdb5863SJason Molenda } 5484fdb5863SJason Molenda 549*b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 550705b1809SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 551705b1809SJason Molenda bool success = false; 552bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 553bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 554705b1809SJason Molenda 555*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 556705b1809SJason Molenda Process::StopLocker stop_locker; 557*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 558705b1809SJason Molenda Thread *thread = exe_ctx.GetThreadPtr(); 559705b1809SJason Molenda StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 560*b9c1b51eSKate Stone if (info_root_sp) { 561*b9c1b51eSKate Stone StructuredData::ObjectSP node = 562*b9c1b51eSKate Stone info_root_sp->GetObjectForDotSeparatedPath(path); 563*b9c1b51eSKate Stone if (node) { 564*b9c1b51eSKate Stone if (node->GetType() == StructuredData::Type::eTypeString) { 565705b1809SJason Molenda strm.Printf("%s", node->GetAsString()->GetValue().c_str()); 566705b1809SJason Molenda success = true; 567705b1809SJason Molenda } 568*b9c1b51eSKate Stone if (node->GetType() == StructuredData::Type::eTypeInteger) { 569705b1809SJason Molenda strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 570705b1809SJason Molenda success = true; 571705b1809SJason Molenda } 572*b9c1b51eSKate Stone if (node->GetType() == StructuredData::Type::eTypeFloat) { 573705b1809SJason Molenda strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 574705b1809SJason Molenda success = true; 575705b1809SJason Molenda } 576*b9c1b51eSKate Stone if (node->GetType() == StructuredData::Type::eTypeBoolean) { 577705b1809SJason Molenda if (node->GetAsBoolean()->GetValue() == true) 578705b1809SJason Molenda strm.Printf("true"); 579705b1809SJason Molenda else 580705b1809SJason Molenda strm.Printf("false"); 581705b1809SJason Molenda success = true; 582705b1809SJason Molenda } 583*b9c1b51eSKate Stone if (node->GetType() == StructuredData::Type::eTypeNull) { 584705b1809SJason Molenda strm.Printf("null"); 585705b1809SJason Molenda success = true; 586705b1809SJason Molenda } 587705b1809SJason Molenda } 588705b1809SJason Molenda } 589*b9c1b51eSKate Stone } else { 590705b1809SJason Molenda if (log) 591*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: " 592*b9c1b51eSKate Stone "process is running", 593705b1809SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 594705b1809SJason Molenda } 595705b1809SJason Molenda } 596705b1809SJason Molenda 597705b1809SJason Molenda if (log) 598705b1809SJason Molenda log->Printf("SBThread(%p)::GetInfoItemByPathAsString () => %s", 599*b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), strm.GetData()); 600705b1809SJason Molenda 601705b1809SJason Molenda return success; 602705b1809SJason Molenda } 603705b1809SJason Molenda 604*b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 605*b9c1b51eSKate Stone ThreadPlan *new_plan) { 60664e7ead1SJim Ingham SBError sb_error; 60764e7ead1SJim Ingham 60864e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 609*b9c1b51eSKate Stone if (!process) { 61064e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 61164e7ead1SJim Ingham return sb_error; 61264e7ead1SJim Ingham } 61364e7ead1SJim Ingham 61464e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 615*b9c1b51eSKate Stone if (!thread) { 61664e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 61764e7ead1SJim Ingham return sb_error; 61864e7ead1SJim Ingham } 61964e7ead1SJim Ingham 620*b9c1b51eSKate Stone // User level plans should be Master Plans so they can be interrupted, other 621*b9c1b51eSKate Stone // plans executed, and 62264e7ead1SJim Ingham // then a "continue" will resume the plan. 623*b9c1b51eSKate Stone if (new_plan != NULL) { 62464e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 62564e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 62664e7ead1SJim Ingham } 62764e7ead1SJim Ingham 62864e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 62964e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 63064e7ead1SJim Ingham 631dc6224e0SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution()) 632dc6224e0SGreg Clayton sb_error.ref() = process->Resume(); 633dc6224e0SGreg Clayton else 634dc6224e0SGreg Clayton sb_error.ref() = process->ResumeSynchronous(NULL); 63564e7ead1SJim Ingham 63664e7ead1SJim Ingham return sb_error; 63764e7ead1SJim Ingham } 63830fdc8d8SChris Lattner 639*b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) { 6405160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 641ceb6b139SCaroline Tice 642bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 643bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 64417a6ad05SGreg Clayton 645ceb6b139SCaroline Tice if (log) 646324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')", 647324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 648ceb6b139SCaroline Tice Thread::RunModeAsCString(stop_other_threads)); 649ceb6b139SCaroline Tice 650*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 6511ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6527ba6e991SJim Ingham bool abort_other_plans = false; 653b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 65430fdc8d8SChris Lattner 6554d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 656*b9c1b51eSKate Stone if (frame_sp) { 657*b9c1b51eSKate Stone if (frame_sp->HasDebugInformation()) { 6584b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 65930fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 660*b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepOverRange( 661*b9c1b51eSKate Stone abort_other_plans, sc.line_entry, sc, stop_other_threads, 6624b4b2478SJim Ingham avoid_no_debug); 663*b9c1b51eSKate Stone } else { 664*b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 665*b9c1b51eSKate Stone true, abort_other_plans, stop_other_threads); 66630fdc8d8SChris Lattner } 66730fdc8d8SChris Lattner } 66830fdc8d8SChris Lattner 66964e7ead1SJim Ingham // This returns an error, we should use it! 6704d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 67130fdc8d8SChris Lattner } 67230fdc8d8SChris Lattner } 67330fdc8d8SChris Lattner 674*b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) { 675c627682eSJim Ingham StepInto(NULL, stop_other_threads); 676c627682eSJim Ingham } 677c627682eSJim Ingham 678*b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, 679*b9c1b51eSKate Stone lldb::RunMode stop_other_threads) { 680cbf6f9b2SJim Ingham SBError error; 681cbf6f9b2SJim Ingham StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 682cbf6f9b2SJim Ingham } 683cbf6f9b2SJim Ingham 684*b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line, 685*b9c1b51eSKate Stone SBError &error, lldb::RunMode stop_other_threads) { 6865160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 687ceb6b139SCaroline Tice 688bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 689bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 69017a6ad05SGreg Clayton 69117a6ad05SGreg Clayton if (log) 692*b9c1b51eSKate Stone log->Printf( 693*b9c1b51eSKate Stone "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 694324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 695c627682eSJim Ingham target_name ? target_name : "<NULL>", 69617a6ad05SGreg Clayton Thread::RunModeAsCString(stop_other_threads)); 697c627682eSJim Ingham 698*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 6997ba6e991SJim Ingham bool abort_other_plans = false; 70030fdc8d8SChris Lattner 7011ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 702b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 7034d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 70430fdc8d8SChris Lattner 705*b9c1b51eSKate Stone if (frame_sp && frame_sp->HasDebugInformation()) { 706cbf6f9b2SJim Ingham SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 707cbf6f9b2SJim Ingham AddressRange range; 708cbf6f9b2SJim Ingham if (end_line == LLDB_INVALID_LINE_NUMBER) 709cbf6f9b2SJim Ingham range = sc.line_entry.range; 710*b9c1b51eSKate Stone else { 711cbf6f9b2SJim Ingham if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 712cbf6f9b2SJim Ingham return; 713cbf6f9b2SJim Ingham } 714cbf6f9b2SJim Ingham 715*b9c1b51eSKate Stone const LazyBool step_out_avoids_code_without_debug_info = 716*b9c1b51eSKate Stone eLazyBoolCalculate; 717*b9c1b51eSKate Stone const LazyBool step_in_avoids_code_without_debug_info = 718*b9c1b51eSKate Stone eLazyBoolCalculate; 719*b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepInRange( 720*b9c1b51eSKate Stone abort_other_plans, range, sc, target_name, stop_other_threads, 7214b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 7224b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 723*b9c1b51eSKate Stone } else { 724*b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 725*b9c1b51eSKate Stone false, abort_other_plans, stop_other_threads); 72630fdc8d8SChris Lattner } 72730fdc8d8SChris Lattner 728cbf6f9b2SJim Ingham error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 72930fdc8d8SChris Lattner } 73030fdc8d8SChris Lattner } 73130fdc8d8SChris Lattner 732*b9c1b51eSKate Stone void SBThread::StepOut() { 7335160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 734ceb6b139SCaroline Tice 735bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 736bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7374fc6cb9cSJim Ingham 73817a6ad05SGreg Clayton if (log) 739324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOut ()", 740324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 74117a6ad05SGreg Clayton 742*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 7437ba6e991SJim Ingham bool abort_other_plans = false; 74494b09246SJim Ingham bool stop_other_threads = false; 74530fdc8d8SChris Lattner 7461ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7471ac04c30SGreg Clayton 7484b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 749*b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 750*b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 751*b9c1b51eSKate Stone eVoteNoOpinion, 0, avoid_no_debug)); 752481cef25SGreg Clayton 75364e7ead1SJim Ingham // This returns an error, we should use it! 7544d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 755481cef25SGreg Clayton } 756481cef25SGreg Clayton } 757481cef25SGreg Clayton 758*b9c1b51eSKate Stone void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) { 7595160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 760481cef25SGreg Clayton 761bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 762bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7634fc6cb9cSJim Ingham 764*b9c1b51eSKate Stone if (!sb_frame.IsValid()) { 765989a7558SJim Ingham if (log) 766*b9c1b51eSKate Stone log->Printf( 767*b9c1b51eSKate Stone "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 768989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 769989a7558SJim Ingham return; 770989a7558SJim Ingham } 771989a7558SJim Ingham 772b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 773*b9c1b51eSKate Stone if (log) { 774481cef25SGreg Clayton SBStream frame_desc_strm; 775481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 776324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 777324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 778*b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 779481cef25SGreg Clayton } 780481cef25SGreg Clayton 781*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 7827ba6e991SJim Ingham bool abort_other_plans = false; 78394b09246SJim Ingham bool stop_other_threads = false; 7841ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 785*b9c1b51eSKate Stone if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 786*b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another " 787*b9c1b51eSKate Stone "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 788989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 789*b9c1b51eSKate Stone sb_frame.GetThread().GetThreadID(), thread->GetID()); 790989a7558SJim Ingham } 791481cef25SGreg Clayton 792*b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 793*b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 794*b9c1b51eSKate Stone eVoteNoOpinion, frame_sp->GetFrameIndex())); 79530fdc8d8SChris Lattner 79664e7ead1SJim Ingham // This returns an error, we should use it! 7974d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 79830fdc8d8SChris Lattner } 79930fdc8d8SChris Lattner } 80030fdc8d8SChris Lattner 801*b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) { 8025160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 803ceb6b139SCaroline Tice 804bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 805bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 806ceb6b139SCaroline Tice 80717a6ad05SGreg Clayton if (log) 808324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepInstruction (step_over=%i)", 809324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), step_over); 81017a6ad05SGreg Clayton 811*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8121ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 813*b9c1b51eSKate Stone ThreadPlanSP new_plan_sp( 814*b9c1b51eSKate Stone thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true)); 81564e7ead1SJim Ingham 81664e7ead1SJim Ingham // This returns an error, we should use it! 8174d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 81830fdc8d8SChris Lattner } 81930fdc8d8SChris Lattner } 82030fdc8d8SChris Lattner 821*b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) { 8225160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 823ceb6b139SCaroline Tice 824bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 825bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 826ceb6b139SCaroline Tice 82717a6ad05SGreg Clayton if (log) 828324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 829324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), addr); 83017a6ad05SGreg Clayton 831*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8327ba6e991SJim Ingham bool abort_other_plans = false; 83330fdc8d8SChris Lattner bool stop_other_threads = true; 83430fdc8d8SChris Lattner 835e72dfb32SGreg Clayton Address target_addr(addr); 83630fdc8d8SChris Lattner 8371ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8381ac04c30SGreg Clayton 839*b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 840*b9c1b51eSKate Stone abort_other_plans, target_addr, stop_other_threads)); 84164e7ead1SJim Ingham 84264e7ead1SJim Ingham // This returns an error, we should use it! 8434d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 84430fdc8d8SChris Lattner } 84530fdc8d8SChris Lattner } 84630fdc8d8SChris Lattner 847*b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 848*b9c1b51eSKate Stone lldb::SBFileSpec &sb_file_spec, uint32_t line) { 849481cef25SGreg Clayton SBError sb_error; 8505160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 851481cef25SGreg Clayton char path[PATH_MAX]; 852481cef25SGreg Clayton 853bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 854bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 8554fc6cb9cSJim Ingham 856b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 85717a6ad05SGreg Clayton 858*b9c1b51eSKate Stone if (log) { 859481cef25SGreg Clayton SBStream frame_desc_strm; 860481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 861481cef25SGreg Clayton sb_file_spec->GetPath(path, sizeof(path)); 862*b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, " 863*b9c1b51eSKate Stone "file+line = %s:%u)", 864324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 865*b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(), 866*b9c1b51eSKate Stone path, line); 867481cef25SGreg Clayton } 868481cef25SGreg Clayton 869*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8701ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 8711ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 872481cef25SGreg Clayton 873*b9c1b51eSKate Stone if (line == 0) { 874481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 875481cef25SGreg Clayton return sb_error; 876481cef25SGreg Clayton } 877481cef25SGreg Clayton 878*b9c1b51eSKate Stone if (!frame_sp) { 8791ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame(); 880481cef25SGreg Clayton if (!frame_sp) 8811ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(0); 882481cef25SGreg Clayton } 883481cef25SGreg Clayton 884481cef25SGreg Clayton SymbolContext frame_sc; 885*b9c1b51eSKate Stone if (!frame_sp) { 886481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 887481cef25SGreg Clayton return sb_error; 888481cef25SGreg Clayton } 889481cef25SGreg Clayton 890481cef25SGreg Clayton // If we have a frame, get its line 891*b9c1b51eSKate Stone frame_sc = frame_sp->GetSymbolContext( 892*b9c1b51eSKate Stone eSymbolContextCompUnit | eSymbolContextFunction | 893*b9c1b51eSKate Stone eSymbolContextLineEntry | eSymbolContextSymbol); 894481cef25SGreg Clayton 895*b9c1b51eSKate Stone if (frame_sc.comp_unit == NULL) { 896*b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 897*b9c1b51eSKate Stone "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 898481cef25SGreg Clayton return sb_error; 899481cef25SGreg Clayton } 900481cef25SGreg Clayton 901481cef25SGreg Clayton FileSpec step_file_spec; 902*b9c1b51eSKate Stone if (sb_file_spec.IsValid()) { 903481cef25SGreg Clayton // The file spec passed in was valid, so use it 904481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 905*b9c1b51eSKate Stone } else { 906481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 907481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 908*b9c1b51eSKate Stone else { 909481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 910481cef25SGreg Clayton return sb_error; 911481cef25SGreg Clayton } 912481cef25SGreg Clayton } 913481cef25SGreg Clayton 9149b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9159b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 916*b9c1b51eSKate Stone // function, and then if there are no addresses remaining, give an 917*b9c1b51eSKate Stone // appropriate 9189b70ddb3SJim Ingham // error message. 9199b70ddb3SJim Ingham 9209b70ddb3SJim Ingham bool all_in_function = true; 9219b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9229b70ddb3SJim Ingham 923481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9247ba6e991SJim Ingham const bool abort_other_plans = false; 925c02e3344SJim Ingham const bool stop_other_threads = false; 926481cef25SGreg Clayton const bool check_inlines = true; 927481cef25SGreg Clayton const bool exact = false; 928481cef25SGreg Clayton 929481cef25SGreg Clayton SymbolContextList sc_list; 930*b9c1b51eSKate Stone const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext( 931*b9c1b51eSKate Stone step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, 9329b70ddb3SJim Ingham sc_list); 933*b9c1b51eSKate Stone if (num_matches > 0) { 934481cef25SGreg Clayton SymbolContext sc; 935*b9c1b51eSKate Stone for (uint32_t i = 0; i < num_matches; ++i) { 936*b9c1b51eSKate Stone if (sc_list.GetContextAtIndex(i, sc)) { 937*b9c1b51eSKate Stone addr_t step_addr = 938*b9c1b51eSKate Stone sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 939*b9c1b51eSKate Stone if (step_addr != LLDB_INVALID_ADDRESS) { 9409b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 941481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9429b70ddb3SJim Ingham else 9439b70ddb3SJim Ingham all_in_function = false; 944481cef25SGreg Clayton } 945481cef25SGreg Clayton } 946481cef25SGreg Clayton } 947481cef25SGreg Clayton } 948481cef25SGreg Clayton 949*b9c1b51eSKate Stone if (step_over_until_addrs.empty()) { 950*b9c1b51eSKate Stone if (all_in_function) { 951481cef25SGreg Clayton step_file_spec.GetPath(path, sizeof(path)); 952*b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 953*b9c1b51eSKate Stone line); 954*b9c1b51eSKate Stone } else 95586edbf41SGreg Clayton sb_error.SetErrorString("step until target not in current function"); 956*b9c1b51eSKate Stone } else { 957*b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 958*b9c1b51eSKate Stone abort_other_plans, &step_over_until_addrs[0], 959*b9c1b51eSKate Stone step_over_until_addrs.size(), stop_other_threads, 9604d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 961481cef25SGreg Clayton 9624d56e9c1SJim Ingham sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 963481cef25SGreg Clayton } 964*b9c1b51eSKate Stone } else { 965481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 966481cef25SGreg Clayton } 967481cef25SGreg Clayton return sb_error; 968481cef25SGreg Clayton } 969481cef25SGreg Clayton 970*b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 971000ca185SOleksiy Vyalov return StepUsingScriptedThreadPlan(script_class_name, true); 972c915a7d2SJim Ingham } 973c915a7d2SJim Ingham 974*b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 975*b9c1b51eSKate Stone bool resume_immediately) { 9762bdbfd50SJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 9772bdbfd50SJim Ingham SBError sb_error; 9782bdbfd50SJim Ingham 979bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 980bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9812bdbfd50SJim Ingham 982*b9c1b51eSKate Stone if (log) { 9832bdbfd50SJim Ingham log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 984*b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name); 9852bdbfd50SJim Ingham } 9862bdbfd50SJim Ingham 987*b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 9882bdbfd50SJim Ingham sb_error.SetErrorString("this SBThread object is invalid"); 9892bdbfd50SJim Ingham return sb_error; 9902bdbfd50SJim Ingham } 9912bdbfd50SJim Ingham 9922bdbfd50SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 993*b9c1b51eSKate Stone ThreadPlanSP thread_plan_sp = 994*b9c1b51eSKate Stone thread->QueueThreadPlanForStepScripted(false, script_class_name, false); 9952bdbfd50SJim Ingham 996*b9c1b51eSKate Stone if (!thread_plan_sp) { 997*b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 998*b9c1b51eSKate Stone "Error queueing thread plan for class: %s", script_class_name); 999c915a7d2SJim Ingham return sb_error; 1000c915a7d2SJim Ingham } 1001c915a7d2SJim Ingham 1002*b9c1b51eSKate Stone if (!resume_immediately) { 1003c915a7d2SJim Ingham return sb_error; 1004c915a7d2SJim Ingham } 1005c915a7d2SJim Ingham 10062bdbfd50SJim Ingham if (thread_plan_sp) 10072bdbfd50SJim Ingham sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); 1008*b9c1b51eSKate Stone else { 1009*b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 1010*b9c1b51eSKate Stone "Error resuming thread plan for class: %s.", script_class_name); 10112bdbfd50SJim Ingham if (log) 1012*b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing " 1013*b9c1b51eSKate Stone "thread plan for class: %s", 10142bdbfd50SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 10152bdbfd50SJim Ingham script_class_name); 10162bdbfd50SJim Ingham } 10172bdbfd50SJim Ingham 10182bdbfd50SJim Ingham return sb_error; 10192bdbfd50SJim Ingham } 10202bdbfd50SJim Ingham 1021*b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 1022f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1023f86248d9SRichard Mitton SBError sb_error; 1024f86248d9SRichard Mitton 1025bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1026bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1027f86248d9SRichard Mitton 1028f86248d9SRichard Mitton if (log) 1029324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1030324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1031324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1032f86248d9SRichard Mitton 1033*b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1034f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1035f86248d9SRichard Mitton return sb_error; 1036f86248d9SRichard Mitton } 1037f86248d9SRichard Mitton 1038f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1039f86248d9SRichard Mitton 1040f86248d9SRichard Mitton Error err = thread->JumpToLine(file_spec.get(), line, true); 1041f86248d9SRichard Mitton sb_error.SetError(err); 1042f86248d9SRichard Mitton return sb_error; 1043f86248d9SRichard Mitton } 1044f86248d9SRichard Mitton 1045*b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 10464413758cSJim Ingham SBError sb_error; 10474413758cSJim Ingham 10485160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 10494413758cSJim Ingham 1050bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1051bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10524413758cSJim Ingham 10534413758cSJim Ingham if (log) 1054324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)", 1055324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1056324a1036SSaleem Abdulrasool frame.GetFrameID()); 10574413758cSJim Ingham 1058*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 10594413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1060*b9c1b51eSKate Stone sb_error.SetError( 1061*b9c1b51eSKate Stone thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 10624413758cSJim Ingham } 10634413758cSJim Ingham 10644413758cSJim Ingham return sb_error; 10654413758cSJim Ingham } 10664413758cSJim Ingham 1067*b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() { 10684ac8e93aSJim Ingham SBError sb_error; 10694ac8e93aSJim Ingham 10704ac8e93aSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 10714ac8e93aSJim Ingham 10724ac8e93aSJim Ingham std::unique_lock<std::recursive_mutex> lock; 10734ac8e93aSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10744ac8e93aSJim Ingham 10754ac8e93aSJim Ingham if (log) 10764ac8e93aSJim Ingham log->Printf("SBThread(%p)::UnwindExpressionEvaluation", 10774ac8e93aSJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 10784ac8e93aSJim Ingham 1079*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 10804ac8e93aSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 10814ac8e93aSJim Ingham sb_error.SetError(thread->UnwindInnermostExpression()); 10824ac8e93aSJim Ingham if (sb_error.Success()) 10834ac8e93aSJim Ingham thread->SetSelectedFrameByIndex(0, false); 10844ac8e93aSJim Ingham } 10854ac8e93aSJim Ingham 10864ac8e93aSJim Ingham return sb_error; 10874ac8e93aSJim Ingham } 1088481cef25SGreg Clayton 1089*b9c1b51eSKate Stone bool SBThread::Suspend() { 10905160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1091b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1092b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1093b2e7d28eSJim Ingham 1094c9858e4dSGreg Clayton bool result = false; 1095*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1096c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1097*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 10981ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 1099c9858e4dSGreg Clayton result = true; 1100*b9c1b51eSKate Stone } else { 1101c9858e4dSGreg Clayton if (log) 1102324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => error: process is running", 1103324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1104c9858e4dSGreg Clayton } 1105c9858e4dSGreg Clayton } 1106c9858e4dSGreg Clayton if (log) 1107324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => %i", 1108324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1109c9858e4dSGreg Clayton return result; 1110722a0cdcSGreg Clayton } 1111722a0cdcSGreg Clayton 1112*b9c1b51eSKate Stone bool SBThread::Resume() { 11135160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1114b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1115b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1116b2e7d28eSJim Ingham 1117c9858e4dSGreg Clayton bool result = false; 1118*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1119c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1120*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11216c9ed91cSJim Ingham const bool override_suspend = true; 11226c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 1123c9858e4dSGreg Clayton result = true; 1124*b9c1b51eSKate Stone } else { 1125c9858e4dSGreg Clayton if (log) 1126324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => error: process is running", 1127324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1128c9858e4dSGreg Clayton } 1129c9858e4dSGreg Clayton } 1130c9858e4dSGreg Clayton if (log) 1131324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => %i", 1132324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1133c9858e4dSGreg Clayton return result; 1134722a0cdcSGreg Clayton } 1135722a0cdcSGreg Clayton 1136*b9c1b51eSKate Stone bool SBThread::IsSuspended() { 1137b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1138b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1139b2e7d28eSJim Ingham 11401ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 11411ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 1142722a0cdcSGreg Clayton return false; 1143722a0cdcSGreg Clayton } 1144722a0cdcSGreg Clayton 1145*b9c1b51eSKate Stone bool SBThread::IsStopped() { 1146b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1147b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1148b2e7d28eSJim Ingham 1149a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1150a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1151a75418dbSAndrew Kaylor return false; 1152a75418dbSAndrew Kaylor } 1153a75418dbSAndrew Kaylor 1154*b9c1b51eSKate Stone SBProcess SBThread::GetProcess() { 1155b9556accSGreg Clayton SBProcess sb_process; 1156b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1157b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1158b2e7d28eSJim Ingham 1159*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1160*b9c1b51eSKate Stone // Have to go up to the target so we can get a shared pointer to our 1161*b9c1b51eSKate Stone // process... 11621ac04c30SGreg Clayton sb_process.SetSP(exe_ctx.GetProcessSP()); 116330fdc8d8SChris Lattner } 1164ceb6b139SCaroline Tice 11655160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1166*b9c1b51eSKate Stone if (log) { 1167481cef25SGreg Clayton SBStream frame_desc_strm; 1168b9556accSGreg Clayton sb_process.GetDescription(frame_desc_strm); 1169324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1170324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1171324a1036SSaleem Abdulrasool static_cast<void *>(sb_process.GetSP().get()), 1172324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1173ceb6b139SCaroline Tice } 1174ceb6b139SCaroline Tice 1175b9556accSGreg Clayton return sb_process; 117630fdc8d8SChris Lattner } 117730fdc8d8SChris Lattner 1178*b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() { 11795160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1180ceb6b139SCaroline Tice 1181ceb6b139SCaroline Tice uint32_t num_frames = 0; 1182bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1183bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11844fc6cb9cSJim Ingham 1185*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11867fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1187*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11881ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1189*b9c1b51eSKate Stone } else { 1190c9858e4dSGreg Clayton if (log) 1191324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames() => error: process is running", 1192324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1193c9858e4dSGreg Clayton } 11947fdf9ef1SGreg Clayton } 1195ceb6b139SCaroline Tice 1196ceb6b139SCaroline Tice if (log) 1197324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames () => %u", 1198324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames); 1199ceb6b139SCaroline Tice 1200ceb6b139SCaroline Tice return num_frames; 120130fdc8d8SChris Lattner } 120230fdc8d8SChris Lattner 1203*b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 12045160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1205ceb6b139SCaroline Tice 120630fdc8d8SChris Lattner SBFrame sb_frame; 1207b57e4a1bSJason Molenda StackFrameSP frame_sp; 1208bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1209bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12104fc6cb9cSJim Ingham 1211*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12127fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1213*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12141ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 1215b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1216*b9c1b51eSKate Stone } else { 1217c9858e4dSGreg Clayton if (log) 1218*b9c1b51eSKate Stone log->Printf( 1219*b9c1b51eSKate Stone "SBThread(%p)::GetFrameAtIndex() => error: process is running", 1220324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1221c9858e4dSGreg Clayton } 12227fdf9ef1SGreg Clayton } 1223ceb6b139SCaroline Tice 1224*b9c1b51eSKate Stone if (log) { 1225481cef25SGreg Clayton SBStream frame_desc_strm; 1226481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 12274838131bSGreg Clayton log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1228324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1229*b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1230ceb6b139SCaroline Tice } 1231ceb6b139SCaroline Tice 123230fdc8d8SChris Lattner return sb_frame; 123330fdc8d8SChris Lattner } 123430fdc8d8SChris Lattner 1235*b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() { 12365160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1237f028a1fbSGreg Clayton 1238f028a1fbSGreg Clayton SBFrame sb_frame; 1239b57e4a1bSJason Molenda StackFrameSP frame_sp; 1240bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1241bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12424fc6cb9cSJim Ingham 1243*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12447fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1245*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12461ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 1247b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1248*b9c1b51eSKate Stone } else { 1249c9858e4dSGreg Clayton if (log) 1250*b9c1b51eSKate Stone log->Printf( 1251*b9c1b51eSKate Stone "SBThread(%p)::GetSelectedFrame() => error: process is running", 1252324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1253c9858e4dSGreg Clayton } 12547fdf9ef1SGreg Clayton } 1255f028a1fbSGreg Clayton 1256*b9c1b51eSKate Stone if (log) { 1257481cef25SGreg Clayton SBStream frame_desc_strm; 1258481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1259f028a1fbSGreg Clayton log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1260324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1261*b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1262f028a1fbSGreg Clayton } 1263f028a1fbSGreg Clayton 1264f028a1fbSGreg Clayton return sb_frame; 1265f028a1fbSGreg Clayton } 1266f028a1fbSGreg Clayton 1267*b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 12685160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1269f028a1fbSGreg Clayton 1270f028a1fbSGreg Clayton SBFrame sb_frame; 1271b57e4a1bSJason Molenda StackFrameSP frame_sp; 1272bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1273bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12744fc6cb9cSJim Ingham 1275*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12767fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1277*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12781ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 12791ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(idx); 1280*b9c1b51eSKate Stone if (frame_sp) { 12811ac04c30SGreg Clayton thread->SetSelectedFrame(frame_sp.get()); 1282b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1283f028a1fbSGreg Clayton } 1284*b9c1b51eSKate Stone } else { 1285c9858e4dSGreg Clayton if (log) 1286*b9c1b51eSKate Stone log->Printf( 1287*b9c1b51eSKate Stone "SBThread(%p)::SetSelectedFrame() => error: process is running", 1288324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1289c9858e4dSGreg Clayton } 12907fdf9ef1SGreg Clayton } 1291f028a1fbSGreg Clayton 1292*b9c1b51eSKate Stone if (log) { 1293481cef25SGreg Clayton SBStream frame_desc_strm; 1294481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1295f028a1fbSGreg Clayton log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1296324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1297*b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1298f028a1fbSGreg Clayton } 1299f028a1fbSGreg Clayton return sb_frame; 1300f028a1fbSGreg Clayton } 1301f028a1fbSGreg Clayton 1302*b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) { 13034f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 13044f465cffSJim Ingham } 13054f465cffSJim Ingham 1306*b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 13074f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 13084f465cffSJim Ingham } 13094f465cffSJim Ingham 1310*b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 13114f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 13124f465cffSJim Ingham } 1313f028a1fbSGreg Clayton 1314*b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const { 1315*b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() == 1316*b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 131730fdc8d8SChris Lattner } 131830fdc8d8SChris Lattner 1319*b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const { 1320*b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() != 1321*b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 132230fdc8d8SChris Lattner } 1323dde9cff3SCaroline Tice 1324*b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const { 13254f465cffSJim Ingham Stream &strm = status.ref(); 13264f465cffSJim Ingham 1327b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1328b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1329b2e7d28eSJim Ingham 1330*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13314f465cffSJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1); 1332*b9c1b51eSKate Stone } else 13334f465cffSJim Ingham strm.PutCString("No status"); 13344f465cffSJim Ingham 13354f465cffSJim Ingham return true; 13364f465cffSJim Ingham } 13374f465cffSJim Ingham 1338*b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const { 1339da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1340da7bc7d0SGreg Clayton 1341b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1342b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1343b2e7d28eSJim Ingham 1344*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1345*b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 1346*b9c1b51eSKate Stone LLDB_INVALID_THREAD_ID); 1347*b9c1b51eSKate Stone // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 1348*b9c1b51eSKate Stone // exe_ctx.GetThreadPtr()->GetID()); 1349*b9c1b51eSKate Stone } else 1350da7bc7d0SGreg Clayton strm.PutCString("No value"); 1351ceb6b139SCaroline Tice 1352ceb6b139SCaroline Tice return true; 1353ceb6b139SCaroline Tice } 13545dd4916fSJason Molenda 1355*b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 13565dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1357bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1358bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13595dd4916fSJason Molenda SBThread sb_origin_thread; 13605dd4916fSJason Molenda 1361*b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13625dd4916fSJason Molenda Process::StopLocker stop_locker; 1363*b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13647a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 1365*b9c1b51eSKate Stone if (real_thread) { 13665dd4916fSJason Molenda ConstString type_const(type); 13677a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 1368*b9c1b51eSKate Stone if (process) { 13697a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 1370*b9c1b51eSKate Stone if (runtime) { 1371*b9c1b51eSKate Stone ThreadSP new_thread_sp( 1372*b9c1b51eSKate Stone runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1373*b9c1b51eSKate Stone if (new_thread_sp) { 1374*b9c1b51eSKate Stone // Save this in the Process' ExtendedThreadList so a strong 1375*b9c1b51eSKate Stone // pointer retains the 13767a2f7904SJason Molenda // object. 13777a2f7904SJason Molenda process->GetExtendedThreadList().AddThread(new_thread_sp); 13787a2f7904SJason Molenda sb_origin_thread.SetThread(new_thread_sp); 1379*b9c1b51eSKate Stone if (log) { 1380a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1381a6e9130dSJason Molenda if (queue_name == NULL) 1382a6e9130dSJason Molenda queue_name = ""; 1383*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new " 1384*b9c1b51eSKate Stone "extended Thread " 1385*b9c1b51eSKate Stone "created (%p) with queue_id 0x%" PRIx64 1386*b9c1b51eSKate Stone " queue name '%s'", 1387324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1388324a1036SSaleem Abdulrasool static_cast<void *>(new_thread_sp.get()), 1389*b9c1b51eSKate Stone new_thread_sp->GetQueueID(), queue_name); 1390a6e9130dSJason Molenda } 1391a6e9130dSJason Molenda } 13927a2f7904SJason Molenda } 13935dd4916fSJason Molenda } 13945dd4916fSJason Molenda } 1395*b9c1b51eSKate Stone } else { 13965dd4916fSJason Molenda if (log) 1397*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: " 1398*b9c1b51eSKate Stone "process is running", 1399324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14005dd4916fSJason Molenda } 14015dd4916fSJason Molenda } 14025dd4916fSJason Molenda 1403ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1404*b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a " 1405*b9c1b51eSKate Stone "Valid thread", 1406324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14075dd4916fSJason Molenda return sb_origin_thread; 14085dd4916fSJason Molenda } 14098ee9cb58SJason Molenda 1410*b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 14118ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14128ee9cb58SJason Molenda if (thread_sp) 14138ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14148ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14158ee9cb58SJason Molenda } 1416b4892cd2SJason Molenda 1417*b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() { 1418b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1419b4892cd2SJason Molenda if (thread_sp) 1420b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1421b4892cd2SJason Molenda return true; 1422b4892cd2SJason Molenda } 14232bdbfd50SJim Ingham 1424*b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() { 14252bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14262bdbfd50SJim Ingham if (thread_sp) 14272bdbfd50SJim Ingham return thread_sp.get(); 14282bdbfd50SJim Ingham else 14292bdbfd50SJim Ingham return NULL; 14302bdbfd50SJim Ingham } 14312bdbfd50SJim Ingham 1432*b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() { 14332bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14342bdbfd50SJim Ingham if (thread_sp) 14352bdbfd50SJim Ingham return thread_sp.get(); 14362bdbfd50SJim Ingham else 14372bdbfd50SJim Ingham return NULL; 14382bdbfd50SJim Ingham } 1439