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>
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@162401 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBThread.cpp b/source/API/SBThread.cpp
index b831a4f..fd69264 100644
--- a/source/API/SBThread.cpp
+++ b/source/API/SBThread.cpp
@@ -96,13 +96,14 @@
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 @@
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 @@
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 @@
{
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 @@
{
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 @@
{
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 @@
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 @@
{
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 @@
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 @@
{
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 @@
{
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 @@
{
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 @@
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 @@
{
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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)