From 9063bf462adddb79b5f011a36b47c27b5a00a33f Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Thu, 12 Sep 2013 19:15:05 +0000 Subject: [PATCH] Fixing a problem where CommandObjectThreadContinue held the thread list lock while waiting for the process to stop after a continue. llvm-svn: 190626 --- lldb/source/Commands/CommandObjectThread.cpp | 27 +++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index 265d1dd3c257..f46a2219a509 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -660,11 +660,14 @@ public: StateType state = process->GetState(); if ((state == eStateCrashed) || (state == eStateStopped) || (state == eStateSuspended)) { - Mutex::Locker locker (process->GetThreadList().GetMutex()); - const uint32_t num_threads = process->GetThreadList().GetSize(); const size_t argc = command.GetArgumentCount(); if (argc > 0) { + // These two lines appear at the beginning of both blocks in + // this if..else, but that is because we need to release the + // lock before calling process->Resume below. + Mutex::Locker locker (process->GetThreadList().GetMutex()); + const uint32_t num_threads = process->GetThreadList().GetSize(); std::vector resume_threads; for (uint32_t i=0; iGetThreadList().FindThreadByIndexID(thread_idx).get(); - + if (thread) { resume_threads.push_back(thread); @@ -693,7 +696,7 @@ public: return false; } } - + if (resume_threads.empty()) { result.AppendError ("no valid thread indexes were specified"); @@ -706,12 +709,12 @@ public: result.AppendMessageWithFormat ("Resuming thread: "); else result.AppendMessageWithFormat ("Resuming threads: "); - + for (uint32_t idx=0; idxGetThreadList().GetThreadAtIndex(idx).get(); std::vector::iterator this_thread_pos = find(resume_threads.begin(), resume_threads.end(), thread); - + if (this_thread_pos != resume_threads.end()) { resume_threads.erase(this_thread_pos); @@ -719,7 +722,7 @@ public: result.AppendMessageWithFormat ("%u, ", thread->GetIndexID()); else result.AppendMessageWithFormat ("%u ", thread->GetIndexID()); - + thread->SetResumeState (eStateRunning); } else @@ -732,6 +735,11 @@ public: } else { + // These two lines appear at the beginning of both blocks in + // this if..else, but that is because we need to release the + // lock before calling process->Resume below. + Mutex::Locker locker (process->GetThreadList().GetMutex()); + const uint32_t num_threads = process->GetThreadList().GetSize(); Thread *current_thread = process->GetThreadList().GetSelectedThread().get(); if (current_thread == NULL) { @@ -754,7 +762,8 @@ public: } } } - + + // We should not be holding the thread list lock when we do this. Error error (process->Resume()); if (error.Success()) { @@ -762,7 +771,7 @@ public: if (synchronous_execution) { state = process->WaitForProcessToStop (NULL); - + result.SetDidChangeProcessState (true); result.AppendMessageWithFormat ("Process %" PRIu64 " %s\n", process->GetID(), StateAsCString (state)); result.SetStatus (eReturnStatusSuccessFinishNoResult);