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

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