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" 14b9c1b51eSKate 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/StreamFile.h" 19705b1809SJason Molenda #include "lldb/Core/StructuredData.h" 20a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h" 216611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2293749ab3SZachary Turner #include "lldb/Symbol/CompileUnit.h" 23b9c1b51eSKate Stone #include "lldb/Symbol/SymbolContext.h" 2430fdc8d8SChris Lattner #include "lldb/Target/Process.h" 25b9ffa98cSJason Molenda #include "lldb/Target/Queue.h" 26f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h" 27b9c1b51eSKate Stone #include "lldb/Target/SystemRuntime.h" 2830fdc8d8SChris Lattner #include "lldb/Target/Target.h" 29b9c1b51eSKate Stone #include "lldb/Target/Thread.h" 3030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 31b9c1b51eSKate Stone #include "lldb/Target/ThreadPlanStepInRange.h" 3230fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepInstruction.h" 3330fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepOut.h" 3430fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanStepRange.h" 35b9c1b51eSKate Stone #include "lldb/Target/UnixSignals.h" 36bf9a7730SZachary Turner #include "lldb/Utility/Stream.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" 46*5bfee5f1SAbhishek Aggarwal #include "lldb/lldb-enumerations.h" 4730fdc8d8SChris Lattner 4830fdc8d8SChris Lattner using namespace lldb; 4930fdc8d8SChris Lattner using namespace lldb_private; 5030fdc8d8SChris Lattner 51b9c1b51eSKate Stone const char *SBThread::GetBroadcasterClassName() { 524f465cffSJim Ingham return Thread::GetStaticBroadcasterClass().AsCString(); 534f465cffSJim Ingham } 544f465cffSJim Ingham 55cfd1acedSGreg Clayton //---------------------------------------------------------------------- 56cfd1acedSGreg Clayton // Constructors 57cfd1acedSGreg Clayton //---------------------------------------------------------------------- 58b9c1b51eSKate Stone SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {} 5930fdc8d8SChris Lattner 60b9c1b51eSKate Stone SBThread::SBThread(const ThreadSP &lldb_object_sp) 61b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {} 6230fdc8d8SChris Lattner 63b9c1b51eSKate Stone SBThread::SBThread(const SBThread &rhs) 64b9c1b51eSKate Stone : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {} 6530fdc8d8SChris Lattner 6630fdc8d8SChris Lattner //---------------------------------------------------------------------- 67cfd1acedSGreg Clayton // Assignment operator 68cfd1acedSGreg Clayton //---------------------------------------------------------------------- 69cfd1acedSGreg Clayton 70b9c1b51eSKate Stone const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { 71cfd1acedSGreg Clayton if (this != &rhs) 727fdf9ef1SGreg Clayton *m_opaque_sp = *rhs.m_opaque_sp; 73cfd1acedSGreg Clayton return *this; 74cfd1acedSGreg Clayton } 75cfd1acedSGreg Clayton 76cfd1acedSGreg Clayton //---------------------------------------------------------------------- 7730fdc8d8SChris Lattner // Destructor 7830fdc8d8SChris Lattner //---------------------------------------------------------------------- 79b9c1b51eSKate Stone SBThread::~SBThread() {} 8030fdc8d8SChris Lattner 81b9c1b51eSKate Stone lldb::SBQueue SBThread::GetQueue() const { 82b9ffa98cSJason Molenda SBQueue sb_queue; 83b9ffa98cSJason Molenda QueueSP queue_sp; 84bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 85bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 86b9ffa98cSJason Molenda 87b9ffa98cSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 88b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 89b9ffa98cSJason Molenda Process::StopLocker stop_locker; 90b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 91b9ffa98cSJason Molenda queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 92b9c1b51eSKate Stone if (queue_sp) { 93b9ffa98cSJason Molenda sb_queue.SetQueue(queue_sp); 94b9ffa98cSJason Molenda } 95b9c1b51eSKate Stone } else { 96b9ffa98cSJason Molenda if (log) 97358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue() => error: process is running", 98b9ffa98cSJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 99b9ffa98cSJason Molenda } 100b9ffa98cSJason Molenda } 101b9ffa98cSJason Molenda 102b9ffa98cSJason Molenda if (log) 103358cf1eaSGreg Clayton log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)", 104b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), 105b9c1b51eSKate Stone static_cast<void *>(queue_sp.get())); 106b9ffa98cSJason Molenda 107b9ffa98cSJason Molenda return sb_queue; 108b9ffa98cSJason Molenda } 109b9ffa98cSJason Molenda 110b9c1b51eSKate Stone bool SBThread::IsValid() const { 111bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 112bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1137fa7dc36SJim Ingham 1147fa7dc36SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 1157fa7dc36SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 116b9c1b51eSKate Stone if (target && process) { 1177fa7dc36SJim Ingham Process::StopLocker stop_locker; 1187fa7dc36SJim Ingham if (stop_locker.TryLock(&process->GetRunLock())) 1197fdf9ef1SGreg Clayton return m_opaque_sp->GetThreadSP().get() != NULL; 12030fdc8d8SChris Lattner } 1217fa7dc36SJim Ingham // Without a valid target & process, this thread can't be valid. 1227fa7dc36SJim Ingham return false; 1237fa7dc36SJim Ingham } 12430fdc8d8SChris Lattner 125b9c1b51eSKate Stone void SBThread::Clear() { m_opaque_sp->Clear(); } 12648e42549SGreg Clayton 127b9c1b51eSKate Stone StopReason SBThread::GetStopReason() { 1285160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 129ceb6b139SCaroline Tice 130ceb6b139SCaroline Tice StopReason reason = eStopReasonInvalid; 131bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 132bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1334fc6cb9cSJim Ingham 134b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1357fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 136b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13797d5cf05SGreg Clayton return exe_ctx.GetThreadPtr()->GetStopReason(); 138b9c1b51eSKate Stone } else { 139c9858e4dSGreg Clayton if (log) 140b9c1b51eSKate Stone log->Printf( 141b9c1b51eSKate Stone "SBThread(%p)::GetStopReason() => error: process is running", 142324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 143c9858e4dSGreg Clayton } 1447fdf9ef1SGreg Clayton } 145ceb6b139SCaroline Tice 146ceb6b139SCaroline Tice if (log) 147324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReason () => %s", 148324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 149750cd175SCaroline Tice Thread::StopReasonAsCString(reason)); 150ceb6b139SCaroline Tice 151ceb6b139SCaroline Tice return reason; 15230fdc8d8SChris Lattner } 15330fdc8d8SChris Lattner 154b9c1b51eSKate Stone size_t SBThread::GetStopReasonDataCount() { 155bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 156bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1574fc6cb9cSJim Ingham 158b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1597fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 160b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1611ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 162b9c1b51eSKate Stone if (stop_info_sp) { 1634e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 164b9c1b51eSKate Stone switch (reason) { 1654e78f606SGreg Clayton case eStopReasonInvalid: 1664e78f606SGreg Clayton case eStopReasonNone: 1674e78f606SGreg Clayton case eStopReasonTrace: 16890ba8115SGreg Clayton case eStopReasonExec: 1694e78f606SGreg Clayton case eStopReasonPlanComplete: 170f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 171afdf842bSKuba Brecka case eStopReasonInstrumentation: 1724e78f606SGreg Clayton // There is no data for these stop reasons. 1734e78f606SGreg Clayton return 0; 1744e78f606SGreg Clayton 175b9c1b51eSKate Stone case eStopReasonBreakpoint: { 1764e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 177b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 178b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 179b9c1b51eSKate Stone site_id)); 1804e78f606SGreg Clayton if (bp_site_sp) 1814e78f606SGreg Clayton return bp_site_sp->GetNumberOfOwners() * 2; 1824e78f606SGreg Clayton else 1834e78f606SGreg Clayton return 0; // Breakpoint must have cleared itself... 184b9c1b51eSKate Stone } break; 1854e78f606SGreg Clayton 1864e78f606SGreg Clayton case eStopReasonWatchpoint: 187290fa41bSJohnny Chen return 1; 1884e78f606SGreg Clayton 1894e78f606SGreg Clayton case eStopReasonSignal: 1904e78f606SGreg Clayton return 1; 1914e78f606SGreg Clayton 1924e78f606SGreg Clayton case eStopReasonException: 1934e78f606SGreg Clayton return 1; 1944e78f606SGreg Clayton } 1954e78f606SGreg Clayton } 196b9c1b51eSKate Stone } else { 1975160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 198c9858e4dSGreg Clayton if (log) 199b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process " 200b9c1b51eSKate Stone "is running", 201324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 202c9858e4dSGreg Clayton } 2037fdf9ef1SGreg Clayton } 2044e78f606SGreg Clayton return 0; 2054e78f606SGreg Clayton } 2064e78f606SGreg Clayton 207b9c1b51eSKate Stone uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { 208bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 209bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2104fc6cb9cSJim Ingham 211b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 2127fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 213b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 2141ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 2151ac04c30SGreg Clayton StopInfoSP stop_info_sp = thread->GetStopInfo(); 216b9c1b51eSKate Stone if (stop_info_sp) { 2174e78f606SGreg Clayton StopReason reason = stop_info_sp->GetStopReason(); 218b9c1b51eSKate Stone switch (reason) { 2194e78f606SGreg Clayton case eStopReasonInvalid: 2204e78f606SGreg Clayton case eStopReasonNone: 2214e78f606SGreg Clayton case eStopReasonTrace: 22290ba8115SGreg Clayton case eStopReasonExec: 2234e78f606SGreg Clayton case eStopReasonPlanComplete: 224f85defaeSAndrew Kaylor case eStopReasonThreadExiting: 225afdf842bSKuba Brecka case eStopReasonInstrumentation: 2264e78f606SGreg Clayton // There is no data for these stop reasons. 2274e78f606SGreg Clayton return 0; 2284e78f606SGreg Clayton 229b9c1b51eSKate Stone case eStopReasonBreakpoint: { 2304e78f606SGreg Clayton break_id_t site_id = stop_info_sp->GetValue(); 231b9c1b51eSKate Stone lldb::BreakpointSiteSP bp_site_sp( 232b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 233b9c1b51eSKate Stone site_id)); 234b9c1b51eSKate Stone if (bp_site_sp) { 2354e78f606SGreg Clayton uint32_t bp_index = idx / 2; 236b9c1b51eSKate Stone BreakpointLocationSP bp_loc_sp( 237b9c1b51eSKate Stone bp_site_sp->GetOwnerAtIndex(bp_index)); 238b9c1b51eSKate Stone if (bp_loc_sp) { 239b9c1b51eSKate Stone if (idx & 1) { 2404e78f606SGreg Clayton // Odd idx, return the breakpoint location ID 2414e78f606SGreg Clayton return bp_loc_sp->GetID(); 242b9c1b51eSKate Stone } else { 2434e78f606SGreg Clayton // Even idx, return the breakpoint ID 2444e78f606SGreg Clayton return bp_loc_sp->GetBreakpoint().GetID(); 2454e78f606SGreg Clayton } 2464e78f606SGreg Clayton } 2474e78f606SGreg Clayton } 2484e78f606SGreg Clayton return LLDB_INVALID_BREAK_ID; 249b9c1b51eSKate Stone } break; 2504e78f606SGreg Clayton 2514e78f606SGreg Clayton case eStopReasonWatchpoint: 252290fa41bSJohnny Chen return stop_info_sp->GetValue(); 2534e78f606SGreg Clayton 2544e78f606SGreg Clayton case eStopReasonSignal: 2554e78f606SGreg Clayton return stop_info_sp->GetValue(); 2564e78f606SGreg Clayton 2574e78f606SGreg Clayton case eStopReasonException: 2584e78f606SGreg Clayton return stop_info_sp->GetValue(); 2594e78f606SGreg Clayton } 2604e78f606SGreg Clayton } 261b9c1b51eSKate Stone } else { 2625160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 263c9858e4dSGreg Clayton if (log) 264b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: " 265b9c1b51eSKate Stone "process is running", 266324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 267c9858e4dSGreg Clayton } 2687fdf9ef1SGreg Clayton } 2694e78f606SGreg Clayton return 0; 2704e78f606SGreg Clayton } 2714e78f606SGreg Clayton 272b9c1b51eSKate Stone bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { 273afdf842bSKuba Brecka Stream &strm = stream.ref(); 274afdf842bSKuba Brecka 275b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 276b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 277b2e7d28eSJim Ingham 278afdf842bSKuba Brecka if (!exe_ctx.HasThreadScope()) 279afdf842bSKuba Brecka return false; 280afdf842bSKuba Brecka 281afdf842bSKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 282afdf842bSKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 283afdf842bSKuba Brecka if (!info) 284afdf842bSKuba Brecka return false; 285afdf842bSKuba Brecka 286afdf842bSKuba Brecka info->Dump(strm); 287afdf842bSKuba Brecka 288afdf842bSKuba Brecka return true; 289afdf842bSKuba Brecka } 290afdf842bSKuba Brecka 2916a831436SKuba Brecka SBThreadCollection 292b9c1b51eSKate Stone SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { 2936a831436SKuba Brecka ThreadCollectionSP threads; 2946a831436SKuba Brecka threads.reset(new ThreadCollection()); 2956a831436SKuba Brecka 2966a831436SKuba Brecka // We currently only support ThreadSanitizer. 2976a831436SKuba Brecka if (type != eInstrumentationRuntimeTypeThreadSanitizer) 2986a831436SKuba Brecka return threads; 2996a831436SKuba Brecka 300b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 301b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 302b2e7d28eSJim Ingham 3036a831436SKuba Brecka if (!exe_ctx.HasThreadScope()) 3041aad8fb7SKuba Brecka return threads; 3056a831436SKuba Brecka 3066a831436SKuba Brecka ProcessSP process_sp = exe_ctx.GetProcessSP(); 3076a831436SKuba Brecka 3086a831436SKuba Brecka StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3096a831436SKuba Brecka StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3106a831436SKuba Brecka if (!info) 3116a831436SKuba Brecka return threads; 3126a831436SKuba Brecka 313b9c1b51eSKate Stone return process_sp->GetInstrumentationRuntime(type) 314b9c1b51eSKate Stone ->GetBacktracesFromExtendedStopInfo(info); 3156a831436SKuba Brecka } 3166a831436SKuba Brecka 317b9c1b51eSKate Stone size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { 3185160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 319ceb6b139SCaroline Tice 320bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 321bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3224fc6cb9cSJim Ingham 323b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 3247fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 325b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 3267fdf9ef1SGreg Clayton 3271ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 328b9c1b51eSKate Stone if (stop_info_sp) { 329b15bfc75SJim Ingham const char *stop_desc = stop_info_sp->GetDescription(); 330b9c1b51eSKate Stone if (stop_desc) { 331ceb6b139SCaroline Tice if (log) 332b9c1b51eSKate Stone log->Printf( 333b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"", 334b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 33530fdc8d8SChris Lattner if (dst) 33630fdc8d8SChris Lattner return ::snprintf(dst, dst_len, "%s", stop_desc); 337b9c1b51eSKate Stone else { 338b9c1b51eSKate Stone // NULL dst passed in, return the length needed to contain the 339b9c1b51eSKate Stone // description 34030fdc8d8SChris Lattner return ::strlen(stop_desc) + 1; // Include the NULL byte for size 34130fdc8d8SChris Lattner } 342b9c1b51eSKate Stone } else { 34330fdc8d8SChris Lattner size_t stop_desc_len = 0; 344b9c1b51eSKate Stone switch (stop_info_sp->GetStopReason()) { 34530fdc8d8SChris Lattner case eStopReasonTrace: 346b9c1b51eSKate Stone case eStopReasonPlanComplete: { 34730fdc8d8SChris Lattner static char trace_desc[] = "step"; 34830fdc8d8SChris Lattner stop_desc = trace_desc; 349b9c1b51eSKate Stone stop_desc_len = 350b9c1b51eSKate Stone sizeof(trace_desc); // Include the NULL byte for size 351b9c1b51eSKate Stone } break; 35230fdc8d8SChris Lattner 353b9c1b51eSKate Stone case eStopReasonBreakpoint: { 35430fdc8d8SChris Lattner static char bp_desc[] = "breakpoint hit"; 35530fdc8d8SChris Lattner stop_desc = bp_desc; 35630fdc8d8SChris Lattner stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size 357b9c1b51eSKate Stone } break; 35830fdc8d8SChris Lattner 359b9c1b51eSKate Stone case eStopReasonWatchpoint: { 36030fdc8d8SChris Lattner static char wp_desc[] = "watchpoint hit"; 36130fdc8d8SChris Lattner stop_desc = wp_desc; 36230fdc8d8SChris Lattner stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size 363b9c1b51eSKate Stone } break; 36430fdc8d8SChris Lattner 365b9c1b51eSKate Stone case eStopReasonSignal: { 366b9c1b51eSKate Stone stop_desc = 367b9c1b51eSKate Stone exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString( 368b9c1b51eSKate Stone stop_info_sp->GetValue()); 369b9c1b51eSKate Stone if (stop_desc == NULL || stop_desc[0] == '\0') { 37030fdc8d8SChris Lattner static char signal_desc[] = "signal"; 37130fdc8d8SChris Lattner stop_desc = signal_desc; 372b9c1b51eSKate Stone stop_desc_len = 373b9c1b51eSKate Stone sizeof(signal_desc); // Include the NULL byte for size 37430fdc8d8SChris Lattner } 375b9c1b51eSKate Stone } break; 37630fdc8d8SChris Lattner 377b9c1b51eSKate Stone case eStopReasonException: { 37830fdc8d8SChris Lattner char exc_desc[] = "exception"; 37930fdc8d8SChris Lattner stop_desc = exc_desc; 38030fdc8d8SChris Lattner stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 381b9c1b51eSKate Stone } break; 382c982c768SGreg Clayton 383b9c1b51eSKate Stone case eStopReasonExec: { 38490ba8115SGreg Clayton char exc_desc[] = "exec"; 38590ba8115SGreg Clayton stop_desc = exc_desc; 38690ba8115SGreg Clayton stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size 387b9c1b51eSKate Stone } break; 38890ba8115SGreg Clayton 389b9c1b51eSKate Stone case eStopReasonThreadExiting: { 390f85defaeSAndrew Kaylor char limbo_desc[] = "thread exiting"; 391f85defaeSAndrew Kaylor stop_desc = limbo_desc; 392f85defaeSAndrew Kaylor stop_desc_len = sizeof(limbo_desc); 393b9c1b51eSKate Stone } break; 394c982c768SGreg Clayton default: 395c982c768SGreg Clayton break; 39630fdc8d8SChris Lattner } 39730fdc8d8SChris Lattner 398b9c1b51eSKate Stone if (stop_desc && stop_desc[0]) { 399ceb6b139SCaroline Tice if (log) 400b9c1b51eSKate Stone log->Printf( 401b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'", 402b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc); 403ceb6b139SCaroline Tice 40430fdc8d8SChris Lattner if (dst) 405b9c1b51eSKate Stone return ::snprintf(dst, dst_len, "%s", stop_desc) + 406b9c1b51eSKate Stone 1; // Include the NULL byte 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner if (stop_desc_len == 0) 40930fdc8d8SChris Lattner stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte 41030fdc8d8SChris Lattner 41130fdc8d8SChris Lattner return stop_desc_len; 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner } 41430fdc8d8SChris Lattner } 415b9c1b51eSKate Stone } else { 4165160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 417c9858e4dSGreg Clayton if (log) 418b9c1b51eSKate Stone log->Printf( 419b9c1b51eSKate Stone "SBThread(%p)::GetStopDescription() => error: process is running", 420324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 421c9858e4dSGreg Clayton } 4227fdf9ef1SGreg Clayton } 42330fdc8d8SChris Lattner if (dst) 42430fdc8d8SChris Lattner *dst = 0; 42530fdc8d8SChris Lattner return 0; 42630fdc8d8SChris Lattner } 42730fdc8d8SChris Lattner 428b9c1b51eSKate Stone SBValue SBThread::GetStopReturnValue() { 4295160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 43073ca05a2SJim Ingham ValueObjectSP return_valobj_sp; 431bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 432bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4334fc6cb9cSJim Ingham 434b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4357fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 436b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4371ac04c30SGreg Clayton StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 438b9c1b51eSKate Stone if (stop_info_sp) { 43973ca05a2SJim Ingham return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); 44073ca05a2SJim Ingham } 441b9c1b51eSKate Stone } else { 442c9858e4dSGreg Clayton if (log) 443b9c1b51eSKate Stone log->Printf( 444b9c1b51eSKate Stone "SBThread(%p)::GetStopReturnValue() => error: process is running", 445324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 446c9858e4dSGreg Clayton } 4477fdf9ef1SGreg Clayton } 44873ca05a2SJim Ingham 44973ca05a2SJim Ingham if (log) 450324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetStopReturnValue () => %s", 451324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 452b9c1b51eSKate Stone return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString() 45373ca05a2SJim Ingham : "<no return value>"); 45473ca05a2SJim Ingham 45573ca05a2SJim Ingham return SBValue(return_valobj_sp); 45673ca05a2SJim Ingham } 45773ca05a2SJim Ingham 458b9c1b51eSKate Stone void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 4597fdf9ef1SGreg Clayton m_opaque_sp->SetThreadSP(lldb_object_sp); 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner 462b9c1b51eSKate Stone lldb::tid_t SBThread::GetThreadID() const { 4637fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 46417a6ad05SGreg Clayton if (thread_sp) 4651ac04c30SGreg Clayton return thread_sp->GetID(); 4661ac04c30SGreg Clayton return LLDB_INVALID_THREAD_ID; 46730fdc8d8SChris Lattner } 46830fdc8d8SChris Lattner 469b9c1b51eSKate Stone uint32_t SBThread::GetIndexID() const { 4707fdf9ef1SGreg Clayton ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 47117a6ad05SGreg Clayton if (thread_sp) 47217a6ad05SGreg Clayton return thread_sp->GetIndexID(); 47330fdc8d8SChris Lattner return LLDB_INVALID_INDEX32; 47430fdc8d8SChris Lattner } 4751ac04c30SGreg Clayton 476b9c1b51eSKate Stone const char *SBThread::GetName() const { 4775160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 4784838131bSGreg Clayton const char *name = NULL; 479bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 480bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4814fc6cb9cSJim Ingham 482b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 4837fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 484b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4851ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetName(); 486b9c1b51eSKate Stone } else { 487c9858e4dSGreg Clayton if (log) 488324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName() => error: process is running", 489324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 490c9858e4dSGreg Clayton } 4917fdf9ef1SGreg Clayton } 492ceb6b139SCaroline Tice 493ceb6b139SCaroline Tice if (log) 494324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetName () => %s", 495324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 496324a1036SSaleem Abdulrasool name ? name : "NULL"); 497ceb6b139SCaroline Tice 4984838131bSGreg Clayton return name; 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner 501b9c1b51eSKate Stone const char *SBThread::GetQueueName() const { 5024838131bSGreg Clayton const char *name = NULL; 503bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 504bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5054fc6cb9cSJim Ingham 5065160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 507b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5087fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 509b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5101ac04c30SGreg Clayton name = exe_ctx.GetThreadPtr()->GetQueueName(); 511b9c1b51eSKate Stone } else { 512c9858e4dSGreg Clayton if (log) 513324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName() => error: process is running", 514324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 515c9858e4dSGreg Clayton } 5167fdf9ef1SGreg Clayton } 517ceb6b139SCaroline Tice 518ceb6b139SCaroline Tice if (log) 519324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueName () => %s", 520324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 521324a1036SSaleem Abdulrasool name ? name : "NULL"); 522ceb6b139SCaroline Tice 5234838131bSGreg Clayton return name; 52430fdc8d8SChris Lattner } 52530fdc8d8SChris Lattner 526b9c1b51eSKate Stone lldb::queue_id_t SBThread::GetQueueID() const { 5274fdb5863SJason Molenda queue_id_t id = LLDB_INVALID_QUEUE_ID; 528bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 529bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5304fdb5863SJason Molenda 5314fdb5863SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 532b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 5334fdb5863SJason Molenda Process::StopLocker stop_locker; 534b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 5354fdb5863SJason Molenda id = exe_ctx.GetThreadPtr()->GetQueueID(); 536b9c1b51eSKate Stone } else { 5374fdb5863SJason Molenda if (log) 538324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID() => error: process is running", 539324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 5404fdb5863SJason Molenda } 5414fdb5863SJason Molenda } 5424fdb5863SJason Molenda 5434fdb5863SJason Molenda if (log) 544324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64, 545324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), id); 5464fdb5863SJason Molenda 5474fdb5863SJason Molenda return id; 5484fdb5863SJason Molenda } 5494fdb5863SJason Molenda 550b9c1b51eSKate Stone bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 551705b1809SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 552705b1809SJason Molenda bool success = false; 553bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 554bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 555705b1809SJason Molenda 556b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 557705b1809SJason Molenda Process::StopLocker stop_locker; 558b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 559705b1809SJason Molenda Thread *thread = exe_ctx.GetThreadPtr(); 560705b1809SJason Molenda StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 561b9c1b51eSKate Stone if (info_root_sp) { 562b9c1b51eSKate Stone StructuredData::ObjectSP node = 563b9c1b51eSKate Stone info_root_sp->GetObjectForDotSeparatedPath(path); 564b9c1b51eSKate Stone if (node) { 565*5bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeString) { 5662833321fSZachary Turner strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); 567705b1809SJason Molenda success = true; 568705b1809SJason Molenda } 569*5bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeInteger) { 570705b1809SJason Molenda strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 571705b1809SJason Molenda success = true; 572705b1809SJason Molenda } 573*5bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeFloat) { 574705b1809SJason Molenda strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 575705b1809SJason Molenda success = true; 576705b1809SJason Molenda } 577*5bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeBoolean) { 578705b1809SJason Molenda if (node->GetAsBoolean()->GetValue() == true) 579705b1809SJason Molenda strm.Printf("true"); 580705b1809SJason Molenda else 581705b1809SJason Molenda strm.Printf("false"); 582705b1809SJason Molenda success = true; 583705b1809SJason Molenda } 584*5bfee5f1SAbhishek Aggarwal if (node->GetType() == eStructuredDataTypeNull) { 585705b1809SJason Molenda strm.Printf("null"); 586705b1809SJason Molenda success = true; 587705b1809SJason Molenda } 588705b1809SJason Molenda } 589705b1809SJason Molenda } 590b9c1b51eSKate Stone } else { 591705b1809SJason Molenda if (log) 592b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: " 593b9c1b51eSKate Stone "process is running", 594705b1809SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr())); 595705b1809SJason Molenda } 596705b1809SJason Molenda } 597705b1809SJason Molenda 598705b1809SJason Molenda if (log) 599753e13c0SJason Molenda log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"", 600753e13c0SJason Molenda static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData()); 601705b1809SJason Molenda 602705b1809SJason Molenda return success; 603705b1809SJason Molenda } 604705b1809SJason Molenda 605b9c1b51eSKate Stone SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 606b9c1b51eSKate Stone ThreadPlan *new_plan) { 60764e7ead1SJim Ingham SBError sb_error; 60864e7ead1SJim Ingham 60964e7ead1SJim Ingham Process *process = exe_ctx.GetProcessPtr(); 610b9c1b51eSKate Stone if (!process) { 61164e7ead1SJim Ingham sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 61264e7ead1SJim Ingham return sb_error; 61364e7ead1SJim Ingham } 61464e7ead1SJim Ingham 61564e7ead1SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 616b9c1b51eSKate Stone if (!thread) { 61764e7ead1SJim Ingham sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 61864e7ead1SJim Ingham return sb_error; 61964e7ead1SJim Ingham } 62064e7ead1SJim Ingham 621b9c1b51eSKate Stone // User level plans should be Master Plans so they can be interrupted, other 622b9c1b51eSKate Stone // plans executed, and 62364e7ead1SJim Ingham // then a "continue" will resume the plan. 624b9c1b51eSKate Stone if (new_plan != NULL) { 62564e7ead1SJim Ingham new_plan->SetIsMasterPlan(true); 62664e7ead1SJim Ingham new_plan->SetOkayToDiscard(false); 62764e7ead1SJim Ingham } 62864e7ead1SJim Ingham 62964e7ead1SJim Ingham // Why do we need to set the current thread by ID here??? 63064e7ead1SJim Ingham process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 63164e7ead1SJim Ingham 632dc6224e0SGreg Clayton if (process->GetTarget().GetDebugger().GetAsyncExecution()) 633dc6224e0SGreg Clayton sb_error.ref() = process->Resume(); 634dc6224e0SGreg Clayton else 635dc6224e0SGreg Clayton sb_error.ref() = process->ResumeSynchronous(NULL); 63664e7ead1SJim Ingham 63764e7ead1SJim Ingham return sb_error; 63864e7ead1SJim Ingham } 63930fdc8d8SChris Lattner 640b9c1b51eSKate Stone void SBThread::StepOver(lldb::RunMode stop_other_threads) { 6415160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 642ceb6b139SCaroline Tice 643bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 644bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 64517a6ad05SGreg Clayton 646ceb6b139SCaroline Tice if (log) 647324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')", 648324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 649ceb6b139SCaroline Tice Thread::RunModeAsCString(stop_other_threads)); 650ceb6b139SCaroline Tice 651b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 6521ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 6537ba6e991SJim Ingham bool abort_other_plans = false; 654b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 65530fdc8d8SChris Lattner 6564d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 657b9c1b51eSKate Stone if (frame_sp) { 658b9c1b51eSKate Stone if (frame_sp->HasDebugInformation()) { 6594b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 66030fdc8d8SChris Lattner SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 661b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepOverRange( 662b9c1b51eSKate Stone abort_other_plans, sc.line_entry, sc, stop_other_threads, 6634b4b2478SJim Ingham avoid_no_debug); 664b9c1b51eSKate Stone } else { 665b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 666b9c1b51eSKate Stone true, abort_other_plans, stop_other_threads); 66730fdc8d8SChris Lattner } 66830fdc8d8SChris Lattner } 66930fdc8d8SChris Lattner 67064e7ead1SJim Ingham // This returns an error, we should use it! 6714d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 67230fdc8d8SChris Lattner } 67330fdc8d8SChris Lattner } 67430fdc8d8SChris Lattner 675b9c1b51eSKate Stone void SBThread::StepInto(lldb::RunMode stop_other_threads) { 676c627682eSJim Ingham StepInto(NULL, stop_other_threads); 677c627682eSJim Ingham } 678c627682eSJim Ingham 679b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, 680b9c1b51eSKate Stone lldb::RunMode stop_other_threads) { 681cbf6f9b2SJim Ingham SBError error; 682cbf6f9b2SJim Ingham StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 683cbf6f9b2SJim Ingham } 684cbf6f9b2SJim Ingham 685b9c1b51eSKate Stone void SBThread::StepInto(const char *target_name, uint32_t end_line, 686b9c1b51eSKate Stone SBError &error, lldb::RunMode stop_other_threads) { 6875160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 688ceb6b139SCaroline Tice 689bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 690bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 69117a6ad05SGreg Clayton 69217a6ad05SGreg Clayton if (log) 693b9c1b51eSKate Stone log->Printf( 694b9c1b51eSKate Stone "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')", 695324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 696c627682eSJim Ingham target_name ? target_name : "<NULL>", 69717a6ad05SGreg Clayton Thread::RunModeAsCString(stop_other_threads)); 698c627682eSJim Ingham 699b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 7007ba6e991SJim Ingham bool abort_other_plans = false; 70130fdc8d8SChris Lattner 7021ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 703b57e4a1bSJason Molenda StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 7044d56e9c1SJim Ingham ThreadPlanSP new_plan_sp; 70530fdc8d8SChris Lattner 706b9c1b51eSKate Stone if (frame_sp && frame_sp->HasDebugInformation()) { 707cbf6f9b2SJim Ingham SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 708cbf6f9b2SJim Ingham AddressRange range; 709cbf6f9b2SJim Ingham if (end_line == LLDB_INVALID_LINE_NUMBER) 710cbf6f9b2SJim Ingham range = sc.line_entry.range; 711b9c1b51eSKate Stone else { 712cbf6f9b2SJim Ingham if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 713cbf6f9b2SJim Ingham return; 714cbf6f9b2SJim Ingham } 715cbf6f9b2SJim Ingham 716b9c1b51eSKate Stone const LazyBool step_out_avoids_code_without_debug_info = 717b9c1b51eSKate Stone eLazyBoolCalculate; 718b9c1b51eSKate Stone const LazyBool step_in_avoids_code_without_debug_info = 719b9c1b51eSKate Stone eLazyBoolCalculate; 720b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepInRange( 721b9c1b51eSKate Stone abort_other_plans, range, sc, target_name, stop_other_threads, 7224b4b2478SJim Ingham step_in_avoids_code_without_debug_info, 7234b4b2478SJim Ingham step_out_avoids_code_without_debug_info); 724b9c1b51eSKate Stone } else { 725b9c1b51eSKate Stone new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 726b9c1b51eSKate Stone false, abort_other_plans, stop_other_threads); 72730fdc8d8SChris Lattner } 72830fdc8d8SChris Lattner 729cbf6f9b2SJim Ingham error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 73030fdc8d8SChris Lattner } 73130fdc8d8SChris Lattner } 73230fdc8d8SChris Lattner 733b9c1b51eSKate Stone void SBThread::StepOut() { 7345160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 735ceb6b139SCaroline Tice 736bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 737bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7384fc6cb9cSJim Ingham 73917a6ad05SGreg Clayton if (log) 740324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOut ()", 741324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 74217a6ad05SGreg Clayton 743b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 7447ba6e991SJim Ingham bool abort_other_plans = false; 74594b09246SJim Ingham bool stop_other_threads = false; 74630fdc8d8SChris Lattner 7471ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 7481ac04c30SGreg Clayton 7494b4b2478SJim Ingham const LazyBool avoid_no_debug = eLazyBoolCalculate; 750b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 751b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 752b9c1b51eSKate Stone eVoteNoOpinion, 0, avoid_no_debug)); 753481cef25SGreg Clayton 75464e7ead1SJim Ingham // This returns an error, we should use it! 7554d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 756481cef25SGreg Clayton } 757481cef25SGreg Clayton } 758481cef25SGreg Clayton 759b9c1b51eSKate Stone void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) { 7605160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 761481cef25SGreg Clayton 762bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 763bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7644fc6cb9cSJim Ingham 765b9c1b51eSKate Stone if (!sb_frame.IsValid()) { 766989a7558SJim Ingham if (log) 767b9c1b51eSKate Stone log->Printf( 768b9c1b51eSKate Stone "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.", 769989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 770989a7558SJim Ingham return; 771989a7558SJim Ingham } 772989a7558SJim Ingham 773b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 774b9c1b51eSKate Stone if (log) { 775481cef25SGreg Clayton SBStream frame_desc_strm; 776481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 777324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", 778324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 779b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 780481cef25SGreg Clayton } 781481cef25SGreg Clayton 782b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 7837ba6e991SJim Ingham bool abort_other_plans = false; 78494b09246SJim Ingham bool stop_other_threads = false; 7851ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 786b9c1b51eSKate Stone if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 787b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another " 788b9c1b51eSKate Stone "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.", 789989a7558SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 790b9c1b51eSKate Stone sb_frame.GetThread().GetThreadID(), thread->GetID()); 791989a7558SJim Ingham } 792481cef25SGreg Clayton 793b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 794b9c1b51eSKate Stone abort_other_plans, NULL, false, stop_other_threads, eVoteYes, 795b9c1b51eSKate Stone eVoteNoOpinion, frame_sp->GetFrameIndex())); 79630fdc8d8SChris Lattner 79764e7ead1SJim Ingham // This returns an error, we should use it! 7984d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 79930fdc8d8SChris Lattner } 80030fdc8d8SChris Lattner } 80130fdc8d8SChris Lattner 802b9c1b51eSKate Stone void SBThread::StepInstruction(bool step_over) { 8035160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 804ceb6b139SCaroline Tice 805bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 806bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 807ceb6b139SCaroline Tice 80817a6ad05SGreg Clayton if (log) 809324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::StepInstruction (step_over=%i)", 810324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), step_over); 81117a6ad05SGreg Clayton 812b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8131ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 814b9c1b51eSKate Stone ThreadPlanSP new_plan_sp( 815b9c1b51eSKate Stone thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true)); 81664e7ead1SJim Ingham 81764e7ead1SJim Ingham // This returns an error, we should use it! 8184d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 81930fdc8d8SChris Lattner } 82030fdc8d8SChris Lattner } 82130fdc8d8SChris Lattner 822b9c1b51eSKate Stone void SBThread::RunToAddress(lldb::addr_t addr) { 8235160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 824ceb6b139SCaroline Tice 825bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 826bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 827ceb6b139SCaroline Tice 82817a6ad05SGreg Clayton if (log) 829324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", 830324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), addr); 83117a6ad05SGreg Clayton 832b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8337ba6e991SJim Ingham bool abort_other_plans = false; 83430fdc8d8SChris Lattner bool stop_other_threads = true; 83530fdc8d8SChris Lattner 836e72dfb32SGreg Clayton Address target_addr(addr); 83730fdc8d8SChris Lattner 8381ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 8391ac04c30SGreg Clayton 840b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 841b9c1b51eSKate Stone abort_other_plans, target_addr, stop_other_threads)); 84264e7ead1SJim Ingham 84364e7ead1SJim Ingham // This returns an error, we should use it! 8444d56e9c1SJim Ingham ResumeNewPlan(exe_ctx, new_plan_sp.get()); 84530fdc8d8SChris Lattner } 84630fdc8d8SChris Lattner } 84730fdc8d8SChris Lattner 848b9c1b51eSKate Stone SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 849b9c1b51eSKate Stone lldb::SBFileSpec &sb_file_spec, uint32_t line) { 850481cef25SGreg Clayton SBError sb_error; 8515160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 852481cef25SGreg Clayton char path[PATH_MAX]; 853481cef25SGreg Clayton 854bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 855bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 8564fc6cb9cSJim Ingham 857b57e4a1bSJason Molenda StackFrameSP frame_sp(sb_frame.GetFrameSP()); 85817a6ad05SGreg Clayton 859b9c1b51eSKate Stone if (log) { 860481cef25SGreg Clayton SBStream frame_desc_strm; 861481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 862481cef25SGreg Clayton sb_file_spec->GetPath(path, sizeof(path)); 863b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, " 864b9c1b51eSKate Stone "file+line = %s:%u)", 865324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 866b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(), 867b9c1b51eSKate Stone path, line); 868481cef25SGreg Clayton } 869481cef25SGreg Clayton 870b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 8711ac04c30SGreg Clayton Target *target = exe_ctx.GetTargetPtr(); 8721ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 873481cef25SGreg Clayton 874b9c1b51eSKate Stone if (line == 0) { 875481cef25SGreg Clayton sb_error.SetErrorString("invalid line argument"); 876481cef25SGreg Clayton return sb_error; 877481cef25SGreg Clayton } 878481cef25SGreg Clayton 879b9c1b51eSKate Stone if (!frame_sp) { 8801ac04c30SGreg Clayton frame_sp = thread->GetSelectedFrame(); 881481cef25SGreg Clayton if (!frame_sp) 8821ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(0); 883481cef25SGreg Clayton } 884481cef25SGreg Clayton 885481cef25SGreg Clayton SymbolContext frame_sc; 886b9c1b51eSKate Stone if (!frame_sp) { 887481cef25SGreg Clayton sb_error.SetErrorString("no valid frames in thread to step"); 888481cef25SGreg Clayton return sb_error; 889481cef25SGreg Clayton } 890481cef25SGreg Clayton 891481cef25SGreg Clayton // If we have a frame, get its line 892b9c1b51eSKate Stone frame_sc = frame_sp->GetSymbolContext( 893b9c1b51eSKate Stone eSymbolContextCompUnit | eSymbolContextFunction | 894b9c1b51eSKate Stone eSymbolContextLineEntry | eSymbolContextSymbol); 895481cef25SGreg Clayton 896b9c1b51eSKate Stone if (frame_sc.comp_unit == NULL) { 897b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 898b9c1b51eSKate Stone "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 899481cef25SGreg Clayton return sb_error; 900481cef25SGreg Clayton } 901481cef25SGreg Clayton 902481cef25SGreg Clayton FileSpec step_file_spec; 903b9c1b51eSKate Stone if (sb_file_spec.IsValid()) { 904481cef25SGreg Clayton // The file spec passed in was valid, so use it 905481cef25SGreg Clayton step_file_spec = sb_file_spec.ref(); 906b9c1b51eSKate Stone } else { 907481cef25SGreg Clayton if (frame_sc.line_entry.IsValid()) 908481cef25SGreg Clayton step_file_spec = frame_sc.line_entry.file; 909b9c1b51eSKate Stone else { 910481cef25SGreg Clayton sb_error.SetErrorString("invalid file argument or no file for frame"); 911481cef25SGreg Clayton return sb_error; 912481cef25SGreg Clayton } 913481cef25SGreg Clayton } 914481cef25SGreg Clayton 9159b70ddb3SJim Ingham // Grab the current function, then we will make sure the "until" address is 9169b70ddb3SJim Ingham // within the function. We discard addresses that are out of the current 917b9c1b51eSKate Stone // function, and then if there are no addresses remaining, give an 918b9c1b51eSKate Stone // appropriate 9199b70ddb3SJim Ingham // error message. 9209b70ddb3SJim Ingham 9219b70ddb3SJim Ingham bool all_in_function = true; 9229b70ddb3SJim Ingham AddressRange fun_range = frame_sc.function->GetAddressRange(); 9239b70ddb3SJim Ingham 924481cef25SGreg Clayton std::vector<addr_t> step_over_until_addrs; 9257ba6e991SJim Ingham const bool abort_other_plans = false; 926c02e3344SJim Ingham const bool stop_other_threads = false; 927481cef25SGreg Clayton const bool check_inlines = true; 928481cef25SGreg Clayton const bool exact = false; 929481cef25SGreg Clayton 930481cef25SGreg Clayton SymbolContextList sc_list; 931b9c1b51eSKate Stone const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext( 932b9c1b51eSKate Stone step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry, 9339b70ddb3SJim Ingham sc_list); 934b9c1b51eSKate Stone if (num_matches > 0) { 935481cef25SGreg Clayton SymbolContext sc; 936b9c1b51eSKate Stone for (uint32_t i = 0; i < num_matches; ++i) { 937b9c1b51eSKate Stone if (sc_list.GetContextAtIndex(i, sc)) { 938b9c1b51eSKate Stone addr_t step_addr = 939b9c1b51eSKate Stone sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 940b9c1b51eSKate Stone if (step_addr != LLDB_INVALID_ADDRESS) { 9419b70ddb3SJim Ingham if (fun_range.ContainsLoadAddress(step_addr, target)) 942481cef25SGreg Clayton step_over_until_addrs.push_back(step_addr); 9439b70ddb3SJim Ingham else 9449b70ddb3SJim Ingham all_in_function = false; 945481cef25SGreg Clayton } 946481cef25SGreg Clayton } 947481cef25SGreg Clayton } 948481cef25SGreg Clayton } 949481cef25SGreg Clayton 950b9c1b51eSKate Stone if (step_over_until_addrs.empty()) { 951b9c1b51eSKate Stone if (all_in_function) { 952481cef25SGreg Clayton step_file_spec.GetPath(path, sizeof(path)); 953b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 954b9c1b51eSKate Stone line); 955b9c1b51eSKate Stone } else 95686edbf41SGreg Clayton sb_error.SetErrorString("step until target not in current function"); 957b9c1b51eSKate Stone } else { 958b9c1b51eSKate Stone ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 959b9c1b51eSKate Stone abort_other_plans, &step_over_until_addrs[0], 960b9c1b51eSKate Stone step_over_until_addrs.size(), stop_other_threads, 9614d56e9c1SJim Ingham frame_sp->GetFrameIndex())); 962481cef25SGreg Clayton 9634d56e9c1SJim Ingham sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 964481cef25SGreg Clayton } 965b9c1b51eSKate Stone } else { 966481cef25SGreg Clayton sb_error.SetErrorString("this SBThread object is invalid"); 967481cef25SGreg Clayton } 968481cef25SGreg Clayton return sb_error; 969481cef25SGreg Clayton } 970481cef25SGreg Clayton 971b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 972000ca185SOleksiy Vyalov return StepUsingScriptedThreadPlan(script_class_name, true); 973c915a7d2SJim Ingham } 974c915a7d2SJim Ingham 975b9c1b51eSKate Stone SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 976b9c1b51eSKate Stone bool resume_immediately) { 9772bdbfd50SJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 9782bdbfd50SJim Ingham SBError sb_error; 9792bdbfd50SJim Ingham 980bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 981bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9822bdbfd50SJim Ingham 983b9c1b51eSKate Stone if (log) { 9842bdbfd50SJim Ingham log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s", 985b9c1b51eSKate Stone static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name); 9862bdbfd50SJim Ingham } 9872bdbfd50SJim Ingham 988b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 9892bdbfd50SJim Ingham sb_error.SetErrorString("this SBThread object is invalid"); 9902bdbfd50SJim Ingham return sb_error; 9912bdbfd50SJim Ingham } 9922bdbfd50SJim Ingham 9932bdbfd50SJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 994b9c1b51eSKate Stone ThreadPlanSP thread_plan_sp = 995b9c1b51eSKate Stone thread->QueueThreadPlanForStepScripted(false, script_class_name, false); 9962bdbfd50SJim Ingham 997b9c1b51eSKate Stone if (!thread_plan_sp) { 998b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 999b9c1b51eSKate Stone "Error queueing thread plan for class: %s", script_class_name); 1000c915a7d2SJim Ingham return sb_error; 1001c915a7d2SJim Ingham } 1002c915a7d2SJim Ingham 1003b9c1b51eSKate Stone if (!resume_immediately) { 1004c915a7d2SJim Ingham return sb_error; 1005c915a7d2SJim Ingham } 1006c915a7d2SJim Ingham 10072bdbfd50SJim Ingham if (thread_plan_sp) 10082bdbfd50SJim Ingham sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); 1009b9c1b51eSKate Stone else { 1010b9c1b51eSKate Stone sb_error.SetErrorStringWithFormat( 1011b9c1b51eSKate Stone "Error resuming thread plan for class: %s.", script_class_name); 10122bdbfd50SJim Ingham if (log) 1013b9c1b51eSKate Stone log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing " 1014b9c1b51eSKate Stone "thread plan for class: %s", 10152bdbfd50SJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr()), 10162bdbfd50SJim Ingham script_class_name); 10172bdbfd50SJim Ingham } 10182bdbfd50SJim Ingham 10192bdbfd50SJim Ingham return sb_error; 10202bdbfd50SJim Ingham } 10212bdbfd50SJim Ingham 1022b9c1b51eSKate Stone SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 1023f86248d9SRichard Mitton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1024f86248d9SRichard Mitton SBError sb_error; 1025f86248d9SRichard Mitton 1026bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1027bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1028f86248d9SRichard Mitton 1029f86248d9SRichard Mitton if (log) 1030324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)", 1031324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1032324a1036SSaleem Abdulrasool file_spec->GetPath().c_str(), line); 1033f86248d9SRichard Mitton 1034b9c1b51eSKate Stone if (!exe_ctx.HasThreadScope()) { 1035f86248d9SRichard Mitton sb_error.SetErrorString("this SBThread object is invalid"); 1036f86248d9SRichard Mitton return sb_error; 1037f86248d9SRichard Mitton } 1038f86248d9SRichard Mitton 1039f86248d9SRichard Mitton Thread *thread = exe_ctx.GetThreadPtr(); 1040f86248d9SRichard Mitton 104197206d57SZachary Turner Status err = thread->JumpToLine(file_spec.get(), line, true); 1042f86248d9SRichard Mitton sb_error.SetError(err); 1043f86248d9SRichard Mitton return sb_error; 1044f86248d9SRichard Mitton } 1045f86248d9SRichard Mitton 1046b9c1b51eSKate Stone SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 10474413758cSJim Ingham SBError sb_error; 10484413758cSJim Ingham 10495160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 10504413758cSJim Ingham 1051bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1052bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10534413758cSJim Ingham 10544413758cSJim Ingham if (log) 1055324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)", 1056324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1057324a1036SSaleem Abdulrasool frame.GetFrameID()); 10584413758cSJim Ingham 1059b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 10604413758cSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 1061b9c1b51eSKate Stone sb_error.SetError( 1062b9c1b51eSKate Stone thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 10634413758cSJim Ingham } 10644413758cSJim Ingham 10654413758cSJim Ingham return sb_error; 10664413758cSJim Ingham } 10674413758cSJim Ingham 1068b9c1b51eSKate Stone SBError SBThread::UnwindInnermostExpression() { 10694ac8e93aSJim Ingham SBError sb_error; 10704ac8e93aSJim Ingham 10714ac8e93aSJim Ingham Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 10724ac8e93aSJim Ingham 10734ac8e93aSJim Ingham std::unique_lock<std::recursive_mutex> lock; 10744ac8e93aSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10754ac8e93aSJim Ingham 10764ac8e93aSJim Ingham if (log) 10774ac8e93aSJim Ingham log->Printf("SBThread(%p)::UnwindExpressionEvaluation", 10784ac8e93aSJim Ingham static_cast<void *>(exe_ctx.GetThreadPtr())); 10794ac8e93aSJim Ingham 1080b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 10814ac8e93aSJim Ingham Thread *thread = exe_ctx.GetThreadPtr(); 10824ac8e93aSJim Ingham sb_error.SetError(thread->UnwindInnermostExpression()); 10834ac8e93aSJim Ingham if (sb_error.Success()) 10844ac8e93aSJim Ingham thread->SetSelectedFrameByIndex(0, false); 10854ac8e93aSJim Ingham } 10864ac8e93aSJim Ingham 10874ac8e93aSJim Ingham return sb_error; 10884ac8e93aSJim Ingham } 1089481cef25SGreg Clayton 1090b9c1b51eSKate Stone bool SBThread::Suspend() { 10915160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1092b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1093b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1094b2e7d28eSJim Ingham 1095c9858e4dSGreg Clayton bool result = false; 1096b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1097c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1098b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 10991ac04c30SGreg Clayton exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 1100c9858e4dSGreg Clayton result = true; 1101b9c1b51eSKate Stone } else { 1102c9858e4dSGreg Clayton if (log) 1103324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => error: process is running", 1104324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1105c9858e4dSGreg Clayton } 1106c9858e4dSGreg Clayton } 1107c9858e4dSGreg Clayton if (log) 1108324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Suspend() => %i", 1109324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1110c9858e4dSGreg Clayton return result; 1111722a0cdcSGreg Clayton } 1112722a0cdcSGreg Clayton 1113b9c1b51eSKate Stone bool SBThread::Resume() { 11145160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1115b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1116b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1117b2e7d28eSJim Ingham 1118c9858e4dSGreg Clayton bool result = false; 1119b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1120c9858e4dSGreg Clayton Process::StopLocker stop_locker; 1121b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11226c9ed91cSJim Ingham const bool override_suspend = true; 11236c9ed91cSJim Ingham exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 1124c9858e4dSGreg Clayton result = true; 1125b9c1b51eSKate Stone } else { 1126c9858e4dSGreg Clayton if (log) 1127324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => error: process is running", 1128324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1129c9858e4dSGreg Clayton } 1130c9858e4dSGreg Clayton } 1131c9858e4dSGreg Clayton if (log) 1132324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::Resume() => %i", 1133324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), result); 1134c9858e4dSGreg Clayton return result; 1135722a0cdcSGreg Clayton } 1136722a0cdcSGreg Clayton 1137b9c1b51eSKate Stone bool SBThread::IsSuspended() { 1138b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1139b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1140b2e7d28eSJim Ingham 11411ac04c30SGreg Clayton if (exe_ctx.HasThreadScope()) 11421ac04c30SGreg Clayton return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 1143722a0cdcSGreg Clayton return false; 1144722a0cdcSGreg Clayton } 1145722a0cdcSGreg Clayton 1146b9c1b51eSKate Stone bool SBThread::IsStopped() { 1147b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1148b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1149b2e7d28eSJim Ingham 1150a75418dbSAndrew Kaylor if (exe_ctx.HasThreadScope()) 1151a75418dbSAndrew Kaylor return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 1152a75418dbSAndrew Kaylor return false; 1153a75418dbSAndrew Kaylor } 1154a75418dbSAndrew Kaylor 1155b9c1b51eSKate Stone SBProcess SBThread::GetProcess() { 1156b9556accSGreg Clayton SBProcess sb_process; 1157b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1158b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1159b2e7d28eSJim Ingham 1160b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1161b9c1b51eSKate Stone // Have to go up to the target so we can get a shared pointer to our 1162b9c1b51eSKate Stone // process... 11631ac04c30SGreg Clayton sb_process.SetSP(exe_ctx.GetProcessSP()); 116430fdc8d8SChris Lattner } 1165ceb6b139SCaroline Tice 11665160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1167b9c1b51eSKate Stone if (log) { 1168481cef25SGreg Clayton SBStream frame_desc_strm; 1169b9556accSGreg Clayton sb_process.GetDescription(frame_desc_strm); 1170324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s", 1171324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1172324a1036SSaleem Abdulrasool static_cast<void *>(sb_process.GetSP().get()), 1173324a1036SSaleem Abdulrasool frame_desc_strm.GetData()); 1174ceb6b139SCaroline Tice } 1175ceb6b139SCaroline Tice 1176b9556accSGreg Clayton return sb_process; 117730fdc8d8SChris Lattner } 117830fdc8d8SChris Lattner 1179b9c1b51eSKate Stone uint32_t SBThread::GetNumFrames() { 11805160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1181ceb6b139SCaroline Tice 1182ceb6b139SCaroline Tice uint32_t num_frames = 0; 1183bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1184bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11854fc6cb9cSJim Ingham 1186b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 11877fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1188b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11891ac04c30SGreg Clayton num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 1190b9c1b51eSKate Stone } else { 1191c9858e4dSGreg Clayton if (log) 1192324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames() => error: process is running", 1193324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1194c9858e4dSGreg Clayton } 11957fdf9ef1SGreg Clayton } 1196ceb6b139SCaroline Tice 1197ceb6b139SCaroline Tice if (log) 1198324a1036SSaleem Abdulrasool log->Printf("SBThread(%p)::GetNumFrames () => %u", 1199324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames); 1200ceb6b139SCaroline Tice 1201ceb6b139SCaroline Tice return num_frames; 120230fdc8d8SChris Lattner } 120330fdc8d8SChris Lattner 1204b9c1b51eSKate Stone SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 12055160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1206ceb6b139SCaroline Tice 120730fdc8d8SChris Lattner SBFrame sb_frame; 1208b57e4a1bSJason Molenda StackFrameSP frame_sp; 1209bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1210bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12114fc6cb9cSJim Ingham 1212b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12137fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1214b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12151ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 1216b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1217b9c1b51eSKate Stone } else { 1218c9858e4dSGreg Clayton if (log) 1219b9c1b51eSKate Stone log->Printf( 1220b9c1b51eSKate Stone "SBThread(%p)::GetFrameAtIndex() => error: process is running", 1221324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1222c9858e4dSGreg Clayton } 12237fdf9ef1SGreg Clayton } 1224ceb6b139SCaroline Tice 1225b9c1b51eSKate Stone if (log) { 1226481cef25SGreg Clayton SBStream frame_desc_strm; 1227481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 12284838131bSGreg Clayton log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s", 1229324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1230b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1231ceb6b139SCaroline Tice } 1232ceb6b139SCaroline Tice 123330fdc8d8SChris Lattner return sb_frame; 123430fdc8d8SChris Lattner } 123530fdc8d8SChris Lattner 1236b9c1b51eSKate Stone lldb::SBFrame SBThread::GetSelectedFrame() { 12375160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1238f028a1fbSGreg Clayton 1239f028a1fbSGreg Clayton SBFrame sb_frame; 1240b57e4a1bSJason Molenda StackFrameSP frame_sp; 1241bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1242bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12434fc6cb9cSJim Ingham 1244b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12457fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1246b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12471ac04c30SGreg Clayton frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 1248b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1249b9c1b51eSKate Stone } else { 1250c9858e4dSGreg Clayton if (log) 1251b9c1b51eSKate Stone log->Printf( 1252b9c1b51eSKate Stone "SBThread(%p)::GetSelectedFrame() => error: process is running", 1253324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1254c9858e4dSGreg Clayton } 12557fdf9ef1SGreg Clayton } 1256f028a1fbSGreg Clayton 1257b9c1b51eSKate Stone if (log) { 1258481cef25SGreg Clayton SBStream frame_desc_strm; 1259481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1260f028a1fbSGreg Clayton log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s", 1261324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1262b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1263f028a1fbSGreg Clayton } 1264f028a1fbSGreg Clayton 1265f028a1fbSGreg Clayton return sb_frame; 1266f028a1fbSGreg Clayton } 1267f028a1fbSGreg Clayton 1268b9c1b51eSKate Stone lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 12695160ce5cSGreg Clayton Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1270f028a1fbSGreg Clayton 1271f028a1fbSGreg Clayton SBFrame sb_frame; 1272b57e4a1bSJason Molenda StackFrameSP frame_sp; 1273bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1274bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12754fc6cb9cSJim Ingham 1276b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 12777fdf9ef1SGreg Clayton Process::StopLocker stop_locker; 1278b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12791ac04c30SGreg Clayton Thread *thread = exe_ctx.GetThreadPtr(); 12801ac04c30SGreg Clayton frame_sp = thread->GetStackFrameAtIndex(idx); 1281b9c1b51eSKate Stone if (frame_sp) { 12821ac04c30SGreg Clayton thread->SetSelectedFrame(frame_sp.get()); 1283b9556accSGreg Clayton sb_frame.SetFrameSP(frame_sp); 1284f028a1fbSGreg Clayton } 1285b9c1b51eSKate Stone } else { 1286c9858e4dSGreg Clayton if (log) 1287b9c1b51eSKate Stone log->Printf( 1288b9c1b51eSKate Stone "SBThread(%p)::SetSelectedFrame() => error: process is running", 1289324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 1290c9858e4dSGreg Clayton } 12917fdf9ef1SGreg Clayton } 1292f028a1fbSGreg Clayton 1293b9c1b51eSKate Stone if (log) { 1294481cef25SGreg Clayton SBStream frame_desc_strm; 1295481cef25SGreg Clayton sb_frame.GetDescription(frame_desc_strm); 1296f028a1fbSGreg Clayton log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s", 1297324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), idx, 1298b9c1b51eSKate Stone static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData()); 1299f028a1fbSGreg Clayton } 1300f028a1fbSGreg Clayton return sb_frame; 1301f028a1fbSGreg Clayton } 1302f028a1fbSGreg Clayton 1303b9c1b51eSKate Stone bool SBThread::EventIsThreadEvent(const SBEvent &event) { 13044f465cffSJim Ingham return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL; 13054f465cffSJim Ingham } 13064f465cffSJim Ingham 1307b9c1b51eSKate Stone SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 13084f465cffSJim Ingham return Thread::ThreadEventData::GetStackFrameFromEvent(event.get()); 13094f465cffSJim Ingham } 13104f465cffSJim Ingham 1311b9c1b51eSKate Stone SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 13124f465cffSJim Ingham return Thread::ThreadEventData::GetThreadFromEvent(event.get()); 13134f465cffSJim Ingham } 1314f028a1fbSGreg Clayton 1315b9c1b51eSKate Stone bool SBThread::operator==(const SBThread &rhs) const { 1316b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() == 1317b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 131830fdc8d8SChris Lattner } 131930fdc8d8SChris Lattner 1320b9c1b51eSKate Stone bool SBThread::operator!=(const SBThread &rhs) const { 1321b9c1b51eSKate Stone return m_opaque_sp->GetThreadSP().get() != 1322b9c1b51eSKate Stone rhs.m_opaque_sp->GetThreadSP().get(); 132330fdc8d8SChris Lattner } 1324dde9cff3SCaroline Tice 1325b9c1b51eSKate Stone bool SBThread::GetStatus(SBStream &status) const { 13264f465cffSJim Ingham Stream &strm = status.ref(); 13274f465cffSJim Ingham 1328b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1329b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1330b2e7d28eSJim Ingham 1331b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13326a9767c7SJim Ingham exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); 1333b9c1b51eSKate Stone } else 13344f465cffSJim Ingham strm.PutCString("No status"); 13354f465cffSJim Ingham 13364f465cffSJim Ingham return true; 13374f465cffSJim Ingham } 13384f465cffSJim Ingham 1339b9c1b51eSKate Stone bool SBThread::GetDescription(SBStream &description) const { 13406a9767c7SJim Ingham return GetDescription(description, false); 13416a9767c7SJim Ingham } 13426a9767c7SJim Ingham 13436a9767c7SJim Ingham bool SBThread::GetDescription(SBStream &description, bool stop_format) const { 1344da7bc7d0SGreg Clayton Stream &strm = description.ref(); 1345da7bc7d0SGreg Clayton 1346b2e7d28eSJim Ingham std::unique_lock<std::recursive_mutex> lock; 1347b2e7d28eSJim Ingham ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1348b2e7d28eSJim Ingham 1349b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 1350b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 13516a9767c7SJim Ingham LLDB_INVALID_THREAD_ID, 13526a9767c7SJim Ingham stop_format); 1353b9c1b51eSKate Stone // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 1354b9c1b51eSKate Stone // exe_ctx.GetThreadPtr()->GetID()); 1355b9c1b51eSKate Stone } else 1356da7bc7d0SGreg Clayton strm.PutCString("No value"); 1357ceb6b139SCaroline Tice 1358ceb6b139SCaroline Tice return true; 1359ceb6b139SCaroline Tice } 13605dd4916fSJason Molenda 1361b9c1b51eSKate Stone SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 13625dd4916fSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1363bb19a13cSSaleem Abdulrasool std::unique_lock<std::recursive_mutex> lock; 1364bb19a13cSSaleem Abdulrasool ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 13655dd4916fSJason Molenda SBThread sb_origin_thread; 13665dd4916fSJason Molenda 1367b9c1b51eSKate Stone if (exe_ctx.HasThreadScope()) { 13685dd4916fSJason Molenda Process::StopLocker stop_locker; 1369b9c1b51eSKate Stone if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 13707a2f7904SJason Molenda ThreadSP real_thread(exe_ctx.GetThreadSP()); 1371b9c1b51eSKate Stone if (real_thread) { 13725dd4916fSJason Molenda ConstString type_const(type); 13737a2f7904SJason Molenda Process *process = exe_ctx.GetProcessPtr(); 1374b9c1b51eSKate Stone if (process) { 13757a2f7904SJason Molenda SystemRuntime *runtime = process->GetSystemRuntime(); 1376b9c1b51eSKate Stone if (runtime) { 1377b9c1b51eSKate Stone ThreadSP new_thread_sp( 1378b9c1b51eSKate Stone runtime->GetExtendedBacktraceThread(real_thread, type_const)); 1379b9c1b51eSKate Stone if (new_thread_sp) { 1380b9c1b51eSKate Stone // Save this in the Process' ExtendedThreadList so a strong 1381b9c1b51eSKate Stone // pointer retains the 13827a2f7904SJason Molenda // object. 13837a2f7904SJason Molenda process->GetExtendedThreadList().AddThread(new_thread_sp); 13847a2f7904SJason Molenda sb_origin_thread.SetThread(new_thread_sp); 1385b9c1b51eSKate Stone if (log) { 1386a6e9130dSJason Molenda const char *queue_name = new_thread_sp->GetQueueName(); 1387a6e9130dSJason Molenda if (queue_name == NULL) 1388a6e9130dSJason Molenda queue_name = ""; 1389b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new " 1390b9c1b51eSKate Stone "extended Thread " 1391b9c1b51eSKate Stone "created (%p) with queue_id 0x%" PRIx64 1392b9c1b51eSKate Stone " queue name '%s'", 1393324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr()), 1394324a1036SSaleem Abdulrasool static_cast<void *>(new_thread_sp.get()), 1395b9c1b51eSKate Stone new_thread_sp->GetQueueID(), queue_name); 1396a6e9130dSJason Molenda } 1397a6e9130dSJason Molenda } 13987a2f7904SJason Molenda } 13995dd4916fSJason Molenda } 14005dd4916fSJason Molenda } 1401b9c1b51eSKate Stone } else { 14025dd4916fSJason Molenda if (log) 1403b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: " 1404b9c1b51eSKate Stone "process is running", 1405324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14065dd4916fSJason Molenda } 14075dd4916fSJason Molenda } 14085dd4916fSJason Molenda 1409ac605f4aSJason Molenda if (log && sb_origin_thread.IsValid() == false) 1410b9c1b51eSKate Stone log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a " 1411b9c1b51eSKate Stone "Valid thread", 1412324a1036SSaleem Abdulrasool static_cast<void *>(exe_ctx.GetThreadPtr())); 14135dd4916fSJason Molenda return sb_origin_thread; 14145dd4916fSJason Molenda } 14158ee9cb58SJason Molenda 1416b9c1b51eSKate Stone uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 14178ee9cb58SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14188ee9cb58SJason Molenda if (thread_sp) 14198ee9cb58SJason Molenda return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 14208ee9cb58SJason Molenda return LLDB_INVALID_INDEX32; 14218ee9cb58SJason Molenda } 1422b4892cd2SJason Molenda 1423b9c1b51eSKate Stone bool SBThread::SafeToCallFunctions() { 1424b4892cd2SJason Molenda ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 1425b4892cd2SJason Molenda if (thread_sp) 1426b4892cd2SJason Molenda return thread_sp->SafeToCallFunctions(); 1427b4892cd2SJason Molenda return true; 1428b4892cd2SJason Molenda } 14292bdbfd50SJim Ingham 1430b9c1b51eSKate Stone lldb_private::Thread *SBThread::operator->() { 14312bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14322bdbfd50SJim Ingham if (thread_sp) 14332bdbfd50SJim Ingham return thread_sp.get(); 14342bdbfd50SJim Ingham else 14352bdbfd50SJim Ingham return NULL; 14362bdbfd50SJim Ingham } 14372bdbfd50SJim Ingham 1438b9c1b51eSKate Stone lldb_private::Thread *SBThread::get() { 14392bdbfd50SJim Ingham ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 14402bdbfd50SJim Ingham if (thread_sp) 14412bdbfd50SJim Ingham return thread_sp.get(); 14422bdbfd50SJim Ingham else 14432bdbfd50SJim Ingham return NULL; 14442bdbfd50SJim Ingham } 1445