https://github.com/felipepiovezan updated https://github.com/llvm/llvm-project/pull/152020
>From 9be92f8ead1294cc1931fe68c13dbaa8c5945423 Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan <fpiove...@apple.com> Date: Mon, 4 Aug 2025 08:32:20 -0700 Subject: [PATCH] [lldb] Guard SBFrame/SBThread methods against running processes Prior to this patch, SBFrame/SBThread methods exhibit racy behavior if called while the process is running, because they do not lock the `Process::RetRunLock` mutex. If they did, they would fail, correctly identifying that the process is not running. Some methods _attempt_ to protect against this with the pattern: ``` ExecutionContext exe_ctx(m_opaque_sp.get(), lock); // this is a different lock Process *process = exe_ctx.GetProcessPtr(); if (process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) .... do work ... ``` However, this is also racy: the constructor of `ExecutionContext` will access the frame list, which is something that can only be done once the process is stopped. With this patch: 1. The constructor of `ExecutionContext` now expects a `ProcessRunLock` as an argument. It attempts to lock the run lock, and only fills in information about frames and threads if the lock can be acquired. Callers of the constructor are expected to check the lock. 2. All uses of ExecutionContext are adjusted to conform to the above. 3. The SBThread.cpp-defined helper function ResumeNewPlan now expects a locked ProcessRunLock as _proof_ that the execution is stopped. It will unlock the mutex prior to resuming the process. This commit exposes many opportunities for early-returns, but these would increase the diff of this patch and distract from the important changes, so we opt not to do it here. --- lldb/include/lldb/API/SBFrame.h | 4 + lldb/include/lldb/Host/ProcessRunLock.h | 5 + lldb/include/lldb/Target/ExecutionContext.h | 9 +- lldb/source/API/SBFrame.cpp | 529 ++++++++++-------- lldb/source/API/SBThread.cpp | 329 ++++++----- lldb/source/Target/ExecutionContext.cpp | 12 +- .../python_api/run_locker/TestRunLocker.py | 4 +- 7 files changed, 508 insertions(+), 384 deletions(-) diff --git a/lldb/include/lldb/API/SBFrame.h b/lldb/include/lldb/API/SBFrame.h index 3635ee5a537ad..35198068814d0 100644 --- a/lldb/include/lldb/API/SBFrame.h +++ b/lldb/include/lldb/API/SBFrame.h @@ -233,6 +233,10 @@ class LLDB_API SBFrame { void SetFrameSP(const lldb::StackFrameSP &lldb_object_sp); + /// Return an SBValue with an error message warning that the process is not + /// currently stopped. + static SBValue CreateProcessIsRunningExprEvalError(); + lldb::ExecutionContextRefSP m_opaque_sp; }; diff --git a/lldb/include/lldb/Host/ProcessRunLock.h b/lldb/include/lldb/Host/ProcessRunLock.h index 94683673024d5..5efa46154a61e 100644 --- a/lldb/include/lldb/Host/ProcessRunLock.h +++ b/lldb/include/lldb/Host/ProcessRunLock.h @@ -41,9 +41,14 @@ class ProcessRunLock { class ProcessRunLocker { public: ProcessRunLocker() = default; + ProcessRunLocker(ProcessRunLocker &&other) : m_lock(other.m_lock) { + other.m_lock = nullptr; + } ~ProcessRunLocker() { Unlock(); } + bool IsLocked() const { return m_lock; } + // Try to lock the read lock, but only do so if there are no writers. bool TryLock(ProcessRunLock *lock) { if (m_lock) { diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h index aebd0d5308e72..ae6051f576fac 100644 --- a/lldb/include/lldb/Target/ExecutionContext.h +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -11,6 +11,7 @@ #include <mutex> +#include "lldb/Host/ProcessRunLock.h" #include "lldb/Target/StackID.h" #include "lldb/lldb-private.h" @@ -318,11 +319,13 @@ class ExecutionContext { // These two variants take in a locker, and grab the target, lock the API // mutex into locker, then fill in the rest of the shared pointers. ExecutionContext(const ExecutionContextRef &exe_ctx_ref, - std::unique_lock<std::recursive_mutex> &locker) - : ExecutionContext(&exe_ctx_ref, locker) {} + std::unique_lock<std::recursive_mutex> &locker, + ProcessRunLock::ProcessRunLocker &stop_locker) + : ExecutionContext(&exe_ctx_ref, locker, stop_locker) {} ExecutionContext(const ExecutionContextRef *exe_ctx_ref, - std::unique_lock<std::recursive_mutex> &locker); + std::unique_lock<std::recursive_mutex> &locker, + ProcessRunLock::ProcessRunLocker &stop_locker); // Create execution contexts from execution context scopes ExecutionContext(ExecutionContextScope *exe_scope); ExecutionContext(ExecutionContextScope &exe_scope); diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 5b69cf1ee2641..96891fee61e73 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -99,14 +99,15 @@ SBFrame::operator bool() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) - return GetFrameSP().get() != nullptr; + return GetFrameSP().get() != nullptr; } // Without a target & process we can't have a valid stack frame. @@ -118,16 +119,16 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const { SBSymbolContext sb_sym_ctx; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_sym_ctx; SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope); Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - if (StackFrame *frame = exe_ctx.GetFramePtr()) - sb_sym_ctx = frame->GetSymbolContext(scope); - } + if (StackFrame *frame = exe_ctx.GetFramePtr()) + sb_sym_ctx = frame->GetSymbolContext(scope); } return sb_sym_ctx; @@ -139,19 +140,19 @@ SBModule SBFrame::GetModule() const { SBModule sb_module; ModuleSP module_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_module; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp; - sb_module.SetSP(module_sp); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp; + sb_module.SetSP(module_sp); } } @@ -163,19 +164,19 @@ SBCompileUnit SBFrame::GetCompileUnit() const { SBCompileUnit sb_comp_unit; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_comp_unit; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - sb_comp_unit.reset( - frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + sb_comp_unit.reset( + frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit); } } @@ -187,19 +188,19 @@ SBFunction SBFrame::GetFunction() const { SBFunction sb_function; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_function; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - sb_function.reset( - frame->GetSymbolContext(eSymbolContextFunction).function); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + sb_function.reset( + frame->GetSymbolContext(eSymbolContextFunction).function); } } @@ -211,18 +212,18 @@ SBSymbol SBFrame::GetSymbol() const { SBSymbol sb_symbol; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_symbol; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol); } } @@ -234,18 +235,18 @@ SBBlock SBFrame::GetBlock() const { SBBlock sb_block; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_block; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block); } return sb_block; } @@ -255,18 +256,18 @@ SBBlock SBFrame::GetFrameBlock() const { SBBlock sb_block; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_block; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - sb_block.SetPtr(frame->GetFrameBlock()); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + sb_block.SetPtr(frame->GetFrameBlock()); } return sb_block; } @@ -276,19 +277,19 @@ SBLineEntry SBFrame::GetLineEntry() const { SBLineEntry sb_line_entry; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_line_entry; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - sb_line_entry.SetLineEntry( - frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + sb_line_entry.SetLineEntry( + frame->GetSymbolContext(eSymbolContextLineEntry).line_entry); } } return sb_line_entry; @@ -300,7 +301,10 @@ uint32_t SBFrame::GetFrameID() const { uint32_t frame_idx = UINT32_MAX; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return frame_idx; StackFrame *frame = exe_ctx.GetFramePtr(); if (frame) @@ -313,7 +317,10 @@ lldb::addr_t SBFrame::GetCFA() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return LLDB_INVALID_ADDRESS; StackFrame *frame = exe_ctx.GetFramePtr(); if (frame) @@ -326,19 +333,19 @@ addr_t SBFrame::GetPC() const { addr_t addr = LLDB_INVALID_ADDRESS; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return addr; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress( - target, AddressClass::eCode); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress( + target, AddressClass::eCode); } } @@ -350,17 +357,17 @@ bool SBFrame::SetPC(addr_t new_pc) { bool ret_val = false; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return ret_val; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - if (StackFrame *frame = exe_ctx.GetFramePtr()) { - if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { - ret_val = reg_ctx_sp->SetPC(new_pc); - } + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + ret_val = reg_ctx_sp->SetPC(new_pc); } } } @@ -373,17 +380,17 @@ addr_t SBFrame::GetSP() const { addr_t addr = LLDB_INVALID_ADDRESS; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return addr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - if (StackFrame *frame = exe_ctx.GetFramePtr()) { - if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { - addr = reg_ctx_sp->GetSP(); - } + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + addr = reg_ctx_sp->GetSP(); } } } @@ -396,17 +403,17 @@ addr_t SBFrame::GetFP() const { addr_t addr = LLDB_INVALID_ADDRESS; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return addr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - if (StackFrame *frame = exe_ctx.GetFramePtr()) { - if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { - addr = reg_ctx_sp->GetFP(); - } + if (StackFrame *frame = exe_ctx.GetFramePtr()) { + if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) { + addr = reg_ctx_sp->GetFP(); } } } @@ -419,18 +426,18 @@ SBAddress SBFrame::GetPCAddress() const { SBAddress sb_addr; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_addr; StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - sb_addr.SetAddress(frame->GetFrameCodeAddress()); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + sb_addr.SetAddress(frame->GetFrameCodeAddress()); } return sb_addr; } @@ -446,7 +453,10 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) { SBValue sb_value; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_value; StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -468,25 +478,25 @@ lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path, } std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_value; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - VariableSP var_sp; - Status error; - ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath( - var_path, eNoDynamicValues, - StackFrame::eExpressionPathOptionCheckPtrVsMember | - StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, - var_sp, error)); - sb_value.SetSP(value_sp, use_dynamic); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + VariableSP var_sp; + Status error; + ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath( + var_path, eNoDynamicValues, + StackFrame::eExpressionPathOptionCheckPtrVsMember | + StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, + var_sp, error)); + sb_value.SetSP(value_sp, use_dynamic); } } return sb_value; @@ -497,7 +507,10 @@ SBValue SBFrame::FindVariable(const char *name) { SBValue value; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return value; StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -522,21 +535,21 @@ SBValue SBFrame::FindVariable(const char *name, ValueObjectSP value_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_value; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - value_sp = frame->FindVariable(ConstString(name)); + frame = exe_ctx.GetFramePtr(); + if (frame) { + value_sp = frame->FindVariable(ConstString(name)); - if (value_sp) - sb_value.SetSP(value_sp, use_dynamic); - } + if (value_sp) + sb_value.SetSP(value_sp, use_dynamic); } } @@ -548,7 +561,10 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type) { SBValue value; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return value; StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -572,14 +588,14 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type, ValueObjectSP value_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); - StackFrame *frame = nullptr; - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { + if (stop_locker.IsLocked()) { + StackFrame *frame = nullptr; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) { frame = exe_ctx.GetFramePtr(); if (frame) { VariableList variable_list; @@ -699,7 +715,10 @@ SBThread SBFrame::GetThread() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBThread(); ThreadSP thread_sp(exe_ctx.GetThreadSP()); SBThread sb_thread(thread_sp); @@ -711,17 +730,17 @@ const char *SBFrame::Disassemble() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (!target || !process) return nullptr; - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - if (auto *frame = exe_ctx.GetFramePtr()) - return ConstString(frame->Disassemble()).GetCString(); - } + if (auto *frame = exe_ctx.GetFramePtr()) + return ConstString(frame->Disassemble()).GetCString(); return nullptr; } @@ -732,7 +751,10 @@ SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics, SBValueList value_list; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return value_list; StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -762,7 +784,12 @@ lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals, use_dynamic); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) { + SBValueList empty_list; + return empty_list; + } Target *target = exe_ctx.GetTargetPtr(); const bool include_runtime_support_values = @@ -782,27 +809,26 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { SBValueList value_list; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { - StackFrame *frame = nullptr; - Target *target = exe_ctx.GetTargetPtr(); + StackFrame *frame = nullptr; + Target *target = exe_ctx.GetTargetPtr(); - const bool statics = options.GetIncludeStatics(); - const bool arguments = options.GetIncludeArguments(); - const bool recognized_arguments = + const bool statics = options.GetIncludeStatics(); + const bool arguments = options.GetIncludeArguments(); + const bool recognized_arguments = options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP())); - const bool locals = options.GetIncludeLocals(); - const bool in_scope_only = options.GetInScopeOnly(); - const bool include_runtime_support_values = - options.GetIncludeRuntimeSupportValues(); - const lldb::DynamicValueType use_dynamic = options.GetUseDynamic(); - + const bool locals = options.GetIncludeLocals(); + const bool in_scope_only = options.GetInScopeOnly(); + const bool include_runtime_support_values = + options.GetIncludeRuntimeSupportValues(); + const lldb::DynamicValueType use_dynamic = options.GetUseDynamic(); - std::set<VariableSP> variable_set; - Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { + std::set<VariableSP> variable_set; + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) { frame = exe_ctx.GetFramePtr(); if (frame) { Debugger &dbg = process->GetTarget().GetDebugger(); @@ -893,14 +919,14 @@ SBValueList SBFrame::GetRegisters() { SBValueList value_list; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { - StackFrame *frame = nullptr; - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { + StackFrame *frame = nullptr; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) { frame = exe_ctx.GetFramePtr(); if (frame) { RegisterContextSP reg_ctx(frame->GetRegisterContext()); @@ -924,14 +950,13 @@ SBValue SBFrame::FindRegister(const char *name) { SBValue result; ValueObjectSP value_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - - StackFrame *frame = nullptr; - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { + StackFrame *frame = nullptr; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); + if (target && process) { frame = exe_ctx.GetFramePtr(); if (frame) { RegisterContextSP reg_ctx(frame->GetRegisterContext()); @@ -954,7 +979,10 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format, Stream &strm = output.ref(); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return "Process is not stopped"; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); @@ -967,13 +995,10 @@ SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format, } if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame && - frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) { - return error; - } + frame = exe_ctx.GetFramePtr(); + if (frame && + frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) { + return error; } } error.SetErrorStringWithFormat( @@ -989,20 +1014,21 @@ bool SBFrame::GetDescription(SBStream &description) { Stream &strm = description.ref(); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) { + strm.PutCString("Error: process is not stopped."); + return true; + } StackFrame *frame; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - frame->DumpUsingSettingsFormat(&strm); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + frame->DumpUsingSettingsFormat(&strm); } - } else strm.PutCString("No value"); @@ -1013,7 +1039,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr) { LLDB_INSTRUMENT_VA(this, expr); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return CreateProcessIsRunningExprEvalError(); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -1044,7 +1073,10 @@ SBFrame::EvaluateExpression(const char *expr, options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return CreateProcessIsRunningExprEvalError(); StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -1064,7 +1096,10 @@ SBValue SBFrame::EvaluateExpression(const char *expr, SBExpressionOptions options; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return CreateProcessIsRunningExprEvalError(); options.SetFetchDynamicValue(fetch_dynamic_value); options.SetUnwindOnError(unwind_on_error); @@ -1080,6 +1115,16 @@ SBValue SBFrame::EvaluateExpression(const char *expr, return EvaluateExpression(expr, options); } +lldb::SBValue SBFrame::CreateProcessIsRunningExprEvalError() { + auto error = Status::FromErrorString("can't evaluate expressions when the " + "process is running."); + ValueObjectSP expr_value_sp = + ValueObjectConstResult::Create(nullptr, std::move(error)); + SBValue expr_result; + expr_result.SetSP(expr_value_sp, false); + return expr_result; +} + lldb::SBValue SBFrame::EvaluateExpression(const char *expr, const SBExpressionOptions &options) { LLDB_INSTRUMENT_VA(this, expr, options); @@ -1095,15 +1140,15 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, ValueObjectSP expr_value_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { - StackFrame *frame = nullptr; - Target *target = exe_ctx.GetTargetPtr(); - Process *process = exe_ctx.GetProcessPtr(); + StackFrame *frame = nullptr; + Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { + if (target && process) { frame = exe_ctx.GetFramePtr(); if (frame) { std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace; @@ -1121,18 +1166,13 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); } } else { - Status error; - error = Status::FromErrorString("can't evaluate expressions when the " - "process is running."); - expr_value_sp = ValueObjectConstResult::Create(nullptr, std::move(error)); - expr_result.SetSP(expr_value_sp, false); - } - } else { Status error; error = Status::FromErrorString("sbframe object is not valid."); expr_value_sp = ValueObjectConstResult::Create(nullptr, std::move(error)); expr_result.SetSP(expr_value_sp, false); - } + } + } else + expr_result = CreateProcessIsRunningExprEvalError(); if (expr_result.GetError().Success()) LLDB_LOGF(expr_log, @@ -1153,7 +1193,10 @@ SBStructuredData SBFrame::GetLanguageSpecificData() const { SBStructuredData sb_data; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_data; StackFrame *frame = exe_ctx.GetFramePtr(); if (!frame) return sb_data; @@ -1173,18 +1216,18 @@ bool SBFrame::IsInlined() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - return frame->IsInlined(); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + return frame->IsInlined(); } return false; } @@ -1199,7 +1242,10 @@ bool SBFrame::IsArtificial() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (StackFrame *frame = exe_ctx.GetFramePtr()) return frame->IsArtificial(); @@ -1211,7 +1257,10 @@ bool SBFrame::IsHidden() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (StackFrame *frame = exe_ctx.GetFramePtr()) return frame->IsHidden(); @@ -1229,18 +1278,18 @@ lldb::LanguageType SBFrame::GuessLanguage() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return eLanguageTypeUnknown; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - return frame->GuessLanguage().AsLanguageType(); - } + frame = exe_ctx.GetFramePtr(); + if (frame) { + return frame->GuessLanguage().AsLanguageType(); } } return eLanguageTypeUnknown; @@ -1251,18 +1300,18 @@ const char *SBFrame::GetFunctionName() const { const char *name = nullptr; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return name; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - return frame->GetFunctionName(); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + return frame->GetFunctionName(); } return name; } @@ -1273,18 +1322,18 @@ const char *SBFrame::GetDisplayFunctionName() { const char *name = nullptr; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return name; StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) - return frame->GetDisplayFunctionName(); - } + frame = exe_ctx.GetFramePtr(); + if (frame) + return frame->GetDisplayFunctionName(); } return name; } diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index 74bc66c4f16f1..17d10e4dc2c2b 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -91,15 +91,15 @@ lldb::SBQueue SBThread::GetQueue() const { SBQueue sb_queue; QueueSP queue_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBQueue(); if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); - if (queue_sp) { - sb_queue.SetQueue(queue_sp); - } + queue_sp = exe_ctx.GetThreadPtr()->GetQueue(); + if (queue_sp) { + sb_queue.SetQueue(queue_sp); } } @@ -114,14 +114,15 @@ SBThread::operator bool() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) - return m_opaque_sp->GetThreadSP().get() != nullptr; + return m_opaque_sp->GetThreadSP().get() != nullptr; } // Without a valid target & process, this thread can't be valid. return false; @@ -138,13 +139,13 @@ StopReason SBThread::GetStopReason() { StopReason reason = eStopReasonInvalid; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return reason; if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - return exe_ctx.GetThreadPtr()->GetStopReason(); - } + return exe_ctx.GetThreadPtr()->GetStopReason(); } return reason; @@ -154,11 +155,10 @@ size_t SBThread::GetStopReasonDataCount() { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { + if (exe_ctx.HasThreadScope()) { StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); if (stop_info_sp) { StopReason reason = stop_info_sp->GetStopReason(); @@ -215,11 +215,10 @@ uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) { LLDB_INSTRUMENT_VA(this, idx); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { + if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); StopInfoSP stop_info_sp = thread->GetStopInfo(); if (stop_info_sp) { @@ -290,7 +289,10 @@ bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) { Stream &strm = stream.ref(); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (!exe_ctx.HasThreadScope()) return false; @@ -312,7 +314,10 @@ SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) { SBThreadCollection threads; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBThreadCollection(); if (!exe_ctx.HasThreadScope()) return SBThreadCollection(); @@ -333,7 +338,10 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { LLDB_INSTRUMENT_VA(this, dst, dst_len); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return 0; if (dst) *dst = 0; @@ -341,10 +349,6 @@ size_t SBThread::GetStopDescription(char *dst, size_t dst_len) { if (!exe_ctx.HasThreadScope()) return 0; - Process::StopLocker stop_locker; - if (!stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) - return 0; - std::string thread_stop_desc = exe_ctx.GetThreadPtr()->GetStopDescription(); if (thread_stop_desc.empty()) return 0; @@ -362,15 +366,15 @@ SBValue SBThread::GetStopReturnValue() { ValueObjectSP return_valobj_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBValue(); if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); - if (stop_info_sp) { - return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); - } + StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo(); + if (stop_info_sp) { + return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp); } } @@ -403,32 +407,30 @@ const char *SBThread::GetName() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return nullptr; if (!exe_ctx.HasThreadScope()) return nullptr; - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) - return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString(); - - return nullptr; + return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString(); } const char *SBThread::GetQueueName() const { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return nullptr; if (!exe_ctx.HasThreadScope()) return nullptr; - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) - return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString(); - - return nullptr; + return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString(); } lldb::queue_id_t SBThread::GetQueueID() const { @@ -436,13 +438,13 @@ lldb::queue_id_t SBThread::GetQueueID() const { queue_id_t id = LLDB_INVALID_QUEUE_ID; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return id; if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - id = exe_ctx.GetThreadPtr()->GetQueueID(); - } + id = exe_ctx.GetThreadPtr()->GetQueueID(); } return id; @@ -453,11 +455,10 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { bool success = false; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (stop_locker.IsLocked()) { + if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo(); if (info_root_sp) { @@ -495,7 +496,12 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { return success; } -static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan) { +static Status ResumeNewPlan(ExecutionContext &exe_ctx, ThreadPlan *new_plan, + Process::StopLocker stop_lock) { + { + assert(stop_lock.IsLocked()); + auto to_unlock = std::move(stop_lock); + } Process *process = exe_ctx.GetProcessPtr(); if (!process) return Status::FromErrorString("No process in SBThread::ResumeNewPlan"); @@ -530,7 +536,10 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { LLDB_INSTRUMENT_VA(this, stop_other_threads, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -555,7 +564,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { true, abort_other_plans, stop_other_threads, new_plan_status); } } - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); } void SBThread::StepInto(lldb::RunMode stop_other_threads) { @@ -577,7 +586,10 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, LLDB_INSTRUMENT_VA(this, target_name, end_line, error, stop_other_threads); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -618,7 +630,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, } if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -634,7 +646,10 @@ void SBThread::StepOut(SBError &error) { LLDB_INSTRUMENT_VA(this, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -653,7 +668,7 @@ void SBThread::StepOut(SBError &error) { eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -669,7 +684,10 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { LLDB_INSTRUMENT_VA(this, sb_frame, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!sb_frame.IsValid()) { error = Status::FromErrorString("passed invalid SBFrame object"); @@ -697,7 +715,7 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -713,7 +731,10 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { LLDB_INSTRUMENT_VA(this, step_over, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -726,7 +747,7 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { step_over, false, true, new_plan_status)); if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -742,7 +763,10 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { LLDB_INSTRUMENT_VA(this, addr, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -761,7 +785,7 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { abort_other_plans, target_addr, stop_other_threads, new_plan_status)); if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -774,7 +798,10 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, char path[PATH_MAX]; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_error; StackFrameSP frame_sp(sb_frame.GetFrameSP()); @@ -875,7 +902,8 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, frame_sp->GetFrameIndex(), new_plan_status)); if (new_plan_status.Success()) - sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + sb_error = + ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else sb_error = Status::FromErrorString(new_plan_status.AsCString()); } @@ -908,7 +936,10 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, SBError error; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return error; if (!exe_ctx.HasThreadScope()) { error = Status::FromErrorString("this SBThread object is invalid"); @@ -931,7 +962,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, return error; if (new_plan_status.Success()) - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + error = ResumeNewPlan(exe_ctx, new_plan_sp.get(), std::move(stop_locker)); else error = Status::FromErrorString(new_plan_status.AsCString()); @@ -944,7 +975,10 @@ SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { SBError sb_error; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_error; if (!exe_ctx.HasThreadScope()) { sb_error = Status::FromErrorString("this SBThread object is invalid"); @@ -964,7 +998,10 @@ SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) { SBError sb_error; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_error; if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); @@ -981,7 +1018,10 @@ SBError SBThread::UnwindInnermostExpression() { SBError sb_error; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return sb_error; if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); @@ -1004,17 +1044,17 @@ bool SBThread::Suspend(SBError &error) { LLDB_INSTRUMENT_VA(this, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) { + error = Status::FromErrorString("process is running"); + return false; + } bool result = false; if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); - result = true; - } else { - error = Status::FromErrorString("process is running"); - } + exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended); + result = true; } else error = Status::FromErrorString("this SBThread object is invalid"); return result; @@ -1031,18 +1071,18 @@ bool SBThread::Resume(SBError &error) { LLDB_INSTRUMENT_VA(this, error); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) { + error = Status::FromErrorString("process is running"); + return false; + } bool result = false; if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - const bool override_suspend = true; - exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); - result = true; - } else { - error = Status::FromErrorString("process is running"); - } + const bool override_suspend = true; + exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend); + result = true; } else error = Status::FromErrorString("this SBThread object is invalid"); return result; @@ -1052,7 +1092,10 @@ bool SBThread::IsSuspended() { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (exe_ctx.HasThreadScope()) return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended; @@ -1063,7 +1106,10 @@ bool SBThread::IsStopped() { LLDB_INSTRUMENT_VA(this); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (exe_ctx.HasThreadScope()) return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true); @@ -1075,7 +1121,10 @@ SBProcess SBThread::GetProcess() { SBProcess sb_process; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBProcess(); if (exe_ctx.HasThreadScope()) { // Have to go up to the target so we can get a shared pointer to our @@ -1091,13 +1140,13 @@ uint32_t SBThread::GetNumFrames() { uint32_t num_frames = 0; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return 0; if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); - } + num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); } return num_frames; @@ -1109,14 +1158,14 @@ SBFrame SBThread::GetFrameAtIndex(uint32_t idx) { SBFrame sb_frame; StackFrameSP frame_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBFrame(); if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); - sb_frame.SetFrameSP(frame_sp); - } + frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx); + sb_frame.SetFrameSP(frame_sp); } return sb_frame; @@ -1128,15 +1177,15 @@ lldb::SBFrame SBThread::GetSelectedFrame() { SBFrame sb_frame; StackFrameSP frame_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBFrame(); if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - frame_sp = - exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame); - sb_frame.SetFrameSP(frame_sp); - } + frame_sp = + exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame); + sb_frame.SetFrameSP(frame_sp); } return sb_frame; @@ -1148,17 +1197,17 @@ lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) { SBFrame sb_frame; StackFrameSP frame_sp; std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return SBFrame(); if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Thread *thread = exe_ctx.GetThreadPtr(); - frame_sp = thread->GetStackFrameAtIndex(idx); - if (frame_sp) { - thread->SetSelectedFrame(frame_sp.get()); - sb_frame.SetFrameSP(frame_sp); - } + Thread *thread = exe_ctx.GetThreadPtr(); + frame_sp = thread->GetStackFrameAtIndex(idx); + if (frame_sp) { + thread->SetSelectedFrame(frame_sp.get()); + sb_frame.SetFrameSP(frame_sp); } } @@ -1203,7 +1252,10 @@ bool SBThread::GetStatus(SBStream &status) const { Stream &strm = status.ref(); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (exe_ctx.HasThreadScope()) { exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true, @@ -1226,7 +1278,10 @@ bool SBThread::GetDescription(SBStream &description, bool stop_format) const { Stream &strm = description.ref(); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return false; if (exe_ctx.HasThreadScope()) { exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat( @@ -1248,7 +1303,10 @@ SBError SBThread::GetDescriptionWithFormat(const SBFormat &format, } std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + Process::StopLocker stop_locker; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + if (!stop_locker.IsLocked()) + return error; if (exe_ctx.HasThreadScope()) { if (exe_ctx.GetThreadPtr()->DumpUsingFormat( @@ -1268,11 +1326,10 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) { LLDB_INSTRUMENT_VA(this, type); std::unique_lock<std::recursive_mutex> lock; - ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - SBThread sb_origin_thread; - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { + ExecutionContext exe_ctx(m_opaque_sp.get(), lock, stop_locker); + SBThread sb_origin_thread; + if (stop_locker.IsLocked()) { if (exe_ctx.HasThreadScope()) { ThreadSP real_thread(exe_ctx.GetThreadSP()); if (real_thread) { diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp index 3f54ea55c9c81..cef21f7ff6d78 100644 --- a/lldb/source/Target/ExecutionContext.cpp +++ b/lldb/source/Target/ExecutionContext.cpp @@ -125,8 +125,10 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, } } -ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, - std::unique_lock<std::recursive_mutex> &lock) +ExecutionContext::ExecutionContext( + const ExecutionContextRef *exe_ctx_ref_ptr, + std::unique_lock<std::recursive_mutex> &lock, + ProcessRunLock::ProcessRunLocker &stop_locker) : m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() { if (exe_ctx_ref_ptr) { m_target_sp = exe_ctx_ref_ptr->GetTargetSP(); @@ -134,8 +136,10 @@ ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr, lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex()); m_process_sp = exe_ctx_ref_ptr->GetProcessSP(); - m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); - m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); + if (m_process_sp && stop_locker.TryLock(&m_process_sp->GetRunLock())) { + m_thread_sp = exe_ctx_ref_ptr->GetThreadSP(); + m_frame_sp = exe_ctx_ref_ptr->GetFrameSP(); + } } } } diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index b7b4941214e86..d525bbf6b406f 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -107,4 +107,6 @@ def runlocker_test(self, stop_at_entry): "script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()", result, ) - self.assertIn("sbframe object is not valid", result.GetOutput()) + self.assertIn( + "can't evaluate expressions when the process is running", result.GetOutput() + ) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits