Take the API lock in SBThread::IsValid & SBFrame::IsValid.

The IsValid calls can try to reconstruct the thread & frame, which can 
take various internal locks.  This can cause A/B locking issues with
the Target lock, so these calls need to that the Target lock.

llvm-svn: 268828
This commit is contained in:
Jim Ingham 2016-05-07 00:54:56 +00:00
parent 8bbfdcd181
commit 7fa7dc36fe
2 changed files with 27 additions and 2 deletions

View File

@ -105,7 +105,20 @@ SBFrame::SetFrameSP (const StackFrameSP &lldb_object_sp)
bool
SBFrame::IsValid() const
{
return GetFrameSP().get() != nullptr;
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
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;
}
// Without a target & process we can't have a valid stack frame.
return false;
}
SBSymbolContext

View File

@ -130,7 +130,19 @@ SBThread::GetQueue () const
bool
SBThread::IsValid() const
{
return m_opaque_sp->GetThreadSP().get() != NULL;
Mutex::Locker api_locker;
ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
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() != NULL;
}
// Without a valid target & process, this thread can't be valid.
return false;
}
void