aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target/ThreadList.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Target/ThreadList.cpp38
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;