From 4fc6cb9c7685552842f39159146be23ffead16c5 Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Wed, 22 Aug 2012 21:34:33 +0000 Subject: [PATCH] Rework how the API mutex is acquired when filling out an ExecutionContext from an ExecutionContextRef, particularly in the SBThread & SBFrame interfaces. Instead of filling the whole context & then getting the API mutex, we now get only the target, acquire the API mutex from it, then fill out the rest of the context. This removes a race condition where you get a ThreadSP, then wait on the API mutex while another command Destroy's the Thread you've just gotten. Also fixed the ExecutionContextRef::Get*SP calls so they don't return invalid objects. Also fixed the ExecutionContext::Has*Scope calls so they don't claim to have a scope if the object representing that scope has been destroyed. Also fixed a think-o in Thread::IsValid which was causing it to return the opposite of the desired value. llvm-svn: 162401 --- lldb/include/lldb/Target/ExecutionContext.h | 36 +++---- lldb/include/lldb/Target/Process.h | 15 +++ lldb/include/lldb/Target/Thread.h | 2 +- lldb/source/API/SBFrame.cpp | 109 ++++++++++++-------- lldb/source/API/SBProcess.cpp | 3 +- lldb/source/API/SBThread.cpp | 90 +++++++++------- lldb/source/Target/ExecutionContext.cpp | 93 ++++++++++++++++- lldb/source/Target/Process.cpp | 2 + lldb/source/Target/Thread.cpp | 2 +- 9 files changed, 242 insertions(+), 110 deletions(-) diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h index 880de01c6891..354c8b62905a 100644 --- a/lldb/include/lldb/Target/ExecutionContext.h +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -37,6 +37,7 @@ #include "lldb/lldb-private.h" #include "lldb/Target/StackID.h" +#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -254,10 +255,7 @@ public: /// A shared pointer to a target that is not guaranteed to be valid. //------------------------------------------------------------------ lldb::TargetSP - GetTargetSP () const - { - return m_target_wp.lock(); - } + GetTargetSP () const; //------------------------------------------------------------------ /// Get accessor that creates a strong reference from the weak process @@ -267,10 +265,7 @@ public: /// A shared pointer to a process that is not guaranteed to be valid. //------------------------------------------------------------------ lldb::ProcessSP - GetProcessSP () const - { - return m_process_wp.lock(); - } + GetProcessSP () const; //------------------------------------------------------------------ /// Get accessor that creates a strong reference from the weak thread @@ -410,6 +405,11 @@ public: ExecutionContext (const lldb::StackFrameWP &frame_wp); ExecutionContext (const ExecutionContextRef &exe_ctx_ref); ExecutionContext (const ExecutionContextRef *exe_ctx_ref); + + // 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, Mutex::Locker &locker); + ExecutionContext (const ExecutionContextRef *exe_ctx_ref, Mutex::Locker &locker); //------------------------------------------------------------------ // Create execution contexts from execution context scopes //------------------------------------------------------------------ @@ -727,10 +727,7 @@ public: /// GetTargetRef() do not need to be checked for validity. //------------------------------------------------------------------ bool - HasTargetScope () const - { - return (bool) m_target_sp; - } + HasTargetScope () const; //------------------------------------------------------------------ /// Returns true the ExecutionContext object contains a valid @@ -742,10 +739,7 @@ public: /// need to be checked for validity. //------------------------------------------------------------------ bool - HasProcessScope () const - { - return m_target_sp && m_process_sp; - } + HasProcessScope () const; //------------------------------------------------------------------ /// Returns true the ExecutionContext object contains a valid @@ -757,10 +751,7 @@ public: /// and GetThreadRef() do not need to be checked for validity. //------------------------------------------------------------------ bool - HasThreadScope () const - { - return m_target_sp && m_process_sp && m_thread_sp; - } + HasThreadScope () const; //------------------------------------------------------------------ /// Returns true the ExecutionContext object contains a valid @@ -773,10 +764,7 @@ public: /// to be checked for validity. //------------------------------------------------------------------ bool - HasFrameScope () const - { - return m_target_sp && m_process_sp && m_thread_sp && m_frame_sp; - } + HasFrameScope () const; protected: //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 6bd9c8a2f8e0..b6e87855d8e9 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -1563,6 +1563,20 @@ public: //------------------------------------------------------------------ virtual void Finalize(); + + + //------------------------------------------------------------------ + /// Return whether this object is valid (i.e. has not been finalized.) + /// + /// @return + /// Returns \b true if this Process has not been finalized + /// and \b false otherwise. + //------------------------------------------------------------------ + bool + IsValid() const + { + return !m_finalize_called; + } //------------------------------------------------------------------ /// Launch a new process. @@ -3366,6 +3380,7 @@ protected: std::vector m_pre_resume_actions; ReadWriteLock m_run_lock; Predicate m_currently_handling_event; + bool m_finalize_called; enum { eCanJITDontKnow= 0, diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 6049dce98844..b8d4859a8cf5 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -692,7 +692,7 @@ public: bool IsValid () const { - return m_destroy_called; + return !m_destroy_called; } // When you implement this method, make sure you don't overwrite the m_actual_stop_info if it claims to be diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 8c0e98a4b3fd..ceab3b72bdbf 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -108,7 +108,9 @@ SBFrame::GetSymbolContext (uint32_t resolve_scope) const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBSymbolContext sb_sym_ctx; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -116,7 +118,6 @@ SBFrame::GetSymbolContext (uint32_t resolve_scope) const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext (resolve_scope)); } else @@ -139,7 +140,9 @@ SBFrame::GetModule () const LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBModule sb_module; ModuleSP module_sp; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -147,7 +150,6 @@ SBFrame::GetModule () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); module_sp = frame->GetSymbolContext (eSymbolContextModule).module_sp; sb_module.SetSP (module_sp); } @@ -170,7 +172,9 @@ SBFrame::GetCompileUnit () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBCompileUnit sb_comp_unit; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -178,7 +182,6 @@ SBFrame::GetCompileUnit () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_comp_unit.reset (frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit); } else @@ -199,7 +202,9 @@ SBFrame::GetFunction () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBFunction sb_function; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -207,7 +212,6 @@ SBFrame::GetFunction () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_function.reset(frame->GetSymbolContext (eSymbolContextFunction).function); } else @@ -228,7 +232,9 @@ SBFrame::GetSymbol () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBSymbol sb_symbol; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -236,7 +242,6 @@ SBFrame::GetSymbol () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_symbol.reset(frame->GetSymbolContext (eSymbolContextSymbol).symbol); } else @@ -256,7 +261,9 @@ SBFrame::GetBlock () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBBlock sb_block; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -264,7 +271,6 @@ SBFrame::GetBlock () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_block.SetPtr (frame->GetSymbolContext (eSymbolContextBlock).block); } else @@ -283,7 +289,9 @@ SBBlock SBFrame::GetFrameBlock () const { SBBlock sb_block; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); @@ -292,7 +300,6 @@ SBFrame::GetFrameBlock () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_block.SetPtr(frame->GetFrameBlock ()); } else @@ -312,7 +319,9 @@ SBFrame::GetLineEntry () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBLineEntry sb_line_entry; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -320,7 +329,6 @@ SBFrame::GetLineEntry () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_line_entry.SetLineEntry (frame->GetSymbolContext (eSymbolContextLineEntry).line_entry); } else @@ -357,7 +365,9 @@ SBFrame::GetPC () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -365,7 +375,6 @@ SBFrame::GetPC () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress (target); } else @@ -386,7 +395,9 @@ SBFrame::SetPC (addr_t new_pc) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); bool ret_val = false; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -394,7 +405,6 @@ SBFrame::SetPC (addr_t new_pc) Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); ret_val = frame->GetRegisterContext()->SetPC (new_pc); } else @@ -416,7 +426,9 @@ SBFrame::GetSP () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -424,7 +436,6 @@ SBFrame::GetSP () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); addr = frame->GetRegisterContext()->GetSP(); } else @@ -445,7 +456,9 @@ SBFrame::GetFP () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); addr_t addr = LLDB_INVALID_ADDRESS; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -453,7 +466,6 @@ SBFrame::GetFP () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); addr = frame->GetRegisterContext()->GetFP(); } else @@ -474,7 +486,9 @@ SBFrame::GetPCAddress () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBAddress sb_addr; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -482,7 +496,6 @@ SBFrame::GetPCAddress () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); sb_addr.SetAddress (&frame->GetFrameCodeAddress()); } else @@ -521,7 +534,9 @@ lldb::SBValue SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dynamic) { SBValue sb_value; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && var_path && var_path[0]) @@ -529,7 +544,6 @@ SBFrame::GetValueForVariablePath (const char *var_path, DynamicValueType use_dyn Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); VariableSP var_sp; Error error; ValueObjectSP value_sp (frame->GetValueForVariableExpressionPath (var_path, @@ -572,7 +586,9 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) VariableSP var_sp; SBValue sb_value; ValueObjectSP value_sp; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && name && name[0]) @@ -581,7 +597,6 @@ SBFrame::FindVariable (const char *name, lldb::DynamicValueType use_dynamic) if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { VariableList variable_list; - Mutex::Locker api_locker (target->GetAPIMutex()); SymbolContext sc (frame->GetSymbolContext (eSymbolContextBlock)); if (sc.block) @@ -640,7 +655,9 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValue sb_value; ValueObjectSP value_sp; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target && name && name[0]) @@ -648,8 +665,6 @@ SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueTy Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); - switch (value_type) { case eValueTypeVariableGlobal: // global variable @@ -810,7 +825,9 @@ SBFrame::Disassemble () const { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); const char *disassembly = NULL; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -818,7 +835,6 @@ SBFrame::Disassemble () const Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); disassembly = frame->Disassemble(); } else @@ -863,7 +879,9 @@ SBFrame::GetVariables (bool arguments, LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValueList value_list; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); @@ -883,7 +901,6 @@ SBFrame::GetVariables (bool arguments, size_t i; VariableList *variable_list = NULL; - Mutex::Locker api_locker (target->GetAPIMutex()); variable_list = frame->GetVariableList(true); if (variable_list) { @@ -948,7 +965,9 @@ SBFrame::GetRegisters () LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBValueList value_list; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -956,7 +975,6 @@ SBFrame::GetRegisters () Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); RegisterContextSP reg_ctx (frame->GetRegisterContext()); if (reg_ctx) { @@ -985,7 +1003,9 @@ SBFrame::GetDescription (SBStream &description) { Stream &strm = description.ref(); - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (frame && target) @@ -993,7 +1013,6 @@ SBFrame::GetDescription (SBStream &description) Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (target->GetAPIMutex()); frame->DumpUsingSettingsFormat (&strm); } else @@ -1042,16 +1061,16 @@ SBFrame::EvaluateExpression (const char *expr, lldb::DynamicValueType fetch_dyna SBValue expr_result; ValueObjectSP expr_value_sp; - ExecutionContext exe_ctx(m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrame *frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); if (log) log->Printf ("SBFrame(%p)::EvaluateExpression (expr=\"%s\")...", frame, expr); if (frame && target) - { - Mutex::Locker api_locker (target->GetAPIMutex()); - + { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 129f887108d1..e5569040c400 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -102,7 +102,8 @@ SBProcess::Clear () bool SBProcess::IsValid() const { - return m_opaque_wp.lock().get() != NULL; + ProcessSP process_sp(m_opaque_wp.lock()); + return ((bool) process_sp && process_sp->IsValid()); } bool diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index b831a4fcb89f..fd692641f08f 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -96,13 +96,14 @@ SBThread::GetStopReason() LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); StopReason reason = eStopReasonInvalid; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); if (stop_info_sp) reason = stop_info_sp->GetStopReason(); @@ -124,13 +125,14 @@ SBThread::GetStopReason() size_t SBThread::GetStopReasonDataCount () { - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); if (stop_info_sp) { @@ -179,14 +181,14 @@ SBThread::GetStopReasonDataCount () uint64_t SBThread::GetStopReasonDataAtIndex (uint32_t idx) { - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); Thread *thread = exe_ctx.GetThreadPtr(); StopInfoSP stop_info_sp = thread->GetStopInfo (); if (stop_info_sp) @@ -253,14 +255,15 @@ SBThread::GetStopDescription (char *dst, size_t dst_len) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); if (stop_info_sp) { @@ -366,13 +369,14 @@ SBThread::GetStopReturnValue () { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); ValueObjectSP return_valobj_sp; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo (); if (stop_info_sp) { @@ -425,13 +429,14 @@ SBThread::GetName () const { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); const char *name = NULL; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); name = exe_ctx.GetThreadPtr()->GetName(); } else @@ -451,14 +456,15 @@ const char * SBThread::GetQueueName () const { const char *name = NULL; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); name = exe_ctx.GetThreadPtr()->GetQueueName(); } else @@ -521,7 +527,9 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (log) log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), @@ -529,7 +537,6 @@ SBThread::StepOver (lldb::RunMode stop_other_threads) if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); Thread *thread = exe_ctx.GetThreadPtr(); bool abort_other_plans = false; StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); @@ -566,14 +573,14 @@ SBThread::StepInto (lldb::RunMode stop_other_threads) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); if (log) log->Printf ("SBThread(%p)::StepInto (stop_other_threads='%s')", exe_ctx.GetThreadPtr(), Thread::RunModeAsCString (stop_other_threads)); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); bool abort_other_plans = false; Thread *thread = exe_ctx.GetThreadPtr(); @@ -608,14 +615,15 @@ SBThread::StepOut () { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (log) log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr()); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); bool abort_other_plans = false; bool stop_other_threads = true; @@ -639,7 +647,9 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) { @@ -650,7 +660,6 @@ SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame) if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); bool abort_other_plans = false; bool stop_other_threads = true; Thread *thread = exe_ctx.GetThreadPtr(); @@ -673,7 +682,9 @@ SBThread::StepInstruction (bool step_over) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (log) @@ -681,7 +692,6 @@ SBThread::StepInstruction (bool step_over) if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); Thread *thread = exe_ctx.GetThreadPtr(); ThreadPlan *new_plan = thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true); @@ -695,14 +705,15 @@ SBThread::RunToAddress (lldb::addr_t addr) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (log) log->Printf ("SBThread(%p)::RunToAddress (addr=0x%llx)", exe_ctx.GetThreadPtr(), addr); if (exe_ctx.HasThreadScope()) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); bool abort_other_plans = false; bool stop_other_threads = true; @@ -726,7 +737,9 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); char path[PATH_MAX]; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + StackFrameSP frame_sp (sb_frame.GetFrameSP()); if (log) @@ -744,7 +757,6 @@ SBThread::StepOverUntil (lldb::SBFrame &sb_frame, if (exe_ctx.HasThreadScope()) { Target *target = exe_ctx.GetTargetPtr(); - Mutex::Locker api_locker (target->GetAPIMutex()); Thread *thread = exe_ctx.GetThreadPtr(); if (line == 0) @@ -956,13 +968,14 @@ SBThread::GetNumFrames () LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); uint32_t num_frames = 0; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount(); } else @@ -985,13 +998,14 @@ SBThread::GetFrameAtIndex (uint32_t idx) SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx); sb_frame.SetFrameSP (frame_sp); } @@ -1020,13 +1034,14 @@ SBThread::GetSelectedFrame () SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame (); sb_frame.SetFrameSP (frame_sp); } @@ -1055,13 +1070,14 @@ SBThread::SetSelectedFrame (uint32_t idx) SBFrame sb_frame; StackFrameSP frame_sp; - ExecutionContext exe_ctx (m_opaque_sp.get()); + Mutex::Locker api_locker; + ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker); + if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - Mutex::Locker api_locker (exe_ctx.GetTargetPtr()->GetAPIMutex()); Thread *thread = exe_ctx.GetThreadPtr(); frame_sp = thread->GetStackFrameAtIndex (idx); if (frame_sp) diff --git a/lldb/source/Target/ExecutionContext.cpp b/lldb/source/Target/ExecutionContext.cpp index 300e87922171..ae3fc20d028f 100644 --- a/lldb/source/Target/ExecutionContext.cpp +++ b/lldb/source/Target/ExecutionContext.cpp @@ -169,6 +169,40 @@ ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr) } } +ExecutionContext::ExecutionContext (const ExecutionContextRef *exe_ctx_ref_ptr, Mutex::Locker &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(); + if (m_target_sp) + { + locker.Lock(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(); + } + } +} + +ExecutionContext::ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker) : + m_target_sp (exe_ctx_ref.GetTargetSP()), + m_process_sp (), + m_thread_sp (), + m_frame_sp () +{ + if (m_target_sp) + { + locker.Lock(m_target_sp->GetAPIMutex()); + m_process_sp = exe_ctx_ref.GetProcessSP(); + m_thread_sp = exe_ctx_ref.GetThreadSP(); + m_frame_sp = exe_ctx_ref.GetFrameSP(); + } +} + ExecutionContext::ExecutionContext (ExecutionContextScope *exe_scope_ptr) : m_target_sp (), m_process_sp (), @@ -459,6 +493,32 @@ ExecutionContext::operator !=(const ExecutionContext &rhs) const return !(*this == rhs); } +bool +ExecutionContext::HasTargetScope () const +{ + return ((bool) m_target_sp + && m_target_sp->IsValid()); +} + +bool +ExecutionContext::HasProcessScope () const +{ + return (HasTargetScope() + && ((bool) m_process_sp && m_process_sp->IsValid())); +} + +bool +ExecutionContext::HasThreadScope () const +{ + return (HasProcessScope() + && ((bool) m_thread_sp && m_thread_sp->IsValid())); +} + +bool +ExecutionContext::HasFrameScope () const +{ + return HasThreadScope() && m_frame_sp; +} ExecutionContextRef::ExecutionContextRef() : m_target_wp (), @@ -703,11 +763,29 @@ ExecutionContextRef::SetFramePtr (StackFrame *frame) Clear(); } +lldb::TargetSP +ExecutionContextRef::GetTargetSP () const +{ + lldb::TargetSP target_sp(m_target_wp.lock()); + if (target_sp && !target_sp->IsValid()) + target_sp.reset(); + return target_sp; +} + +lldb::ProcessSP +ExecutionContextRef::GetProcessSP () const +{ + lldb::ProcessSP process_sp(m_process_wp.lock()); + if (process_sp && !process_sp->IsValid()) + process_sp.reset(); + return process_sp; +} lldb::ThreadSP ExecutionContextRef::GetThreadSP () const { lldb::ThreadSP thread_sp (m_thread_wp.lock()); + if (m_tid != LLDB_INVALID_THREAD_ID) { // We check if the thread has been destroyed in cases where clients @@ -716,13 +794,20 @@ ExecutionContextRef::GetThreadSP () const if (!thread_sp || !thread_sp->IsValid()) { lldb::ProcessSP process_sp(GetProcessSP()); - if (process_sp) + if (process_sp && process_sp->IsValid()) { thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid); m_thread_wp = thread_sp; } } } + + // Check that we aren't about to return an invalid thread sp. We might return a NULL thread_sp, + // but don't return an invalid one. + + if (thread_sp && !thread_sp->IsValid()) + thread_sp.reset(); + return thread_sp; } @@ -738,6 +823,12 @@ ExecutionContextRef::GetFrameSP () const frame_sp = thread_sp->GetFrameWithStackID (m_stack_id); m_frame_wp = frame_sp; } + else + { + // If the thread that this frame was supposed to belong to is not valid, then + // return a NULL frame_sp. + frame_sp.reset(); + } } return frame_sp; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 29f3793c3600..454cf3a51e6c 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -921,6 +921,7 @@ Process::Process(Target &target, Listener &listener) : m_next_event_action_ap(), m_run_lock (), m_currently_handling_event(false), + m_finalize_called(false), m_can_jit(eCanJITDontKnow) { CheckInWithManager (); @@ -1016,6 +1017,7 @@ Process::Finalize() m_allocated_memory_cache.Clear(); m_language_runtimes.clear(); m_next_event_action_ap.reset(); + m_finalize_called = true; } void diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index df86869cc335..7ff006c6bce4 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -708,7 +708,7 @@ Thread::PopPlan () { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (m_plan_stack.empty()) + if (m_plan_stack.size() <= 1) return; else {