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.

<rdar://problem/11995490>

llvm-svn: 162401
This commit is contained in:
Jim Ingham 2012-08-22 21:34:33 +00:00
parent 1e4f425d2f
commit 4fc6cb9c76
9 changed files with 242 additions and 110 deletions

View File

@ -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:
//------------------------------------------------------------------

View File

@ -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<PreResumeCallbackAndBaton> m_pre_resume_actions;
ReadWriteLock m_run_lock;
Predicate<bool> m_currently_handling_event;
bool m_finalize_called;
enum {
eCanJITDontKnow= 0,

View File

@ -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

View File

@ -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()))
{

View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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
{