Author: jingham Date: Fri May 6 19:54:56 2016 New Revision: 268828 URL: http://llvm.org/viewvc/llvm-project?rev=268828&view=rev Log: 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. Modified: lldb/trunk/source/API/SBFrame.cpp lldb/trunk/source/API/SBThread.cpp Modified: lldb/trunk/source/API/SBFrame.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBFrame.cpp?rev=268828&r1=268827&r2=268828&view=diff ============================================================================== --- lldb/trunk/source/API/SBFrame.cpp (original) +++ lldb/trunk/source/API/SBFrame.cpp Fri May 6 19:54:56 2016 @@ -105,7 +105,20 @@ SBFrame::SetFrameSP (const StackFrameSP 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 Modified: lldb/trunk/source/API/SBThread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBThread.cpp?rev=268828&r1=268827&r2=268828&view=diff ============================================================================== --- lldb/trunk/source/API/SBThread.cpp (original) +++ lldb/trunk/source/API/SBThread.cpp Fri May 6 19:54:56 2016 @@ -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 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits