diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target/ThreadList.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Target/ThreadList.cpp | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp index d581a7c96060..a34cb0fa143a 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp @@ -6,10 +6,15 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + +// C Includes #include <stdlib.h> +// C++ Includes #include <algorithm> +// Other libraries and framework includes +// Project includes #include "lldb/Core/Log.h" #include "lldb/Core/State.h" #include "lldb/Target/RegisterContext.h" @@ -18,6 +23,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/Process.h" #include "lldb/Utility/ConvertEnum.h" +#include "lldb/Utility/LLDBAssert.h" using namespace lldb; using namespace lldb_private; @@ -46,7 +52,7 @@ ThreadList::operator = (const ThreadList& rhs) if (this != &rhs) { // Lock both mutexes to make sure neither side changes anyone on us - // while the assignement occurs + // while the assignment occurs Mutex::Locker locker(GetMutex()); m_process = rhs.m_process; m_stop_id = rhs.m_stop_id; @@ -257,7 +263,24 @@ ThreadList::ShouldStop (Event *event_ptr) Mutex::Locker locker(GetMutex()); m_process->UpdateThreadListIfNeeded(); - threads_copy = m_threads; + for (lldb::ThreadSP thread_sp : m_threads) + { + // This is an optimization... If we didn't let a thread run in between the previous stop and this + // one, we shouldn't have to consult it for ShouldStop. So just leave it off the list we are going to + // inspect. + // On Linux, if a thread-specific conditional breakpoint was hit, it won't necessarily be the thread + // that hit the breakpoint itself that evaluates the conditional expression, so the thread that hit + // the breakpoint could still be asked to stop, even though it hasn't been allowed to run since the + // previous stop. + if (thread_sp->GetTemporaryResumeState () != eStateSuspended || thread_sp->IsStillAtLastBreakpointHit()) + threads_copy.push_back(thread_sp); + } + + // It is possible the threads we were allowing to run all exited and then maybe the user interrupted + // or something, then fall back on looking at all threads: + + if (threads_copy.size() == 0) + threads_copy = m_threads; } collection::iterator pos, end = threads_copy.end(); @@ -265,7 +288,10 @@ ThreadList::ShouldStop (Event *event_ptr) if (log) { log->PutCString(""); - log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size()); + log->Printf ("ThreadList::%s: %" PRIu64 " threads, %" PRIu64 " unsuspended threads", + __FUNCTION__, + (uint64_t)m_threads.size(), + (uint64_t)threads_copy.size()); } bool did_anybody_stop_for_a_reason = false; @@ -518,6 +544,7 @@ ThreadList::WillResume () for (pos = m_threads.begin(); pos != end; ++pos) { + lldbassert((*pos)->GetCurrentPlan() && "thread should not have null thread plan"); if ((*pos)->GetResumeState() != eStateSuspended && (*pos)->GetCurrentPlan()->StopOthers()) { @@ -750,7 +777,7 @@ ThreadList::Update (ThreadList &rhs) if (this != &rhs) { // Lock both mutexes to make sure neither side changes anyone on us - // while the assignement occurs + // while the assignment occurs Mutex::Locker locker(GetMutex()); m_process = rhs.m_process; m_stop_id = rhs.m_stop_id; @@ -773,7 +800,8 @@ ThreadList::Update (ThreadList &rhs) const uint32_t num_threads = m_threads.size(); for (uint32_t idx = 0; idx < num_threads; ++idx) { - if (m_threads[idx]->GetID() == tid) + ThreadSP backing_thread = m_threads[idx]->GetBackingThread(); + if (m_threads[idx]->GetID() == tid || (backing_thread && backing_thread->GetID() == tid)) { thread_is_alive = true; break; |