15ffd83dbSDimitry Andric //===-- SBThread.cpp ------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/API/SBThread.h" 100b57cec5SDimitry Andric #include "SBReproducerPrivate.h" 110b57cec5SDimitry Andric #include "Utils.h" 120b57cec5SDimitry Andric #include "lldb/API/SBAddress.h" 130b57cec5SDimitry Andric #include "lldb/API/SBDebugger.h" 140b57cec5SDimitry Andric #include "lldb/API/SBEvent.h" 150b57cec5SDimitry Andric #include "lldb/API/SBFileSpec.h" 160b57cec5SDimitry Andric #include "lldb/API/SBFrame.h" 170b57cec5SDimitry Andric #include "lldb/API/SBProcess.h" 180b57cec5SDimitry Andric #include "lldb/API/SBStream.h" 199dba64beSDimitry Andric #include "lldb/API/SBStructuredData.h" 200b57cec5SDimitry Andric #include "lldb/API/SBSymbolContext.h" 210b57cec5SDimitry Andric #include "lldb/API/SBThreadCollection.h" 220b57cec5SDimitry Andric #include "lldb/API/SBThreadPlan.h" 230b57cec5SDimitry Andric #include "lldb/API/SBValue.h" 240b57cec5SDimitry Andric #include "lldb/Breakpoint/BreakpointLocation.h" 250b57cec5SDimitry Andric #include "lldb/Core/Debugger.h" 260b57cec5SDimitry Andric #include "lldb/Core/StreamFile.h" 279dba64beSDimitry Andric #include "lldb/Core/StructuredDataImpl.h" 280b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h" 290b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h" 300b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 310b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 320b57cec5SDimitry Andric #include "lldb/Target/Process.h" 330b57cec5SDimitry Andric #include "lldb/Target/Queue.h" 340b57cec5SDimitry Andric #include "lldb/Target/StopInfo.h" 350b57cec5SDimitry Andric #include "lldb/Target/SystemRuntime.h" 360b57cec5SDimitry Andric #include "lldb/Target/Target.h" 370b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 380b57cec5SDimitry Andric #include "lldb/Target/ThreadPlan.h" 390b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepInRange.h" 400b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepInstruction.h" 410b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepOut.h" 420b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanStepRange.h" 430b57cec5SDimitry Andric #include "lldb/Utility/State.h" 440b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 450b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h" 460b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h" 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric #include <memory> 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric using namespace lldb; 510b57cec5SDimitry Andric using namespace lldb_private; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric const char *SBThread::GetBroadcasterClassName() { 540b57cec5SDimitry Andric LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBThread, 550b57cec5SDimitry Andric GetBroadcasterClassName); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric return Thread::GetStaticBroadcasterClass().AsCString(); 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric // Constructors 610b57cec5SDimitry Andric SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) { 620b57cec5SDimitry Andric LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBThread); 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric SBThread::SBThread(const ThreadSP &lldb_object_sp) 660b57cec5SDimitry Andric : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) { 670b57cec5SDimitry Andric LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &), lldb_object_sp); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric SBThread::SBThread(const SBThread &rhs) : m_opaque_sp() { 710b57cec5SDimitry Andric LLDB_RECORD_CONSTRUCTOR(SBThread, (const lldb::SBThread &), rhs); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric m_opaque_sp = clone(rhs.m_opaque_sp); 740b57cec5SDimitry Andric } 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // Assignment operator 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric const lldb::SBThread &SBThread::operator=(const SBThread &rhs) { 790b57cec5SDimitry Andric LLDB_RECORD_METHOD(const lldb::SBThread &, 800b57cec5SDimitry Andric SBThread, operator=,(const lldb::SBThread &), rhs); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric if (this != &rhs) 830b57cec5SDimitry Andric m_opaque_sp = clone(rhs.m_opaque_sp); 840b57cec5SDimitry Andric return LLDB_RECORD_RESULT(*this); 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric // Destructor 885ffd83dbSDimitry Andric SBThread::~SBThread() = default; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric lldb::SBQueue SBThread::GetQueue() const { 910b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBQueue, SBThread, GetQueue); 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric SBQueue sb_queue; 940b57cec5SDimitry Andric QueueSP queue_sp; 950b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 960b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 990b57cec5SDimitry Andric Process::StopLocker stop_locker; 1000b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1010b57cec5SDimitry Andric queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); 1020b57cec5SDimitry Andric if (queue_sp) { 1030b57cec5SDimitry Andric sb_queue.SetQueue(queue_sp); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_queue); 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric bool SBThread::IsValid() const { 1120b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, IsValid); 1130b57cec5SDimitry Andric return this->operator bool(); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric SBThread::operator bool() const { 1160b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBThread, operator bool); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 1190b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 1220b57cec5SDimitry Andric Process *process = exe_ctx.GetProcessPtr(); 1230b57cec5SDimitry Andric if (target && process) { 1240b57cec5SDimitry Andric Process::StopLocker stop_locker; 1250b57cec5SDimitry Andric if (stop_locker.TryLock(&process->GetRunLock())) 1260b57cec5SDimitry Andric return m_opaque_sp->GetThreadSP().get() != nullptr; 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric // Without a valid target & process, this thread can't be valid. 1290b57cec5SDimitry Andric return false; 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric void SBThread::Clear() { 1330b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, Clear); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric m_opaque_sp->Clear(); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric StopReason SBThread::GetStopReason() { 1390b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::StopReason, SBThread, GetStopReason); 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric StopReason reason = eStopReasonInvalid; 1420b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 1430b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 1460b57cec5SDimitry Andric Process::StopLocker stop_locker; 1470b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1480b57cec5SDimitry Andric return exe_ctx.GetThreadPtr()->GetStopReason(); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric } 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric return reason; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric size_t SBThread::GetStopReasonDataCount() { 1560b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(size_t, SBThread, GetStopReasonDataCount); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 1590b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 1620b57cec5SDimitry Andric Process::StopLocker stop_locker; 1630b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 1640b57cec5SDimitry Andric StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 1650b57cec5SDimitry Andric if (stop_info_sp) { 1660b57cec5SDimitry Andric StopReason reason = stop_info_sp->GetStopReason(); 1670b57cec5SDimitry Andric switch (reason) { 1680b57cec5SDimitry Andric case eStopReasonInvalid: 1690b57cec5SDimitry Andric case eStopReasonNone: 1700b57cec5SDimitry Andric case eStopReasonTrace: 1710b57cec5SDimitry Andric case eStopReasonExec: 1720b57cec5SDimitry Andric case eStopReasonPlanComplete: 1730b57cec5SDimitry Andric case eStopReasonThreadExiting: 1740b57cec5SDimitry Andric case eStopReasonInstrumentation: 175fe6060f1SDimitry Andric case eStopReasonProcessorTrace: 176fe6060f1SDimitry Andric case eStopReasonVForkDone: 1770b57cec5SDimitry Andric // There is no data for these stop reasons. 1780b57cec5SDimitry Andric return 0; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric case eStopReasonBreakpoint: { 1810b57cec5SDimitry Andric break_id_t site_id = stop_info_sp->GetValue(); 1820b57cec5SDimitry Andric lldb::BreakpointSiteSP bp_site_sp( 1830b57cec5SDimitry Andric exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 1840b57cec5SDimitry Andric site_id)); 1850b57cec5SDimitry Andric if (bp_site_sp) 1860b57cec5SDimitry Andric return bp_site_sp->GetNumberOfOwners() * 2; 1870b57cec5SDimitry Andric else 1880b57cec5SDimitry Andric return 0; // Breakpoint must have cleared itself... 1890b57cec5SDimitry Andric } break; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric case eStopReasonWatchpoint: 1920b57cec5SDimitry Andric return 1; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric case eStopReasonSignal: 1950b57cec5SDimitry Andric return 1; 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric case eStopReasonException: 1980b57cec5SDimitry Andric return 1; 199fe6060f1SDimitry Andric 200fe6060f1SDimitry Andric case eStopReasonFork: 201fe6060f1SDimitry Andric return 1; 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric case eStopReasonVFork: 204fe6060f1SDimitry Andric return 1; 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric } 2070b57cec5SDimitry Andric } 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric return 0; 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { 2130b57cec5SDimitry Andric LLDB_RECORD_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, (uint32_t), 2140b57cec5SDimitry Andric idx); 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 2170b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 2200b57cec5SDimitry Andric Process::StopLocker stop_locker; 2210b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 2220b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 2230b57cec5SDimitry Andric StopInfoSP stop_info_sp = thread->GetStopInfo(); 2240b57cec5SDimitry Andric if (stop_info_sp) { 2250b57cec5SDimitry Andric StopReason reason = stop_info_sp->GetStopReason(); 2260b57cec5SDimitry Andric switch (reason) { 2270b57cec5SDimitry Andric case eStopReasonInvalid: 2280b57cec5SDimitry Andric case eStopReasonNone: 2290b57cec5SDimitry Andric case eStopReasonTrace: 2300b57cec5SDimitry Andric case eStopReasonExec: 2310b57cec5SDimitry Andric case eStopReasonPlanComplete: 2320b57cec5SDimitry Andric case eStopReasonThreadExiting: 2330b57cec5SDimitry Andric case eStopReasonInstrumentation: 234fe6060f1SDimitry Andric case eStopReasonProcessorTrace: 235fe6060f1SDimitry Andric case eStopReasonVForkDone: 2360b57cec5SDimitry Andric // There is no data for these stop reasons. 2370b57cec5SDimitry Andric return 0; 2380b57cec5SDimitry Andric 2390b57cec5SDimitry Andric case eStopReasonBreakpoint: { 2400b57cec5SDimitry Andric break_id_t site_id = stop_info_sp->GetValue(); 2410b57cec5SDimitry Andric lldb::BreakpointSiteSP bp_site_sp( 2420b57cec5SDimitry Andric exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID( 2430b57cec5SDimitry Andric site_id)); 2440b57cec5SDimitry Andric if (bp_site_sp) { 2450b57cec5SDimitry Andric uint32_t bp_index = idx / 2; 2460b57cec5SDimitry Andric BreakpointLocationSP bp_loc_sp( 2470b57cec5SDimitry Andric bp_site_sp->GetOwnerAtIndex(bp_index)); 2480b57cec5SDimitry Andric if (bp_loc_sp) { 2490b57cec5SDimitry Andric if (idx & 1) { 2500b57cec5SDimitry Andric // Odd idx, return the breakpoint location ID 2510b57cec5SDimitry Andric return bp_loc_sp->GetID(); 2520b57cec5SDimitry Andric } else { 2530b57cec5SDimitry Andric // Even idx, return the breakpoint ID 2540b57cec5SDimitry Andric return bp_loc_sp->GetBreakpoint().GetID(); 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric } 2570b57cec5SDimitry Andric } 2580b57cec5SDimitry Andric return LLDB_INVALID_BREAK_ID; 2590b57cec5SDimitry Andric } break; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric case eStopReasonWatchpoint: 2620b57cec5SDimitry Andric return stop_info_sp->GetValue(); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric case eStopReasonSignal: 2650b57cec5SDimitry Andric return stop_info_sp->GetValue(); 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric case eStopReasonException: 2680b57cec5SDimitry Andric return stop_info_sp->GetValue(); 269fe6060f1SDimitry Andric 270fe6060f1SDimitry Andric case eStopReasonFork: 271fe6060f1SDimitry Andric return stop_info_sp->GetValue(); 272fe6060f1SDimitry Andric 273fe6060f1SDimitry Andric case eStopReasonVFork: 274fe6060f1SDimitry Andric return stop_info_sp->GetValue(); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric return 0; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { 2830b57cec5SDimitry Andric LLDB_RECORD_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON, 2840b57cec5SDimitry Andric (lldb::SBStream &), stream); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric Stream &strm = stream.ref(); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 2890b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) 2920b57cec5SDimitry Andric return false; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 2950b57cec5SDimitry Andric StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 2960b57cec5SDimitry Andric if (!info) 2970b57cec5SDimitry Andric return false; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric info->Dump(strm); 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric return true; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric SBThreadCollection 3050b57cec5SDimitry Andric SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { 3060b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBThreadCollection, SBThread, 3070b57cec5SDimitry Andric GetStopReasonExtendedBacktraces, 3080b57cec5SDimitry Andric (lldb::InstrumentationRuntimeType), type); 3090b57cec5SDimitry Andric 3105ffd83dbSDimitry Andric SBThreadCollection threads; 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 3130b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) 3165ffd83dbSDimitry Andric return LLDB_RECORD_RESULT(SBThreadCollection()); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric ProcessSP process_sp = exe_ctx.GetProcessSP(); 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo(); 3210b57cec5SDimitry Andric StructuredData::ObjectSP info = stop_info->GetExtendedInfo(); 3220b57cec5SDimitry Andric if (!info) 3230b57cec5SDimitry Andric return LLDB_RECORD_RESULT(threads); 3240b57cec5SDimitry Andric 3255ffd83dbSDimitry Andric threads = process_sp->GetInstrumentationRuntime(type) 3265ffd83dbSDimitry Andric ->GetBacktracesFromExtendedStopInfo(info); 3275ffd83dbSDimitry Andric return LLDB_RECORD_RESULT(threads); 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { 3315ffd83dbSDimitry Andric LLDB_RECORD_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription, 3325ffd83dbSDimitry Andric (char *, size_t), dst, "", dst_len); 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 3350b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric if (dst) 3380b57cec5SDimitry Andric *dst = 0; 3395ffd83dbSDimitry Andric 3405ffd83dbSDimitry Andric if (!exe_ctx.HasThreadScope()) 3410b57cec5SDimitry Andric return 0; 3425ffd83dbSDimitry Andric 3435ffd83dbSDimitry Andric Process::StopLocker stop_locker; 3445ffd83dbSDimitry Andric if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) 3455ffd83dbSDimitry Andric return 0; 3465ffd83dbSDimitry Andric 3475ffd83dbSDimitry Andric std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription(); 3485ffd83dbSDimitry Andric if (thread_stop_desc.empty()) 3495ffd83dbSDimitry Andric return 0; 3505ffd83dbSDimitry Andric 3515ffd83dbSDimitry Andric if (dst) 3525ffd83dbSDimitry Andric return ::snprintf(dst, dst_len, "%s", thread_stop_desc.c_str()) + 1; 3535ffd83dbSDimitry Andric 3545ffd83dbSDimitry Andric // NULL dst passed in, return the length needed to contain the 3555ffd83dbSDimitry Andric // description. 3565ffd83dbSDimitry Andric return thread_stop_desc.size() + 1; // Include the NULL byte for size 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric SBValue SBThread::GetStopReturnValue() { 3600b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetStopReturnValue); 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric ValueObjectSP return_valobj_sp; 3630b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 3640b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 3670b57cec5SDimitry Andric Process::StopLocker stop_locker; 3680b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 3690b57cec5SDimitry Andric StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); 3700b57cec5SDimitry Andric if (stop_info_sp) { 3710b57cec5SDimitry Andric return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); 3720b57cec5SDimitry Andric } 3730b57cec5SDimitry Andric } 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric return LLDB_RECORD_RESULT(SBValue(return_valobj_sp)); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric void SBThread::SetThread(const ThreadSP &lldb_object_sp) { 3800b57cec5SDimitry Andric m_opaque_sp->SetThreadSP(lldb_object_sp); 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric lldb::tid_t SBThread::GetThreadID() const { 3840b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::tid_t, SBThread, GetThreadID); 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 3870b57cec5SDimitry Andric if (thread_sp) 3880b57cec5SDimitry Andric return thread_sp->GetID(); 3890b57cec5SDimitry Andric return LLDB_INVALID_THREAD_ID; 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric uint32_t SBThread::GetIndexID() const { 3930b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBThread, GetIndexID); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 3960b57cec5SDimitry Andric if (thread_sp) 3970b57cec5SDimitry Andric return thread_sp->GetIndexID(); 3980b57cec5SDimitry Andric return LLDB_INVALID_INDEX32; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric const char *SBThread::GetName() const { 4020b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetName); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric const char *name = nullptr; 4050b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 4060b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 4090b57cec5SDimitry Andric Process::StopLocker stop_locker; 4100b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4110b57cec5SDimitry Andric name = exe_ctx.GetThreadPtr()->GetName(); 4120b57cec5SDimitry Andric } 4130b57cec5SDimitry Andric } 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric return name; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric 4180b57cec5SDimitry Andric const char *SBThread::GetQueueName() const { 4190b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBThread, GetQueueName); 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric const char *name = nullptr; 4220b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 4230b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 4260b57cec5SDimitry Andric Process::StopLocker stop_locker; 4270b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4280b57cec5SDimitry Andric name = exe_ctx.GetThreadPtr()->GetQueueName(); 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric return name; 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric lldb::queue_id_t SBThread::GetQueueID() const { 4360b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBThread, GetQueueID); 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric queue_id_t id = LLDB_INVALID_QUEUE_ID; 4390b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 4400b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 4430b57cec5SDimitry Andric Process::StopLocker stop_locker; 4440b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4450b57cec5SDimitry Andric id = exe_ctx.GetThreadPtr()->GetQueueID(); 4460b57cec5SDimitry Andric } 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric return id; 4500b57cec5SDimitry Andric } 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { 4530b57cec5SDimitry Andric LLDB_RECORD_METHOD(bool, SBThread, GetInfoItemByPathAsString, 4540b57cec5SDimitry Andric (const char *, lldb::SBStream &), path, strm); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric bool success = false; 4570b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 4580b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 4610b57cec5SDimitry Andric Process::StopLocker stop_locker; 4620b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 4630b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 4640b57cec5SDimitry Andric StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); 4650b57cec5SDimitry Andric if (info_root_sp) { 4660b57cec5SDimitry Andric StructuredData::ObjectSP node = 4670b57cec5SDimitry Andric info_root_sp->GetObjectForDotSeparatedPath(path); 4680b57cec5SDimitry Andric if (node) { 4690b57cec5SDimitry Andric if (node->GetType() == eStructuredDataTypeString) { 4700b57cec5SDimitry Andric strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); 4710b57cec5SDimitry Andric success = true; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric if (node->GetType() == eStructuredDataTypeInteger) { 4740b57cec5SDimitry Andric strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); 4750b57cec5SDimitry Andric success = true; 4760b57cec5SDimitry Andric } 4770b57cec5SDimitry Andric if (node->GetType() == eStructuredDataTypeFloat) { 4780b57cec5SDimitry Andric strm.Printf("0x%f", node->GetAsFloat()->GetValue()); 4790b57cec5SDimitry Andric success = true; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric if (node->GetType() == eStructuredDataTypeBoolean) { 4820b57cec5SDimitry Andric if (node->GetAsBoolean()->GetValue()) 4830b57cec5SDimitry Andric strm.Printf("true"); 4840b57cec5SDimitry Andric else 4850b57cec5SDimitry Andric strm.Printf("false"); 4860b57cec5SDimitry Andric success = true; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric if (node->GetType() == eStructuredDataTypeNull) { 4890b57cec5SDimitry Andric strm.Printf("null"); 4900b57cec5SDimitry Andric success = true; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric } 4950b57cec5SDimitry Andric } 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric return success; 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx, 5010b57cec5SDimitry Andric ThreadPlan *new_plan) { 5020b57cec5SDimitry Andric SBError sb_error; 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric Process *process = exe_ctx.GetProcessPtr(); 5050b57cec5SDimitry Andric if (!process) { 5060b57cec5SDimitry Andric sb_error.SetErrorString("No process in SBThread::ResumeNewPlan"); 5070b57cec5SDimitry Andric return sb_error; 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 5110b57cec5SDimitry Andric if (!thread) { 5120b57cec5SDimitry Andric sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan"); 5130b57cec5SDimitry Andric return sb_error; 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric // User level plans should be Master Plans so they can be interrupted, other 5170b57cec5SDimitry Andric // plans executed, and then a "continue" will resume the plan. 5180b57cec5SDimitry Andric if (new_plan != nullptr) { 5190b57cec5SDimitry Andric new_plan->SetIsMasterPlan(true); 5200b57cec5SDimitry Andric new_plan->SetOkayToDiscard(false); 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric // Why do we need to set the current thread by ID here??? 5240b57cec5SDimitry Andric process->GetThreadList().SetSelectedThreadByID(thread->GetID()); 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric if (process->GetTarget().GetDebugger().GetAsyncExecution()) 5270b57cec5SDimitry Andric sb_error.ref() = process->Resume(); 5280b57cec5SDimitry Andric else 5290b57cec5SDimitry Andric sb_error.ref() = process->ResumeSynchronous(nullptr); 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric return sb_error; 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric void SBThread::StepOver(lldb::RunMode stop_other_threads) { 5350b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode), 5360b57cec5SDimitry Andric stop_other_threads); 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric SBError error; // Ignored 5390b57cec5SDimitry Andric StepOver(stop_other_threads, error); 5400b57cec5SDimitry Andric } 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { 5430b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepOver, (lldb::RunMode, lldb::SBError &), 5440b57cec5SDimitry Andric stop_other_threads, error); 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 5470b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 5500b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 5510b57cec5SDimitry Andric return; 5520b57cec5SDimitry Andric } 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 5550b57cec5SDimitry Andric bool abort_other_plans = false; 5560b57cec5SDimitry Andric StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric Status new_plan_status; 5590b57cec5SDimitry Andric ThreadPlanSP new_plan_sp; 5600b57cec5SDimitry Andric if (frame_sp) { 5610b57cec5SDimitry Andric if (frame_sp->HasDebugInformation()) { 5620b57cec5SDimitry Andric const LazyBool avoid_no_debug = eLazyBoolCalculate; 5630b57cec5SDimitry Andric SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 5640b57cec5SDimitry Andric new_plan_sp = thread->QueueThreadPlanForStepOverRange( 5650b57cec5SDimitry Andric abort_other_plans, sc.line_entry, sc, stop_other_threads, 5660b57cec5SDimitry Andric new_plan_status, avoid_no_debug); 5670b57cec5SDimitry Andric } else { 5680b57cec5SDimitry Andric new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 5690b57cec5SDimitry Andric true, abort_other_plans, stop_other_threads, new_plan_status); 5700b57cec5SDimitry Andric } 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric void SBThread::StepInto(lldb::RunMode stop_other_threads) { 5760b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepInto, (lldb::RunMode), 5770b57cec5SDimitry Andric stop_other_threads); 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric StepInto(nullptr, stop_other_threads); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric void SBThread::StepInto(const char *target_name, 5830b57cec5SDimitry Andric lldb::RunMode stop_other_threads) { 5840b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepInto, (const char *, lldb::RunMode), 5850b57cec5SDimitry Andric target_name, stop_other_threads); 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric SBError error; // Ignored 5880b57cec5SDimitry Andric StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads); 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric void SBThread::StepInto(const char *target_name, uint32_t end_line, 5920b57cec5SDimitry Andric SBError &error, lldb::RunMode stop_other_threads) { 5930b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepInto, 5940b57cec5SDimitry Andric (const char *, uint32_t, lldb::SBError &, lldb::RunMode), 5950b57cec5SDimitry Andric target_name, end_line, error, stop_other_threads); 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 5990b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 6020b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 6030b57cec5SDimitry Andric return; 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric bool abort_other_plans = false; 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 6090b57cec5SDimitry Andric StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); 6100b57cec5SDimitry Andric ThreadPlanSP new_plan_sp; 6110b57cec5SDimitry Andric Status new_plan_status; 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric if (frame_sp && frame_sp->HasDebugInformation()) { 6140b57cec5SDimitry Andric SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); 6150b57cec5SDimitry Andric AddressRange range; 6160b57cec5SDimitry Andric if (end_line == LLDB_INVALID_LINE_NUMBER) 6170b57cec5SDimitry Andric range = sc.line_entry.range; 6180b57cec5SDimitry Andric else { 6190b57cec5SDimitry Andric if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref())) 6200b57cec5SDimitry Andric return; 6210b57cec5SDimitry Andric } 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric const LazyBool step_out_avoids_code_without_debug_info = 6240b57cec5SDimitry Andric eLazyBoolCalculate; 6250b57cec5SDimitry Andric const LazyBool step_in_avoids_code_without_debug_info = 6260b57cec5SDimitry Andric eLazyBoolCalculate; 6270b57cec5SDimitry Andric new_plan_sp = thread->QueueThreadPlanForStepInRange( 6280b57cec5SDimitry Andric abort_other_plans, range, sc, target_name, stop_other_threads, 6290b57cec5SDimitry Andric new_plan_status, step_in_avoids_code_without_debug_info, 6300b57cec5SDimitry Andric step_out_avoids_code_without_debug_info); 6310b57cec5SDimitry Andric } else { 6320b57cec5SDimitry Andric new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( 6330b57cec5SDimitry Andric false, abort_other_plans, stop_other_threads, new_plan_status); 6340b57cec5SDimitry Andric } 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric if (new_plan_status.Success()) 6370b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 6380b57cec5SDimitry Andric else 6390b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric void SBThread::StepOut() { 6430b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(void, SBThread, StepOut); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric SBError error; // Ignored 6460b57cec5SDimitry Andric StepOut(error); 6470b57cec5SDimitry Andric } 6480b57cec5SDimitry Andric 6490b57cec5SDimitry Andric void SBThread::StepOut(SBError &error) { 6500b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepOut, (lldb::SBError &), error); 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 6530b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 6560b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 6570b57cec5SDimitry Andric return; 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric bool abort_other_plans = false; 6610b57cec5SDimitry Andric bool stop_other_threads = false; 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric const LazyBool avoid_no_debug = eLazyBoolCalculate; 6660b57cec5SDimitry Andric Status new_plan_status; 6670b57cec5SDimitry Andric ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 6680b57cec5SDimitry Andric abort_other_plans, nullptr, false, stop_other_threads, eVoteYes, 6690b57cec5SDimitry Andric eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric if (new_plan_status.Success()) 6720b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 6730b57cec5SDimitry Andric else 6740b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric void SBThread::StepOutOfFrame(SBFrame &sb_frame) { 6780b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &), 6790b57cec5SDimitry Andric sb_frame); 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric SBError error; // Ignored 6820b57cec5SDimitry Andric StepOutOfFrame(sb_frame, error); 6830b57cec5SDimitry Andric } 6840b57cec5SDimitry Andric 6850b57cec5SDimitry Andric void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { 6860b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepOutOfFrame, 6870b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBError &), sb_frame, error); 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 6910b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric if (!sb_frame.IsValid()) { 6940b57cec5SDimitry Andric error.SetErrorString("passed invalid SBFrame object"); 6950b57cec5SDimitry Andric return; 6960b57cec5SDimitry Andric } 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric StackFrameSP frame_sp(sb_frame.GetFrameSP()); 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 7010b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 7020b57cec5SDimitry Andric return; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric bool abort_other_plans = false; 7060b57cec5SDimitry Andric bool stop_other_threads = false; 7070b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 7080b57cec5SDimitry Andric if (sb_frame.GetThread().GetThreadID() != thread->GetID()) { 7090b57cec5SDimitry Andric error.SetErrorString("passed a frame from another thread"); 7100b57cec5SDimitry Andric return; 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric Status new_plan_status; 7140b57cec5SDimitry Andric ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( 7150b57cec5SDimitry Andric abort_other_plans, nullptr, false, stop_other_threads, eVoteYes, 7160b57cec5SDimitry Andric eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric if (new_plan_status.Success()) 7190b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 7200b57cec5SDimitry Andric else 7210b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric void SBThread::StepInstruction(bool step_over) { 7250b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool), step_over); 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric SBError error; // Ignored 7280b57cec5SDimitry Andric StepInstruction(step_over, error); 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric void SBThread::StepInstruction(bool step_over, SBError &error) { 7320b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, StepInstruction, (bool, lldb::SBError &), 7330b57cec5SDimitry Andric step_over, error); 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 7360b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 7390b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 7400b57cec5SDimitry Andric return; 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 7440b57cec5SDimitry Andric Status new_plan_status; 7450b57cec5SDimitry Andric ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( 7460b57cec5SDimitry Andric step_over, true, true, new_plan_status)); 7470b57cec5SDimitry Andric 7480b57cec5SDimitry Andric if (new_plan_status.Success()) 7490b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 7500b57cec5SDimitry Andric else 7510b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 7520b57cec5SDimitry Andric } 7530b57cec5SDimitry Andric 7540b57cec5SDimitry Andric void SBThread::RunToAddress(lldb::addr_t addr) { 7550b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, RunToAddress, (lldb::addr_t), addr); 7560b57cec5SDimitry Andric 7570b57cec5SDimitry Andric SBError error; // Ignored 7580b57cec5SDimitry Andric RunToAddress(addr, error); 7590b57cec5SDimitry Andric } 7600b57cec5SDimitry Andric 7610b57cec5SDimitry Andric void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { 7620b57cec5SDimitry Andric LLDB_RECORD_METHOD(void, SBThread, RunToAddress, 7630b57cec5SDimitry Andric (lldb::addr_t, lldb::SBError &), addr, error); 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 7660b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 7690b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 7700b57cec5SDimitry Andric return; 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 7730b57cec5SDimitry Andric bool abort_other_plans = false; 7740b57cec5SDimitry Andric bool stop_other_threads = true; 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric Address target_addr(addr); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric Status new_plan_status; 7810b57cec5SDimitry Andric ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( 7820b57cec5SDimitry Andric abort_other_plans, target_addr, stop_other_threads, new_plan_status)); 7830b57cec5SDimitry Andric 7840b57cec5SDimitry Andric if (new_plan_status.Success()) 7850b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 7860b57cec5SDimitry Andric else 7870b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 7880b57cec5SDimitry Andric } 7890b57cec5SDimitry Andric 7900b57cec5SDimitry Andric SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, 7910b57cec5SDimitry Andric lldb::SBFileSpec &sb_file_spec, uint32_t line) { 7920b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepOverUntil, 7930b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t), sb_frame, 7940b57cec5SDimitry Andric sb_file_spec, line); 7950b57cec5SDimitry Andric 7960b57cec5SDimitry Andric SBError sb_error; 7970b57cec5SDimitry Andric char path[PATH_MAX]; 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 8000b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric StackFrameSP frame_sp(sb_frame.GetFrameSP()); 8030b57cec5SDimitry Andric 8040b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 8050b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 8060b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric if (line == 0) { 8090b57cec5SDimitry Andric sb_error.SetErrorString("invalid line argument"); 8100b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 8110b57cec5SDimitry Andric } 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric if (!frame_sp) { 8140b57cec5SDimitry Andric frame_sp = thread->GetSelectedFrame(); 8150b57cec5SDimitry Andric if (!frame_sp) 8160b57cec5SDimitry Andric frame_sp = thread->GetStackFrameAtIndex(0); 8170b57cec5SDimitry Andric } 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric SymbolContext frame_sc; 8200b57cec5SDimitry Andric if (!frame_sp) { 8210b57cec5SDimitry Andric sb_error.SetErrorString("no valid frames in thread to step"); 8220b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andric // If we have a frame, get its line 8260b57cec5SDimitry Andric frame_sc = frame_sp->GetSymbolContext( 8270b57cec5SDimitry Andric eSymbolContextCompUnit | eSymbolContextFunction | 8280b57cec5SDimitry Andric eSymbolContextLineEntry | eSymbolContextSymbol); 8290b57cec5SDimitry Andric 8300b57cec5SDimitry Andric if (frame_sc.comp_unit == nullptr) { 8310b57cec5SDimitry Andric sb_error.SetErrorStringWithFormat( 8320b57cec5SDimitry Andric "frame %u doesn't have debug information", frame_sp->GetFrameIndex()); 8330b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 8340b57cec5SDimitry Andric } 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric FileSpec step_file_spec; 8370b57cec5SDimitry Andric if (sb_file_spec.IsValid()) { 8380b57cec5SDimitry Andric // The file spec passed in was valid, so use it 8390b57cec5SDimitry Andric step_file_spec = sb_file_spec.ref(); 8400b57cec5SDimitry Andric } else { 8410b57cec5SDimitry Andric if (frame_sc.line_entry.IsValid()) 8420b57cec5SDimitry Andric step_file_spec = frame_sc.line_entry.file; 8430b57cec5SDimitry Andric else { 8440b57cec5SDimitry Andric sb_error.SetErrorString("invalid file argument or no file for frame"); 8450b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric } 8480b57cec5SDimitry Andric 8490b57cec5SDimitry Andric // Grab the current function, then we will make sure the "until" address is 8500b57cec5SDimitry Andric // within the function. We discard addresses that are out of the current 8510b57cec5SDimitry Andric // function, and then if there are no addresses remaining, give an 8520b57cec5SDimitry Andric // appropriate error message. 8530b57cec5SDimitry Andric 8540b57cec5SDimitry Andric bool all_in_function = true; 8550b57cec5SDimitry Andric AddressRange fun_range = frame_sc.function->GetAddressRange(); 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric std::vector<addr_t> step_over_until_addrs; 8580b57cec5SDimitry Andric const bool abort_other_plans = false; 8590b57cec5SDimitry Andric const bool stop_other_threads = false; 860fe6060f1SDimitry Andric // TODO: Handle SourceLocationSpec column information 861fe6060f1SDimitry Andric SourceLocationSpec location_spec( 862fe6060f1SDimitry Andric step_file_spec, line, /*column=*/llvm::None, /*check_inlines=*/true, 863fe6060f1SDimitry Andric /*exact_match=*/false); 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric SymbolContextList sc_list; 866fe6060f1SDimitry Andric frame_sc.comp_unit->ResolveSymbolContext(location_spec, 867480093f4SDimitry Andric eSymbolContextLineEntry, sc_list); 868480093f4SDimitry Andric const uint32_t num_matches = sc_list.GetSize(); 8690b57cec5SDimitry Andric if (num_matches > 0) { 8700b57cec5SDimitry Andric SymbolContext sc; 8710b57cec5SDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) { 8720b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(i, sc)) { 8730b57cec5SDimitry Andric addr_t step_addr = 8740b57cec5SDimitry Andric sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); 8750b57cec5SDimitry Andric if (step_addr != LLDB_INVALID_ADDRESS) { 8760b57cec5SDimitry Andric if (fun_range.ContainsLoadAddress(step_addr, target)) 8770b57cec5SDimitry Andric step_over_until_addrs.push_back(step_addr); 8780b57cec5SDimitry Andric else 8790b57cec5SDimitry Andric all_in_function = false; 8800b57cec5SDimitry Andric } 8810b57cec5SDimitry Andric } 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric } 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric if (step_over_until_addrs.empty()) { 8860b57cec5SDimitry Andric if (all_in_function) { 8870b57cec5SDimitry Andric step_file_spec.GetPath(path, sizeof(path)); 8880b57cec5SDimitry Andric sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, 8890b57cec5SDimitry Andric line); 8900b57cec5SDimitry Andric } else 8910b57cec5SDimitry Andric sb_error.SetErrorString("step until target not in current function"); 8920b57cec5SDimitry Andric } else { 8930b57cec5SDimitry Andric Status new_plan_status; 8940b57cec5SDimitry Andric ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( 8950b57cec5SDimitry Andric abort_other_plans, &step_over_until_addrs[0], 8960b57cec5SDimitry Andric step_over_until_addrs.size(), stop_other_threads, 8970b57cec5SDimitry Andric frame_sp->GetFrameIndex(), new_plan_status)); 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric if (new_plan_status.Success()) 9000b57cec5SDimitry Andric sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 9010b57cec5SDimitry Andric else 9020b57cec5SDimitry Andric sb_error.SetErrorString(new_plan_status.AsCString()); 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric } else { 9050b57cec5SDimitry Andric sb_error.SetErrorString("this SBThread object is invalid"); 9060b57cec5SDimitry Andric } 9070b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 9080b57cec5SDimitry Andric } 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { 9110b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 9120b57cec5SDimitry Andric (const char *), script_class_name); 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric return LLDB_RECORD_RESULT( 9150b57cec5SDimitry Andric StepUsingScriptedThreadPlan(script_class_name, true)); 9160b57cec5SDimitry Andric } 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 9190b57cec5SDimitry Andric bool resume_immediately) { 9200b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 9210b57cec5SDimitry Andric (const char *, bool), script_class_name, 9220b57cec5SDimitry Andric resume_immediately); 9230b57cec5SDimitry Andric 9249dba64beSDimitry Andric lldb::SBStructuredData no_data; 9255ffd83dbSDimitry Andric return LLDB_RECORD_RESULT(StepUsingScriptedThreadPlan( 9265ffd83dbSDimitry Andric script_class_name, no_data, resume_immediately)); 9279dba64beSDimitry Andric } 9289dba64beSDimitry Andric 9299dba64beSDimitry Andric SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, 9309dba64beSDimitry Andric SBStructuredData &args_data, 9319dba64beSDimitry Andric bool resume_immediately) { 9329dba64beSDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 9339dba64beSDimitry Andric (const char *, lldb::SBStructuredData &, bool), 9345ffd83dbSDimitry Andric script_class_name, args_data, resume_immediately); 9359dba64beSDimitry Andric 9360b57cec5SDimitry Andric SBError error; 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 9390b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 9420b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 9430b57cec5SDimitry Andric return LLDB_RECORD_RESULT(error); 9440b57cec5SDimitry Andric } 9450b57cec5SDimitry Andric 9460b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 9470b57cec5SDimitry Andric Status new_plan_status; 9489dba64beSDimitry Andric StructuredData::ObjectSP obj_sp = args_data.m_impl_up->GetObjectSP(); 9499dba64beSDimitry Andric 9500b57cec5SDimitry Andric ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( 9519dba64beSDimitry Andric false, script_class_name, obj_sp, false, new_plan_status); 9520b57cec5SDimitry Andric 9530b57cec5SDimitry Andric if (new_plan_status.Fail()) { 9540b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 9550b57cec5SDimitry Andric return LLDB_RECORD_RESULT(error); 9560b57cec5SDimitry Andric } 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric if (!resume_immediately) 9590b57cec5SDimitry Andric return LLDB_RECORD_RESULT(error); 9600b57cec5SDimitry Andric 9610b57cec5SDimitry Andric if (new_plan_status.Success()) 9620b57cec5SDimitry Andric error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); 9630b57cec5SDimitry Andric else 9640b57cec5SDimitry Andric error.SetErrorString(new_plan_status.AsCString()); 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric return LLDB_RECORD_RESULT(error); 9670b57cec5SDimitry Andric } 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { 9700b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, JumpToLine, 9710b57cec5SDimitry Andric (lldb::SBFileSpec &, uint32_t), file_spec, line); 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric SBError sb_error; 9740b57cec5SDimitry Andric 9750b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 9760b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9770b57cec5SDimitry Andric 9780b57cec5SDimitry Andric if (!exe_ctx.HasThreadScope()) { 9790b57cec5SDimitry Andric sb_error.SetErrorString("this SBThread object is invalid"); 9800b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 9810b57cec5SDimitry Andric } 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 9840b57cec5SDimitry Andric 985480093f4SDimitry Andric Status err = thread->JumpToLine(file_spec.ref(), line, true); 9860b57cec5SDimitry Andric sb_error.SetError(err); 9870b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 9880b57cec5SDimitry Andric } 9890b57cec5SDimitry Andric 9900b57cec5SDimitry Andric SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { 9910b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBError, SBThread, ReturnFromFrame, 9920b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBValue &), frame, return_value); 9930b57cec5SDimitry Andric 9940b57cec5SDimitry Andric SBError sb_error; 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 9970b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 10000b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 10010b57cec5SDimitry Andric sb_error.SetError( 10020b57cec5SDimitry Andric thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP())); 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 10060b57cec5SDimitry Andric } 10070b57cec5SDimitry Andric 10080b57cec5SDimitry Andric SBError SBThread::UnwindInnermostExpression() { 10090b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBError, SBThread, 10100b57cec5SDimitry Andric UnwindInnermostExpression); 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric SBError sb_error; 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10150b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10160b57cec5SDimitry Andric 10170b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 10180b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 10190b57cec5SDimitry Andric sb_error.SetError(thread->UnwindInnermostExpression()); 10200b57cec5SDimitry Andric if (sb_error.Success()) 10210b57cec5SDimitry Andric thread->SetSelectedFrameByIndex(0, false); 10220b57cec5SDimitry Andric } 10230b57cec5SDimitry Andric 10240b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_error); 10250b57cec5SDimitry Andric } 10260b57cec5SDimitry Andric 10270b57cec5SDimitry Andric bool SBThread::Suspend() { 10280b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Suspend); 10290b57cec5SDimitry Andric 10300b57cec5SDimitry Andric SBError error; // Ignored 10310b57cec5SDimitry Andric return Suspend(error); 10320b57cec5SDimitry Andric } 10330b57cec5SDimitry Andric 10340b57cec5SDimitry Andric bool SBThread::Suspend(SBError &error) { 10350b57cec5SDimitry Andric LLDB_RECORD_METHOD(bool, SBThread, Suspend, (lldb::SBError &), error); 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10380b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric bool result = false; 10410b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 10420b57cec5SDimitry Andric Process::StopLocker stop_locker; 10430b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 10440b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); 10450b57cec5SDimitry Andric result = true; 10460b57cec5SDimitry Andric } else { 10470b57cec5SDimitry Andric error.SetErrorString("process is running"); 10480b57cec5SDimitry Andric } 10490b57cec5SDimitry Andric } else 10500b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 10510b57cec5SDimitry Andric return result; 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric bool SBThread::Resume() { 10550b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, Resume); 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric SBError error; // Ignored 10580b57cec5SDimitry Andric return Resume(error); 10590b57cec5SDimitry Andric } 10600b57cec5SDimitry Andric 10610b57cec5SDimitry Andric bool SBThread::Resume(SBError &error) { 10620b57cec5SDimitry Andric LLDB_RECORD_METHOD(bool, SBThread, Resume, (lldb::SBError &), error); 10630b57cec5SDimitry Andric 10640b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10650b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric bool result = false; 10680b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 10690b57cec5SDimitry Andric Process::StopLocker stop_locker; 10700b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 10710b57cec5SDimitry Andric const bool override_suspend = true; 10720b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); 10730b57cec5SDimitry Andric result = true; 10740b57cec5SDimitry Andric } else { 10750b57cec5SDimitry Andric error.SetErrorString("process is running"); 10760b57cec5SDimitry Andric } 10770b57cec5SDimitry Andric } else 10780b57cec5SDimitry Andric error.SetErrorString("this SBThread object is invalid"); 10790b57cec5SDimitry Andric return result; 10800b57cec5SDimitry Andric } 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric bool SBThread::IsSuspended() { 10830b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsSuspended); 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10860b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) 10890b57cec5SDimitry Andric return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; 10900b57cec5SDimitry Andric return false; 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric bool SBThread::IsStopped() { 10940b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, IsStopped); 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 10970b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 10980b57cec5SDimitry Andric 10990b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) 11000b57cec5SDimitry Andric return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); 11010b57cec5SDimitry Andric return false; 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric SBProcess SBThread::GetProcess() { 11050b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBThread, GetProcess); 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andric SBProcess sb_process; 11080b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 11090b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 11120b57cec5SDimitry Andric // Have to go up to the target so we can get a shared pointer to our 11130b57cec5SDimitry Andric // process... 11140b57cec5SDimitry Andric sb_process.SetSP(exe_ctx.GetProcessSP()); 11150b57cec5SDimitry Andric } 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_process); 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 11200b57cec5SDimitry Andric uint32_t SBThread::GetNumFrames() { 11210b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, GetNumFrames); 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric uint32_t num_frames = 0; 11240b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 11250b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 11280b57cec5SDimitry Andric Process::StopLocker stop_locker; 11290b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11300b57cec5SDimitry Andric num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); 11310b57cec5SDimitry Andric } 11320b57cec5SDimitry Andric } 11330b57cec5SDimitry Andric 11340b57cec5SDimitry Andric return num_frames; 11350b57cec5SDimitry Andric } 11360b57cec5SDimitry Andric 11370b57cec5SDimitry Andric SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { 11380b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t), idx); 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric SBFrame sb_frame; 11410b57cec5SDimitry Andric StackFrameSP frame_sp; 11420b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 11430b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11440b57cec5SDimitry Andric 11450b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 11460b57cec5SDimitry Andric Process::StopLocker stop_locker; 11470b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11480b57cec5SDimitry Andric frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); 11490b57cec5SDimitry Andric sb_frame.SetFrameSP(frame_sp); 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric } 11520b57cec5SDimitry Andric 11530b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_frame); 11540b57cec5SDimitry Andric } 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric lldb::SBFrame SBThread::GetSelectedFrame() { 11570b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBFrame, SBThread, GetSelectedFrame); 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric SBFrame sb_frame; 11600b57cec5SDimitry Andric StackFrameSP frame_sp; 11610b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 11620b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 11650b57cec5SDimitry Andric Process::StopLocker stop_locker; 11660b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11670b57cec5SDimitry Andric frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); 11680b57cec5SDimitry Andric sb_frame.SetFrameSP(frame_sp); 11690b57cec5SDimitry Andric } 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_frame); 11730b57cec5SDimitry Andric } 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { 11760b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t), 11770b57cec5SDimitry Andric idx); 11780b57cec5SDimitry Andric 11790b57cec5SDimitry Andric SBFrame sb_frame; 11800b57cec5SDimitry Andric StackFrameSP frame_sp; 11810b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 11820b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 11830b57cec5SDimitry Andric 11840b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 11850b57cec5SDimitry Andric Process::StopLocker stop_locker; 11860b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 11870b57cec5SDimitry Andric Thread *thread = exe_ctx.GetThreadPtr(); 11880b57cec5SDimitry Andric frame_sp = thread->GetStackFrameAtIndex(idx); 11890b57cec5SDimitry Andric if (frame_sp) { 11900b57cec5SDimitry Andric thread->SetSelectedFrame(frame_sp.get()); 11910b57cec5SDimitry Andric sb_frame.SetFrameSP(frame_sp); 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric } 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_frame); 11970b57cec5SDimitry Andric } 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric bool SBThread::EventIsThreadEvent(const SBEvent &event) { 12000b57cec5SDimitry Andric LLDB_RECORD_STATIC_METHOD(bool, SBThread, EventIsThreadEvent, 12010b57cec5SDimitry Andric (const lldb::SBEvent &), event); 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != nullptr; 12040b57cec5SDimitry Andric } 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) { 12070b57cec5SDimitry Andric LLDB_RECORD_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent, 12080b57cec5SDimitry Andric (const lldb::SBEvent &), event); 12090b57cec5SDimitry Andric 12100b57cec5SDimitry Andric return LLDB_RECORD_RESULT( 12110b57cec5SDimitry Andric Thread::ThreadEventData::GetStackFrameFromEvent(event.get())); 12120b57cec5SDimitry Andric } 12130b57cec5SDimitry Andric 12140b57cec5SDimitry Andric SBThread SBThread::GetThreadFromEvent(const SBEvent &event) { 12150b57cec5SDimitry Andric LLDB_RECORD_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent, 12160b57cec5SDimitry Andric (const lldb::SBEvent &), event); 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric return LLDB_RECORD_RESULT( 12190b57cec5SDimitry Andric Thread::ThreadEventData::GetThreadFromEvent(event.get())); 12200b57cec5SDimitry Andric } 12210b57cec5SDimitry Andric 12220b57cec5SDimitry Andric bool SBThread::operator==(const SBThread &rhs) const { 12230b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST(bool, SBThread, operator==,(const lldb::SBThread &), 12240b57cec5SDimitry Andric rhs); 12250b57cec5SDimitry Andric 12260b57cec5SDimitry Andric return m_opaque_sp->GetThreadSP().get() == 12270b57cec5SDimitry Andric rhs.m_opaque_sp->GetThreadSP().get(); 12280b57cec5SDimitry Andric } 12290b57cec5SDimitry Andric 12300b57cec5SDimitry Andric bool SBThread::operator!=(const SBThread &rhs) const { 12310b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST(bool, SBThread, operator!=,(const lldb::SBThread &), 12320b57cec5SDimitry Andric rhs); 12330b57cec5SDimitry Andric 12340b57cec5SDimitry Andric return m_opaque_sp->GetThreadSP().get() != 12350b57cec5SDimitry Andric rhs.m_opaque_sp->GetThreadSP().get(); 12360b57cec5SDimitry Andric } 12370b57cec5SDimitry Andric 12380b57cec5SDimitry Andric bool SBThread::GetStatus(SBStream &status) const { 12390b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &), 12400b57cec5SDimitry Andric status); 12410b57cec5SDimitry Andric 12420b57cec5SDimitry Andric Stream &strm = status.ref(); 12430b57cec5SDimitry Andric 12440b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 12450b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12460b57cec5SDimitry Andric 12470b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 12480b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true); 12490b57cec5SDimitry Andric } else 12500b57cec5SDimitry Andric strm.PutCString("No status"); 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andric return true; 12530b57cec5SDimitry Andric } 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric bool SBThread::GetDescription(SBStream &description) const { 12560b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, (lldb::SBStream &), 12570b57cec5SDimitry Andric description); 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric return GetDescription(description, false); 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric bool SBThread::GetDescription(SBStream &description, bool stop_format) const { 12630b57cec5SDimitry Andric LLDB_RECORD_METHOD_CONST(bool, SBThread, GetDescription, 12640b57cec5SDimitry Andric (lldb::SBStream &, bool), description, stop_format); 12650b57cec5SDimitry Andric 12660b57cec5SDimitry Andric Stream &strm = description.ref(); 12670b57cec5SDimitry Andric 12680b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 12690b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12700b57cec5SDimitry Andric 12710b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 12720b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm, 12730b57cec5SDimitry Andric LLDB_INVALID_THREAD_ID, 12740b57cec5SDimitry Andric stop_format); 12750b57cec5SDimitry Andric // strm.Printf("SBThread: tid = 0x%4.4" PRIx64, 12760b57cec5SDimitry Andric // exe_ctx.GetThreadPtr()->GetID()); 12770b57cec5SDimitry Andric } else 12780b57cec5SDimitry Andric strm.PutCString("No value"); 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric return true; 12810b57cec5SDimitry Andric } 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andric SBThread SBThread::GetExtendedBacktraceThread(const char *type) { 12840b57cec5SDimitry Andric LLDB_RECORD_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread, 12850b57cec5SDimitry Andric (const char *), type); 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock; 12880b57cec5SDimitry Andric ExecutionContext exe_ctx(m_opaque_sp.get(), lock); 12890b57cec5SDimitry Andric SBThread sb_origin_thread; 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric Process::StopLocker stop_locker; 12920b57cec5SDimitry Andric if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { 12930b57cec5SDimitry Andric if (exe_ctx.HasThreadScope()) { 12940b57cec5SDimitry Andric ThreadSP real_thread(exe_ctx.GetThreadSP()); 12950b57cec5SDimitry Andric if (real_thread) { 12960b57cec5SDimitry Andric ConstString type_const(type); 12970b57cec5SDimitry Andric Process *process = exe_ctx.GetProcessPtr(); 12980b57cec5SDimitry Andric if (process) { 12990b57cec5SDimitry Andric SystemRuntime *runtime = process->GetSystemRuntime(); 13000b57cec5SDimitry Andric if (runtime) { 13010b57cec5SDimitry Andric ThreadSP new_thread_sp( 13020b57cec5SDimitry Andric runtime->GetExtendedBacktraceThread(real_thread, type_const)); 13030b57cec5SDimitry Andric if (new_thread_sp) { 13040b57cec5SDimitry Andric // Save this in the Process' ExtendedThreadList so a strong 13050b57cec5SDimitry Andric // pointer retains the object. 13060b57cec5SDimitry Andric process->GetExtendedThreadList().AddThread(new_thread_sp); 13070b57cec5SDimitry Andric sb_origin_thread.SetThread(new_thread_sp); 13080b57cec5SDimitry Andric } 13090b57cec5SDimitry Andric } 13100b57cec5SDimitry Andric } 13110b57cec5SDimitry Andric } 13120b57cec5SDimitry Andric } 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andric return LLDB_RECORD_RESULT(sb_origin_thread); 13160b57cec5SDimitry Andric } 13170b57cec5SDimitry Andric 13180b57cec5SDimitry Andric uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { 13190b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBThread, 13200b57cec5SDimitry Andric GetExtendedBacktraceOriginatingIndexID); 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13230b57cec5SDimitry Andric if (thread_sp) 13240b57cec5SDimitry Andric return thread_sp->GetExtendedBacktraceOriginatingIndexID(); 13250b57cec5SDimitry Andric return LLDB_INVALID_INDEX32; 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric SBValue SBThread::GetCurrentException() { 13290b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBValue, SBThread, GetCurrentException); 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13320b57cec5SDimitry Andric if (!thread_sp) 13330b57cec5SDimitry Andric return LLDB_RECORD_RESULT(SBValue()); 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric return LLDB_RECORD_RESULT(SBValue(thread_sp->GetCurrentException())); 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric 13380b57cec5SDimitry Andric SBThread SBThread::GetCurrentExceptionBacktrace() { 13390b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(lldb::SBThread, SBThread, 13400b57cec5SDimitry Andric GetCurrentExceptionBacktrace); 13410b57cec5SDimitry Andric 13420b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13430b57cec5SDimitry Andric if (!thread_sp) 13440b57cec5SDimitry Andric return LLDB_RECORD_RESULT(SBThread()); 13450b57cec5SDimitry Andric 13460b57cec5SDimitry Andric return LLDB_RECORD_RESULT( 13470b57cec5SDimitry Andric SBThread(thread_sp->GetCurrentExceptionBacktrace())); 13480b57cec5SDimitry Andric } 13490b57cec5SDimitry Andric 13500b57cec5SDimitry Andric bool SBThread::SafeToCallFunctions() { 13510b57cec5SDimitry Andric LLDB_RECORD_METHOD_NO_ARGS(bool, SBThread, SafeToCallFunctions); 13520b57cec5SDimitry Andric 13530b57cec5SDimitry Andric ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); 13540b57cec5SDimitry Andric if (thread_sp) 13550b57cec5SDimitry Andric return thread_sp->SafeToCallFunctions(); 13560b57cec5SDimitry Andric return true; 13570b57cec5SDimitry Andric } 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric lldb_private::Thread *SBThread::operator->() { 13600b57cec5SDimitry Andric return get(); 13610b57cec5SDimitry Andric } 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric lldb_private::Thread *SBThread::get() { 13640b57cec5SDimitry Andric return m_opaque_sp->GetThreadSP().get(); 13650b57cec5SDimitry Andric } 13660b57cec5SDimitry Andric 13670b57cec5SDimitry Andric namespace lldb_private { 13680b57cec5SDimitry Andric namespace repro { 13690b57cec5SDimitry Andric 13700b57cec5SDimitry Andric template <> 13710b57cec5SDimitry Andric void RegisterMethods<SBThread>(Registry &R) { 13720b57cec5SDimitry Andric LLDB_REGISTER_STATIC_METHOD(const char *, SBThread, GetBroadcasterClassName, 13730b57cec5SDimitry Andric ()); 13740b57cec5SDimitry Andric LLDB_REGISTER_CONSTRUCTOR(SBThread, ()); 13750b57cec5SDimitry Andric LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::ThreadSP &)); 13760b57cec5SDimitry Andric LLDB_REGISTER_CONSTRUCTOR(SBThread, (const lldb::SBThread &)); 13770b57cec5SDimitry Andric LLDB_REGISTER_METHOD(const lldb::SBThread &, 13780b57cec5SDimitry Andric SBThread, operator=,(const lldb::SBThread &)); 13790b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(lldb::SBQueue, SBThread, GetQueue, ()); 13800b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, SBThread, IsValid, ()); 13810b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, SBThread, operator bool, ()); 13820b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, Clear, ()); 13830b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::StopReason, SBThread, GetStopReason, ()); 13840b57cec5SDimitry Andric LLDB_REGISTER_METHOD(size_t, SBThread, GetStopReasonDataCount, ()); 13850b57cec5SDimitry Andric LLDB_REGISTER_METHOD(uint64_t, SBThread, GetStopReasonDataAtIndex, 13860b57cec5SDimitry Andric (uint32_t)); 13870b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, GetStopReasonExtendedInfoAsJSON, 13880b57cec5SDimitry Andric (lldb::SBStream &)); 13890b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBThreadCollection, SBThread, 13900b57cec5SDimitry Andric GetStopReasonExtendedBacktraces, 13910b57cec5SDimitry Andric (lldb::InstrumentationRuntimeType)); 13920b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetStopReturnValue, ()); 13930b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(lldb::tid_t, SBThread, GetThreadID, ()); 13940b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(uint32_t, SBThread, GetIndexID, ()); 13950b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetName, ()); 13960b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(const char *, SBThread, GetQueueName, ()); 13970b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t, SBThread, GetQueueID, ()); 13980b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, GetInfoItemByPathAsString, 13990b57cec5SDimitry Andric (const char *, lldb::SBStream &)); 14000b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOver, (lldb::RunMode)); 14010b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOver, 14020b57cec5SDimitry Andric (lldb::RunMode, lldb::SBError &)); 14030b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepInto, (lldb::RunMode)); 14040b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepInto, 14050b57cec5SDimitry Andric (const char *, lldb::RunMode)); 14060b57cec5SDimitry Andric LLDB_REGISTER_METHOD( 14070b57cec5SDimitry Andric void, SBThread, StepInto, 14080b57cec5SDimitry Andric (const char *, uint32_t, lldb::SBError &, lldb::RunMode)); 14090b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOut, ()); 14100b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOut, (lldb::SBError &)); 14110b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, (lldb::SBFrame &)); 14120b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepOutOfFrame, 14130b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBError &)); 14140b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, (bool)); 14150b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, StepInstruction, 14160b57cec5SDimitry Andric (bool, lldb::SBError &)); 14170b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, (lldb::addr_t)); 14180b57cec5SDimitry Andric LLDB_REGISTER_METHOD(void, SBThread, RunToAddress, 14190b57cec5SDimitry Andric (lldb::addr_t, lldb::SBError &)); 14200b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepOverUntil, 14210b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBFileSpec &, uint32_t)); 14220b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 14230b57cec5SDimitry Andric (const char *)); 14240b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 14250b57cec5SDimitry Andric (const char *, bool)); 14269dba64beSDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, StepUsingScriptedThreadPlan, 14279dba64beSDimitry Andric (const char *, SBStructuredData &, bool)); 14280b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, JumpToLine, 14290b57cec5SDimitry Andric (lldb::SBFileSpec &, uint32_t)); 14300b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, ReturnFromFrame, 14310b57cec5SDimitry Andric (lldb::SBFrame &, lldb::SBValue &)); 14320b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBError, SBThread, UnwindInnermostExpression, 14330b57cec5SDimitry Andric ()); 14340b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, Suspend, ()); 14350b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, Suspend, (lldb::SBError &)); 14360b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, Resume, ()); 14370b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, Resume, (lldb::SBError &)); 14380b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, IsSuspended, ()); 14390b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, IsStopped, ()); 14400b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBProcess, SBThread, GetProcess, ()); 14410b57cec5SDimitry Andric LLDB_REGISTER_METHOD(uint32_t, SBThread, GetNumFrames, ()); 14420b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetFrameAtIndex, (uint32_t)); 14430b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, GetSelectedFrame, ()); 14440b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBFrame, SBThread, SetSelectedFrame, (uint32_t)); 14450b57cec5SDimitry Andric LLDB_REGISTER_STATIC_METHOD(bool, SBThread, EventIsThreadEvent, 14460b57cec5SDimitry Andric (const lldb::SBEvent &)); 14470b57cec5SDimitry Andric LLDB_REGISTER_STATIC_METHOD(lldb::SBFrame, SBThread, GetStackFrameFromEvent, 14480b57cec5SDimitry Andric (const lldb::SBEvent &)); 14490b57cec5SDimitry Andric LLDB_REGISTER_STATIC_METHOD(lldb::SBThread, SBThread, GetThreadFromEvent, 14500b57cec5SDimitry Andric (const lldb::SBEvent &)); 14510b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, 14520b57cec5SDimitry Andric SBThread, operator==,(const lldb::SBThread &)); 14530b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, 14540b57cec5SDimitry Andric SBThread, operator!=,(const lldb::SBThread &)); 14550b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetStatus, (lldb::SBStream &)); 14560b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription, 14570b57cec5SDimitry Andric (lldb::SBStream &)); 14580b57cec5SDimitry Andric LLDB_REGISTER_METHOD_CONST(bool, SBThread, GetDescription, 14590b57cec5SDimitry Andric (lldb::SBStream &, bool)); 14600b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetExtendedBacktraceThread, 14610b57cec5SDimitry Andric (const char *)); 14620b57cec5SDimitry Andric LLDB_REGISTER_METHOD(uint32_t, SBThread, 14630b57cec5SDimitry Andric GetExtendedBacktraceOriginatingIndexID, ()); 14640b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBValue, SBThread, GetCurrentException, ()); 14650b57cec5SDimitry Andric LLDB_REGISTER_METHOD(lldb::SBThread, SBThread, GetCurrentExceptionBacktrace, 14660b57cec5SDimitry Andric ()); 14670b57cec5SDimitry Andric LLDB_REGISTER_METHOD(bool, SBThread, SafeToCallFunctions, ()); 14685ffd83dbSDimitry Andric LLDB_REGISTER_CHAR_PTR_METHOD(size_t, SBThread, GetStopDescription); 14690b57cec5SDimitry Andric } 14700b57cec5SDimitry Andric 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric } 1473