diff options
author | Jim Ingham <jingham@apple.com> | 2014-03-07 11:20:03 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2014-03-07 11:20:03 +0000 |
commit | 4a65fb1f2571543206825b47e91827b1550f4c88 (patch) | |
tree | a50ae15e3916fb6a0d326b3707be3f8d5a1d0432 /lldb/source/Core/Debugger.cpp | |
parent | a04ef756d46ea03d0e70fe092b1162a2903a9990 (diff) | |
download | bcm5719-llvm-4a65fb1f2571543206825b47e91827b1550f4c88.tar.gz bcm5719-llvm-4a65fb1f2571543206825b47e91827b1550f4c88.zip |
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
Diffstat (limited to 'lldb/source/Core/Debugger.cpp')
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 111 |
1 files changed, 58 insertions, 53 deletions
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 064f278fb69..923d85904b7 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -2864,66 +2864,71 @@ Debugger::HandleProcessEvent (const EventSP &event_sp) } else { - // Lock the thread list so it doesn't change on us - ThreadList &thread_list = process_sp->GetThreadList(); - Mutex::Locker locker (thread_list.GetMutex()); - - ThreadSP curr_thread (thread_list.GetSelectedThread()); - ThreadSP thread; - StopReason curr_thread_stop_reason = eStopReasonInvalid; - if (curr_thread) - curr_thread_stop_reason = curr_thread->GetStopReason(); - if (!curr_thread || - !curr_thread->IsValid() || - curr_thread_stop_reason == eStopReasonInvalid || - curr_thread_stop_reason == eStopReasonNone) + // Lock the thread list so it doesn't change on us, this is the scope for the locker: { - // Prefer a thread that has just completed its plan over another thread as current thread. - ThreadSP plan_thread; - ThreadSP other_thread; - const size_t num_threads = thread_list.GetSize(); - size_t i; - for (i = 0; i < num_threads; ++i) + ThreadList &thread_list = process_sp->GetThreadList(); + Mutex::Locker locker (thread_list.GetMutex()); + + ThreadSP curr_thread (thread_list.GetSelectedThread()); + ThreadSP thread; + StopReason curr_thread_stop_reason = eStopReasonInvalid; + if (curr_thread) + curr_thread_stop_reason = curr_thread->GetStopReason(); + if (!curr_thread || + !curr_thread->IsValid() || + curr_thread_stop_reason == eStopReasonInvalid || + curr_thread_stop_reason == eStopReasonNone) { - thread = thread_list.GetThreadAtIndex(i); - StopReason thread_stop_reason = thread->GetStopReason(); - switch (thread_stop_reason) + // Prefer a thread that has just completed its plan over another thread as current thread. + ThreadSP plan_thread; + ThreadSP other_thread; + const size_t num_threads = thread_list.GetSize(); + size_t i; + for (i = 0; i < num_threads; ++i) { - case eStopReasonInvalid: - case eStopReasonNone: - break; - - case eStopReasonTrace: - case eStopReasonBreakpoint: - case eStopReasonWatchpoint: - case eStopReasonSignal: - case eStopReasonException: - case eStopReasonExec: - case eStopReasonThreadExiting: - if (!other_thread) - other_thread = thread; - break; - case eStopReasonPlanComplete: - if (!plan_thread) - plan_thread = thread; - break; + thread = thread_list.GetThreadAtIndex(i); + StopReason thread_stop_reason = thread->GetStopReason(); + switch (thread_stop_reason) + { + case eStopReasonInvalid: + case eStopReasonNone: + break; + + case eStopReasonTrace: + case eStopReasonBreakpoint: + case eStopReasonWatchpoint: + case eStopReasonSignal: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonThreadExiting: + if (!other_thread) + other_thread = thread; + break; + case eStopReasonPlanComplete: + if (!plan_thread) + plan_thread = thread; + break; + } } - } - if (plan_thread) - thread_list.SetSelectedThreadByID (plan_thread->GetID()); - else if (other_thread) - thread_list.SetSelectedThreadByID (other_thread->GetID()); - else - { - if (curr_thread && curr_thread->IsValid()) - thread = curr_thread; + if (plan_thread) + thread_list.SetSelectedThreadByID (plan_thread->GetID()); + else if (other_thread) + thread_list.SetSelectedThreadByID (other_thread->GetID()); else - thread = thread_list.GetThreadAtIndex(0); - - if (thread) - thread_list.SetSelectedThreadByID (thread->GetID()); + { + if (curr_thread && curr_thread->IsValid()) + thread = curr_thread; + else + thread = thread_list.GetThreadAtIndex(0); + + if (thread) + 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()) { |