Don't hold the ThreadList lock over calls to the GetStatus (Process or Thread) calls
or the lower levels of the Process won't be able to restart. <rdar://problem/16244835> llvm-svn: 203233
This commit is contained in:
parent
a04ef756d4
commit
4a65fb1f25
|
@ -2864,7 +2864,8 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Lock the thread list so it doesn't change on us
|
||||
// Lock the thread list so it doesn't change on us, this is the scope for the locker:
|
||||
{
|
||||
ThreadList &thread_list = process_sp->GetThreadList();
|
||||
Mutex::Locker locker (thread_list.GetMutex());
|
||||
|
||||
|
@ -2924,6 +2925,10 @@ Debugger::HandleProcessEvent (const EventSP &event_sp)
|
|||
thread_list.SetSelectedThreadByID (thread->GetID());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drop the ThreadList mutex by here, since GetThreadStatus below might have to run code,
|
||||
// e.g. for Data formatters, and if we hold the ThreadList mutex, then the process is going to
|
||||
// have a hard time restarting the process.
|
||||
|
||||
if (GetTargetList().GetSelectedTarget().get() == &process_sp->GetTarget())
|
||||
{
|
||||
|
|
|
@ -5897,25 +5897,47 @@ Process::GetThreadStatus (Stream &strm,
|
|||
{
|
||||
size_t num_thread_infos_dumped = 0;
|
||||
|
||||
// You can't hold the thread list lock while calling Thread::GetStatus. That very well might run code (e.g. if we need it
|
||||
// to get return values or arguments.) For that to work the process has to be able to acquire it. So instead copy the thread
|
||||
// ID's, and look them up one by one:
|
||||
|
||||
uint32_t num_threads;
|
||||
std::vector<uint32_t> thread_index_array;
|
||||
//Scope for thread list locker;
|
||||
{
|
||||
Mutex::Locker locker (GetThreadList().GetMutex());
|
||||
const size_t num_threads = GetThreadList().GetSize();
|
||||
ThreadList &curr_thread_list = GetThreadList();
|
||||
num_threads = curr_thread_list.GetSize();
|
||||
uint32_t idx;
|
||||
thread_index_array.resize(num_threads);
|
||||
for (idx = 0; idx < num_threads; ++idx)
|
||||
thread_index_array[idx] = curr_thread_list.GetThreadAtIndex(idx)->GetID();
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_threads; i++)
|
||||
{
|
||||
Thread *thread = GetThreadList().GetThreadAtIndex(i).get();
|
||||
if (thread)
|
||||
ThreadSP thread_sp(GetThreadList().FindThreadByID(thread_index_array[i]));
|
||||
if (thread_sp)
|
||||
{
|
||||
if (only_threads_with_stop_reason)
|
||||
{
|
||||
StopInfoSP stop_info_sp = thread->GetStopInfo();
|
||||
StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
|
||||
if (stop_info_sp.get() == NULL || !stop_info_sp->IsValid())
|
||||
continue;
|
||||
}
|
||||
thread->GetStatus (strm,
|
||||
thread_sp->GetStatus (strm,
|
||||
start_frame,
|
||||
num_frames,
|
||||
num_frames_with_source);
|
||||
++num_thread_infos_dumped;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
|
||||
if (log)
|
||||
log->Printf("Process::GetThreadStatus - thread 0x" PRIu64 " vanished while running Thread::GetStatus.");
|
||||
|
||||
}
|
||||
}
|
||||
return num_thread_infos_dumped;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue