xref: /openbsd-src/gnu/llvm/lldb/source/Target/ThreadList.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1dda28197Spatrick //===-- ThreadList.cpp ----------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9be691f3bSpatrick #include <cstdlib>
10061da546Spatrick 
11061da546Spatrick #include <algorithm>
12061da546Spatrick 
13061da546Spatrick #include "lldb/Target/Process.h"
14061da546Spatrick #include "lldb/Target/RegisterContext.h"
15061da546Spatrick #include "lldb/Target/Thread.h"
16061da546Spatrick #include "lldb/Target/ThreadList.h"
17061da546Spatrick #include "lldb/Target/ThreadPlan.h"
18061da546Spatrick #include "lldb/Utility/LLDBAssert.h"
19*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
20061da546Spatrick #include "lldb/Utility/Log.h"
21061da546Spatrick #include "lldb/Utility/State.h"
22061da546Spatrick 
23061da546Spatrick using namespace lldb;
24061da546Spatrick using namespace lldb_private;
25061da546Spatrick 
ThreadList(Process * process)26061da546Spatrick ThreadList::ThreadList(Process *process)
27061da546Spatrick     : ThreadCollection(), m_process(process), m_stop_id(0),
28061da546Spatrick       m_selected_tid(LLDB_INVALID_THREAD_ID) {}
29061da546Spatrick 
ThreadList(const ThreadList & rhs)30061da546Spatrick ThreadList::ThreadList(const ThreadList &rhs)
31061da546Spatrick     : ThreadCollection(), m_process(rhs.m_process), m_stop_id(rhs.m_stop_id),
32061da546Spatrick       m_selected_tid() {
33061da546Spatrick   // Use the assignment operator since it uses the mutex
34061da546Spatrick   *this = rhs;
35061da546Spatrick }
36061da546Spatrick 
operator =(const ThreadList & rhs)37061da546Spatrick const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
38061da546Spatrick   if (this != &rhs) {
39061da546Spatrick     // Lock both mutexes to make sure neither side changes anyone on us while
40061da546Spatrick     // the assignment occurs
41061da546Spatrick     std::lock(GetMutex(), rhs.GetMutex());
42061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(GetMutex(), std::adopt_lock);
43061da546Spatrick     std::lock_guard<std::recursive_mutex> rhs_guard(rhs.GetMutex(),
44061da546Spatrick                                                     std::adopt_lock);
45061da546Spatrick 
46061da546Spatrick     m_process = rhs.m_process;
47061da546Spatrick     m_stop_id = rhs.m_stop_id;
48061da546Spatrick     m_threads = rhs.m_threads;
49061da546Spatrick     m_selected_tid = rhs.m_selected_tid;
50061da546Spatrick   }
51061da546Spatrick   return *this;
52061da546Spatrick }
53061da546Spatrick 
~ThreadList()54061da546Spatrick ThreadList::~ThreadList() {
55061da546Spatrick   // Clear the thread list. Clear will take the mutex lock which will ensure
56061da546Spatrick   // that if anyone is using the list they won't get it removed while using it.
57061da546Spatrick   Clear();
58061da546Spatrick }
59061da546Spatrick 
GetExpressionExecutionThread()60061da546Spatrick lldb::ThreadSP ThreadList::GetExpressionExecutionThread() {
61061da546Spatrick   if (m_expression_tid_stack.empty())
62061da546Spatrick     return GetSelectedThread();
63061da546Spatrick   ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back());
64061da546Spatrick   if (expr_thread_sp)
65061da546Spatrick     return expr_thread_sp;
66061da546Spatrick   else
67061da546Spatrick     return GetSelectedThread();
68061da546Spatrick }
69061da546Spatrick 
PushExpressionExecutionThread(lldb::tid_t tid)70061da546Spatrick void ThreadList::PushExpressionExecutionThread(lldb::tid_t tid) {
71061da546Spatrick   m_expression_tid_stack.push_back(tid);
72061da546Spatrick }
73061da546Spatrick 
PopExpressionExecutionThread(lldb::tid_t tid)74061da546Spatrick void ThreadList::PopExpressionExecutionThread(lldb::tid_t tid) {
75061da546Spatrick   assert(m_expression_tid_stack.back() == tid);
76061da546Spatrick   m_expression_tid_stack.pop_back();
77061da546Spatrick }
78061da546Spatrick 
GetStopID() const79061da546Spatrick uint32_t ThreadList::GetStopID() const { return m_stop_id; }
80061da546Spatrick 
SetStopID(uint32_t stop_id)81061da546Spatrick void ThreadList::SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
82061da546Spatrick 
GetSize(bool can_update)83061da546Spatrick uint32_t ThreadList::GetSize(bool can_update) {
84061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
85061da546Spatrick 
86061da546Spatrick   if (can_update)
87061da546Spatrick     m_process->UpdateThreadListIfNeeded();
88061da546Spatrick   return m_threads.size();
89061da546Spatrick }
90061da546Spatrick 
GetThreadAtIndex(uint32_t idx,bool can_update)91061da546Spatrick ThreadSP ThreadList::GetThreadAtIndex(uint32_t idx, bool can_update) {
92061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
93061da546Spatrick 
94061da546Spatrick   if (can_update)
95061da546Spatrick     m_process->UpdateThreadListIfNeeded();
96061da546Spatrick 
97061da546Spatrick   ThreadSP thread_sp;
98061da546Spatrick   if (idx < m_threads.size())
99061da546Spatrick     thread_sp = m_threads[idx];
100061da546Spatrick   return thread_sp;
101061da546Spatrick }
102061da546Spatrick 
FindThreadByID(lldb::tid_t tid,bool can_update)103061da546Spatrick ThreadSP ThreadList::FindThreadByID(lldb::tid_t tid, bool can_update) {
104061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
105061da546Spatrick 
106061da546Spatrick   if (can_update)
107061da546Spatrick     m_process->UpdateThreadListIfNeeded();
108061da546Spatrick 
109061da546Spatrick   ThreadSP thread_sp;
110061da546Spatrick   uint32_t idx = 0;
111061da546Spatrick   const uint32_t num_threads = m_threads.size();
112061da546Spatrick   for (idx = 0; idx < num_threads; ++idx) {
113061da546Spatrick     if (m_threads[idx]->GetID() == tid) {
114061da546Spatrick       thread_sp = m_threads[idx];
115061da546Spatrick       break;
116061da546Spatrick     }
117061da546Spatrick   }
118061da546Spatrick   return thread_sp;
119061da546Spatrick }
120061da546Spatrick 
FindThreadByProtocolID(lldb::tid_t tid,bool can_update)121061da546Spatrick ThreadSP ThreadList::FindThreadByProtocolID(lldb::tid_t tid, bool can_update) {
122061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
123061da546Spatrick 
124061da546Spatrick   if (can_update)
125061da546Spatrick     m_process->UpdateThreadListIfNeeded();
126061da546Spatrick 
127061da546Spatrick   ThreadSP thread_sp;
128061da546Spatrick   uint32_t idx = 0;
129061da546Spatrick   const uint32_t num_threads = m_threads.size();
130061da546Spatrick   for (idx = 0; idx < num_threads; ++idx) {
131061da546Spatrick     if (m_threads[idx]->GetProtocolID() == tid) {
132061da546Spatrick       thread_sp = m_threads[idx];
133061da546Spatrick       break;
134061da546Spatrick     }
135061da546Spatrick   }
136061da546Spatrick   return thread_sp;
137061da546Spatrick }
138061da546Spatrick 
RemoveThreadByID(lldb::tid_t tid,bool can_update)139061da546Spatrick ThreadSP ThreadList::RemoveThreadByID(lldb::tid_t tid, bool can_update) {
140061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
141061da546Spatrick 
142061da546Spatrick   if (can_update)
143061da546Spatrick     m_process->UpdateThreadListIfNeeded();
144061da546Spatrick 
145061da546Spatrick   ThreadSP thread_sp;
146061da546Spatrick   uint32_t idx = 0;
147061da546Spatrick   const uint32_t num_threads = m_threads.size();
148061da546Spatrick   for (idx = 0; idx < num_threads; ++idx) {
149061da546Spatrick     if (m_threads[idx]->GetID() == tid) {
150061da546Spatrick       thread_sp = m_threads[idx];
151061da546Spatrick       m_threads.erase(m_threads.begin() + idx);
152061da546Spatrick       break;
153061da546Spatrick     }
154061da546Spatrick   }
155061da546Spatrick   return thread_sp;
156061da546Spatrick }
157061da546Spatrick 
RemoveThreadByProtocolID(lldb::tid_t tid,bool can_update)158061da546Spatrick ThreadSP ThreadList::RemoveThreadByProtocolID(lldb::tid_t tid,
159061da546Spatrick                                               bool can_update) {
160061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
161061da546Spatrick 
162061da546Spatrick   if (can_update)
163061da546Spatrick     m_process->UpdateThreadListIfNeeded();
164061da546Spatrick 
165061da546Spatrick   ThreadSP thread_sp;
166061da546Spatrick   uint32_t idx = 0;
167061da546Spatrick   const uint32_t num_threads = m_threads.size();
168061da546Spatrick   for (idx = 0; idx < num_threads; ++idx) {
169061da546Spatrick     if (m_threads[idx]->GetProtocolID() == tid) {
170061da546Spatrick       thread_sp = m_threads[idx];
171061da546Spatrick       m_threads.erase(m_threads.begin() + idx);
172061da546Spatrick       break;
173061da546Spatrick     }
174061da546Spatrick   }
175061da546Spatrick   return thread_sp;
176061da546Spatrick }
177061da546Spatrick 
GetThreadSPForThreadPtr(Thread * thread_ptr)178061da546Spatrick ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {
179061da546Spatrick   ThreadSP thread_sp;
180061da546Spatrick   if (thread_ptr) {
181061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(GetMutex());
182061da546Spatrick 
183061da546Spatrick     uint32_t idx = 0;
184061da546Spatrick     const uint32_t num_threads = m_threads.size();
185061da546Spatrick     for (idx = 0; idx < num_threads; ++idx) {
186061da546Spatrick       if (m_threads[idx].get() == thread_ptr) {
187061da546Spatrick         thread_sp = m_threads[idx];
188061da546Spatrick         break;
189061da546Spatrick       }
190061da546Spatrick     }
191061da546Spatrick   }
192061da546Spatrick   return thread_sp;
193061da546Spatrick }
194061da546Spatrick 
GetBackingThread(const ThreadSP & real_thread)195061da546Spatrick ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) {
196061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
197061da546Spatrick 
198061da546Spatrick   ThreadSP thread_sp;
199061da546Spatrick   const uint32_t num_threads = m_threads.size();
200061da546Spatrick   for (uint32_t idx = 0; idx < num_threads; ++idx) {
201061da546Spatrick     if (m_threads[idx]->GetBackingThread() == real_thread) {
202061da546Spatrick       thread_sp = m_threads[idx];
203061da546Spatrick       break;
204061da546Spatrick     }
205061da546Spatrick   }
206061da546Spatrick   return thread_sp;
207061da546Spatrick }
208061da546Spatrick 
FindThreadByIndexID(uint32_t index_id,bool can_update)209061da546Spatrick ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) {
210061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
211061da546Spatrick 
212061da546Spatrick   if (can_update)
213061da546Spatrick     m_process->UpdateThreadListIfNeeded();
214061da546Spatrick 
215061da546Spatrick   ThreadSP thread_sp;
216061da546Spatrick   const uint32_t num_threads = m_threads.size();
217061da546Spatrick   for (uint32_t idx = 0; idx < num_threads; ++idx) {
218061da546Spatrick     if (m_threads[idx]->GetIndexID() == index_id) {
219061da546Spatrick       thread_sp = m_threads[idx];
220061da546Spatrick       break;
221061da546Spatrick     }
222061da546Spatrick   }
223061da546Spatrick   return thread_sp;
224061da546Spatrick }
225061da546Spatrick 
ShouldStop(Event * event_ptr)226061da546Spatrick bool ThreadList::ShouldStop(Event *event_ptr) {
227061da546Spatrick   // Running events should never stop, obviously...
228061da546Spatrick 
229*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::Step);
230061da546Spatrick 
231061da546Spatrick   // The ShouldStop method of the threads can do a whole lot of work, figuring
232061da546Spatrick   // out whether the thread plan conditions are met.  So we don't want to keep
233061da546Spatrick   // the ThreadList locked the whole time we are doing this.
234061da546Spatrick   // FIXME: It is possible that running code could cause new threads
235061da546Spatrick   // to be created.  If that happens, we will miss asking them whether they
236061da546Spatrick   // should stop.  This is not a big deal since we haven't had a chance to hang
237061da546Spatrick   // any interesting operations on those threads yet.
238061da546Spatrick 
239061da546Spatrick   collection threads_copy;
240061da546Spatrick   {
241061da546Spatrick     // Scope for locker
242061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(GetMutex());
243061da546Spatrick 
244061da546Spatrick     m_process->UpdateThreadListIfNeeded();
245061da546Spatrick     for (lldb::ThreadSP thread_sp : m_threads) {
246061da546Spatrick       // This is an optimization...  If we didn't let a thread run in between
247061da546Spatrick       // the previous stop and this one, we shouldn't have to consult it for
248*f6aab3d8Srobert       // ShouldStop.  So just leave it off the list we are going to inspect.
249*f6aab3d8Srobert       // If the thread didn't run but had work to do before declaring a public
250*f6aab3d8Srobert       // stop, then also include it.
251*f6aab3d8Srobert       // On Linux, if a thread-specific conditional breakpoint was hit, it won't
252061da546Spatrick       // necessarily be the thread that hit the breakpoint itself that
253061da546Spatrick       // evaluates the conditional expression, so the thread that hit the
254061da546Spatrick       // breakpoint could still be asked to stop, even though it hasn't been
255061da546Spatrick       // allowed to run since the previous stop.
256061da546Spatrick       if (thread_sp->GetTemporaryResumeState() != eStateSuspended ||
257*f6aab3d8Srobert           thread_sp->IsStillAtLastBreakpointHit()
258*f6aab3d8Srobert           || thread_sp->ShouldRunBeforePublicStop())
259061da546Spatrick         threads_copy.push_back(thread_sp);
260061da546Spatrick     }
261061da546Spatrick 
262061da546Spatrick     // It is possible the threads we were allowing to run all exited and then
263061da546Spatrick     // maybe the user interrupted or something, then fall back on looking at
264061da546Spatrick     // all threads:
265061da546Spatrick 
266061da546Spatrick     if (threads_copy.size() == 0)
267061da546Spatrick       threads_copy = m_threads;
268061da546Spatrick   }
269061da546Spatrick 
270061da546Spatrick   collection::iterator pos, end = threads_copy.end();
271061da546Spatrick 
272061da546Spatrick   if (log) {
273061da546Spatrick     log->PutCString("");
274061da546Spatrick     LLDB_LOGF(log,
275061da546Spatrick               "ThreadList::%s: %" PRIu64 " threads, %" PRIu64
276061da546Spatrick               " unsuspended threads",
277061da546Spatrick               __FUNCTION__, (uint64_t)m_threads.size(),
278061da546Spatrick               (uint64_t)threads_copy.size());
279061da546Spatrick   }
280061da546Spatrick 
281061da546Spatrick   bool did_anybody_stop_for_a_reason = false;
282061da546Spatrick 
283061da546Spatrick   // If the event is an Interrupt event, then we're going to stop no matter
284061da546Spatrick   // what.  Otherwise, presume we won't stop.
285061da546Spatrick   bool should_stop = false;
286061da546Spatrick   if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
287061da546Spatrick     LLDB_LOGF(
288061da546Spatrick         log, "ThreadList::%s handling interrupt event, should stop set to true",
289061da546Spatrick         __FUNCTION__);
290061da546Spatrick 
291061da546Spatrick     should_stop = true;
292061da546Spatrick   }
293061da546Spatrick 
294061da546Spatrick   // Now we run through all the threads and get their stop info's.  We want to
295061da546Spatrick   // make sure to do this first before we start running the ShouldStop, because
296061da546Spatrick   // one thread's ShouldStop could destroy information (like deleting a thread
297061da546Spatrick   // specific breakpoint another thread had stopped at) which could lead us to
298061da546Spatrick   // compute the StopInfo incorrectly. We don't need to use it here, we just
299061da546Spatrick   // want to make sure it gets computed.
300061da546Spatrick 
301061da546Spatrick   for (pos = threads_copy.begin(); pos != end; ++pos) {
302061da546Spatrick     ThreadSP thread_sp(*pos);
303061da546Spatrick     thread_sp->GetStopInfo();
304061da546Spatrick   }
305061da546Spatrick 
306*f6aab3d8Srobert   // If a thread needs to finish some job that can be done just on this thread
307*f6aab3d8Srobert   // before broadcastion the stop, it will signal that by returning true for
308*f6aab3d8Srobert   // ShouldRunBeforePublicStop.  This variable gathers the results from that.
309*f6aab3d8Srobert   bool a_thread_needs_to_run = false;
310061da546Spatrick   for (pos = threads_copy.begin(); pos != end; ++pos) {
311061da546Spatrick     ThreadSP thread_sp(*pos);
312061da546Spatrick 
313061da546Spatrick     // We should never get a stop for which no thread had a stop reason, but
314061da546Spatrick     // sometimes we do see this - for instance when we first connect to a
315061da546Spatrick     // remote stub.  In that case we should stop, since we can't figure out the
316061da546Spatrick     // right thing to do and stopping gives the user control over what to do in
317061da546Spatrick     // this instance.
318061da546Spatrick     //
319061da546Spatrick     // Note, this causes a problem when you have a thread specific breakpoint,
320061da546Spatrick     // and a bunch of threads hit the breakpoint, but not the thread which we
321061da546Spatrick     // are waiting for.  All the threads that are not "supposed" to hit the
322061da546Spatrick     // breakpoint are marked as having no stop reason, which is right, they
323061da546Spatrick     // should not show a stop reason.  But that triggers this code and causes
324061da546Spatrick     // us to stop seemingly for no reason.
325061da546Spatrick     //
326061da546Spatrick     // Since the only way we ever saw this error was on first attach, I'm only
327061da546Spatrick     // going to trigger set did_anybody_stop_for_a_reason to true unless this
328061da546Spatrick     // is the first stop.
329061da546Spatrick     //
330061da546Spatrick     // If this becomes a problem, we'll have to have another StopReason like
331061da546Spatrick     // "StopInfoHidden" which will look invalid everywhere but at this check.
332061da546Spatrick 
333061da546Spatrick     if (thread_sp->GetProcess()->GetStopID() > 1)
334061da546Spatrick       did_anybody_stop_for_a_reason = true;
335061da546Spatrick     else
336061da546Spatrick       did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
337061da546Spatrick 
338061da546Spatrick     const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
339*f6aab3d8Srobert 
340061da546Spatrick     if (thread_should_stop)
341061da546Spatrick       should_stop |= true;
342*f6aab3d8Srobert     else {
343*f6aab3d8Srobert       bool this_thread_forces_run = thread_sp->ShouldRunBeforePublicStop();
344*f6aab3d8Srobert       a_thread_needs_to_run |= this_thread_forces_run;
345*f6aab3d8Srobert       if (this_thread_forces_run)
346*f6aab3d8Srobert         LLDB_LOG(log,
347*f6aab3d8Srobert                  "ThreadList::{0} thread: {1:x}, "
348*f6aab3d8Srobert                  "says it needs to run before public stop.",
349*f6aab3d8Srobert                  __FUNCTION__, thread_sp->GetID());
350*f6aab3d8Srobert     }
351061da546Spatrick   }
352061da546Spatrick 
353*f6aab3d8Srobert   if (a_thread_needs_to_run) {
354*f6aab3d8Srobert     should_stop = false;
355*f6aab3d8Srobert   } else if (!should_stop && !did_anybody_stop_for_a_reason) {
356061da546Spatrick     should_stop = true;
357061da546Spatrick     LLDB_LOGF(log,
358061da546Spatrick               "ThreadList::%s we stopped but no threads had a stop reason, "
359061da546Spatrick               "overriding should_stop and stopping.",
360061da546Spatrick               __FUNCTION__);
361061da546Spatrick   }
362061da546Spatrick 
363061da546Spatrick   LLDB_LOGF(log, "ThreadList::%s overall should_stop = %i", __FUNCTION__,
364061da546Spatrick             should_stop);
365061da546Spatrick 
366061da546Spatrick   if (should_stop) {
367061da546Spatrick     for (pos = threads_copy.begin(); pos != end; ++pos) {
368061da546Spatrick       ThreadSP thread_sp(*pos);
369061da546Spatrick       thread_sp->WillStop();
370061da546Spatrick     }
371061da546Spatrick   }
372061da546Spatrick 
373061da546Spatrick   return should_stop;
374061da546Spatrick }
375061da546Spatrick 
ShouldReportStop(Event * event_ptr)376061da546Spatrick Vote ThreadList::ShouldReportStop(Event *event_ptr) {
377061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
378061da546Spatrick 
379061da546Spatrick   Vote result = eVoteNoOpinion;
380061da546Spatrick   m_process->UpdateThreadListIfNeeded();
381061da546Spatrick   collection::iterator pos, end = m_threads.end();
382061da546Spatrick 
383*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::Step);
384061da546Spatrick 
385061da546Spatrick   LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
386061da546Spatrick             (uint64_t)m_threads.size());
387061da546Spatrick 
388061da546Spatrick   // Run through the threads and ask whether we should report this event. For
389061da546Spatrick   // stopping, a YES vote wins over everything.  A NO vote wins over NO
390*f6aab3d8Srobert   // opinion.  The exception is if a thread has work it needs to force before
391*f6aab3d8Srobert   // a public stop, which overrides everyone else's opinion:
392061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
393061da546Spatrick     ThreadSP thread_sp(*pos);
394*f6aab3d8Srobert     if (thread_sp->ShouldRunBeforePublicStop()) {
395*f6aab3d8Srobert       LLDB_LOG(log, "Thread {0:x} has private business to complete, overrode "
396*f6aab3d8Srobert                "the should report stop.", thread_sp->GetID());
397*f6aab3d8Srobert       result = eVoteNo;
398*f6aab3d8Srobert       break;
399*f6aab3d8Srobert     }
400*f6aab3d8Srobert 
401061da546Spatrick     const Vote vote = thread_sp->ShouldReportStop(event_ptr);
402061da546Spatrick     switch (vote) {
403061da546Spatrick     case eVoteNoOpinion:
404061da546Spatrick       continue;
405061da546Spatrick 
406061da546Spatrick     case eVoteYes:
407061da546Spatrick       result = eVoteYes;
408061da546Spatrick       break;
409061da546Spatrick 
410061da546Spatrick     case eVoteNo:
411061da546Spatrick       if (result == eVoteNoOpinion) {
412061da546Spatrick         result = eVoteNo;
413061da546Spatrick       } else {
414061da546Spatrick         LLDB_LOG(log,
415061da546Spatrick           "Thread {0:x} voted {1}, but lost out because result was {2}",
416061da546Spatrick           thread_sp->GetID(), vote, result);
417061da546Spatrick       }
418061da546Spatrick       break;
419061da546Spatrick     }
420061da546Spatrick   }
421061da546Spatrick   LLDB_LOG(log, "Returning {0}", result);
422061da546Spatrick   return result;
423061da546Spatrick }
424061da546Spatrick 
SetShouldReportStop(Vote vote)425061da546Spatrick void ThreadList::SetShouldReportStop(Vote vote) {
426061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
427061da546Spatrick 
428061da546Spatrick   m_process->UpdateThreadListIfNeeded();
429061da546Spatrick   collection::iterator pos, end = m_threads.end();
430061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
431061da546Spatrick     ThreadSP thread_sp(*pos);
432061da546Spatrick     thread_sp->SetShouldReportStop(vote);
433061da546Spatrick   }
434061da546Spatrick }
435061da546Spatrick 
ShouldReportRun(Event * event_ptr)436061da546Spatrick Vote ThreadList::ShouldReportRun(Event *event_ptr) {
437061da546Spatrick 
438061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
439061da546Spatrick 
440061da546Spatrick   Vote result = eVoteNoOpinion;
441061da546Spatrick   m_process->UpdateThreadListIfNeeded();
442061da546Spatrick   collection::iterator pos, end = m_threads.end();
443061da546Spatrick 
444061da546Spatrick   // Run through the threads and ask whether we should report this event. The
445061da546Spatrick   // rule is NO vote wins over everything, a YES vote wins over no opinion.
446061da546Spatrick 
447*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::Step);
448061da546Spatrick 
449061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
450061da546Spatrick     if ((*pos)->GetResumeState() != eStateSuspended) {
451061da546Spatrick       switch ((*pos)->ShouldReportRun(event_ptr)) {
452061da546Spatrick       case eVoteNoOpinion:
453061da546Spatrick         continue;
454061da546Spatrick       case eVoteYes:
455061da546Spatrick         if (result == eVoteNoOpinion)
456061da546Spatrick           result = eVoteYes;
457061da546Spatrick         break;
458061da546Spatrick       case eVoteNo:
459061da546Spatrick         LLDB_LOGF(log,
460061da546Spatrick                   "ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
461061da546Spatrick                   ") says don't report.",
462061da546Spatrick                   (*pos)->GetIndexID(), (*pos)->GetID());
463061da546Spatrick         result = eVoteNo;
464061da546Spatrick         break;
465061da546Spatrick       }
466061da546Spatrick     }
467061da546Spatrick   }
468061da546Spatrick   return result;
469061da546Spatrick }
470061da546Spatrick 
Clear()471061da546Spatrick void ThreadList::Clear() {
472061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
473061da546Spatrick   m_stop_id = 0;
474061da546Spatrick   m_threads.clear();
475061da546Spatrick   m_selected_tid = LLDB_INVALID_THREAD_ID;
476061da546Spatrick }
477061da546Spatrick 
Destroy()478061da546Spatrick void ThreadList::Destroy() {
479061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
480061da546Spatrick   const uint32_t num_threads = m_threads.size();
481061da546Spatrick   for (uint32_t idx = 0; idx < num_threads; ++idx) {
482061da546Spatrick     m_threads[idx]->DestroyThread();
483061da546Spatrick   }
484061da546Spatrick }
485061da546Spatrick 
RefreshStateAfterStop()486061da546Spatrick void ThreadList::RefreshStateAfterStop() {
487061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
488061da546Spatrick 
489061da546Spatrick   m_process->UpdateThreadListIfNeeded();
490061da546Spatrick 
491*f6aab3d8Srobert   Log *log = GetLog(LLDBLog::Step);
492061da546Spatrick   if (log && log->GetVerbose())
493061da546Spatrick     LLDB_LOGF(log,
494061da546Spatrick               "Turning off notification of new threads while single stepping "
495061da546Spatrick               "a thread.");
496061da546Spatrick 
497061da546Spatrick   collection::iterator pos, end = m_threads.end();
498061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos)
499061da546Spatrick     (*pos)->RefreshStateAfterStop();
500061da546Spatrick }
501061da546Spatrick 
DiscardThreadPlans()502061da546Spatrick void ThreadList::DiscardThreadPlans() {
503061da546Spatrick   // You don't need to update the thread list here, because only threads that
504061da546Spatrick   // you currently know about have any thread plans.
505061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
506061da546Spatrick 
507061da546Spatrick   collection::iterator pos, end = m_threads.end();
508061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos)
509061da546Spatrick     (*pos)->DiscardThreadPlans(true);
510061da546Spatrick }
511061da546Spatrick 
WillResume()512061da546Spatrick bool ThreadList::WillResume() {
513061da546Spatrick   // Run through the threads and perform their momentary actions. But we only
514061da546Spatrick   // do this for threads that are running, user suspended threads stay where
515061da546Spatrick   // they are.
516061da546Spatrick 
517061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
518061da546Spatrick   m_process->UpdateThreadListIfNeeded();
519061da546Spatrick 
520061da546Spatrick   collection::iterator pos, end = m_threads.end();
521061da546Spatrick 
522061da546Spatrick   // See if any thread wants to run stopping others.  If it does, then we won't
523061da546Spatrick   // setup the other threads for resume, since they aren't going to get a
524061da546Spatrick   // chance to run.  This is necessary because the SetupForResume might add
525061da546Spatrick   // "StopOthers" plans which would then get to be part of the who-gets-to-run
526061da546Spatrick   // negotiation, but they're coming in after the fact, and the threads that
527061da546Spatrick   // are already set up should take priority.
528061da546Spatrick 
529061da546Spatrick   bool wants_solo_run = false;
530061da546Spatrick 
531061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
532061da546Spatrick     lldbassert((*pos)->GetCurrentPlan() &&
533061da546Spatrick                "thread should not have null thread plan");
534061da546Spatrick     if ((*pos)->GetResumeState() != eStateSuspended &&
535061da546Spatrick         (*pos)->GetCurrentPlan()->StopOthers()) {
536061da546Spatrick       if ((*pos)->IsOperatingSystemPluginThread() &&
537061da546Spatrick           !(*pos)->GetBackingThread())
538061da546Spatrick         continue;
539061da546Spatrick       wants_solo_run = true;
540061da546Spatrick       break;
541061da546Spatrick     }
542061da546Spatrick   }
543061da546Spatrick 
544061da546Spatrick   if (wants_solo_run) {
545*f6aab3d8Srobert     Log *log = GetLog(LLDBLog::Step);
546061da546Spatrick     if (log && log->GetVerbose())
547061da546Spatrick       LLDB_LOGF(log, "Turning on notification of new threads while single "
548061da546Spatrick                      "stepping a thread.");
549061da546Spatrick     m_process->StartNoticingNewThreads();
550061da546Spatrick   } else {
551*f6aab3d8Srobert     Log *log = GetLog(LLDBLog::Step);
552061da546Spatrick     if (log && log->GetVerbose())
553061da546Spatrick       LLDB_LOGF(log, "Turning off notification of new threads while single "
554061da546Spatrick                      "stepping a thread.");
555061da546Spatrick     m_process->StopNoticingNewThreads();
556061da546Spatrick   }
557061da546Spatrick 
558061da546Spatrick   // Give all the threads that are likely to run a last chance to set up their
559061da546Spatrick   // state before we negotiate who is actually going to get a chance to run...
560061da546Spatrick   // Don't set to resume suspended threads, and if any thread wanted to stop
561061da546Spatrick   // others, only call setup on the threads that request StopOthers...
562061da546Spatrick 
563061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
564061da546Spatrick     if ((*pos)->GetResumeState() != eStateSuspended &&
565061da546Spatrick         (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) {
566061da546Spatrick       if ((*pos)->IsOperatingSystemPluginThread() &&
567061da546Spatrick           !(*pos)->GetBackingThread())
568061da546Spatrick         continue;
569061da546Spatrick       (*pos)->SetupForResume();
570061da546Spatrick     }
571061da546Spatrick   }
572061da546Spatrick 
573061da546Spatrick   // Now go through the threads and see if any thread wants to run just itself.
574061da546Spatrick   // if so then pick one and run it.
575061da546Spatrick 
576061da546Spatrick   ThreadList run_me_only_list(m_process);
577061da546Spatrick 
578061da546Spatrick   run_me_only_list.SetStopID(m_process->GetStopID());
579061da546Spatrick 
580*f6aab3d8Srobert   // One or more threads might want to "Stop Others".  We want to handle all
581*f6aab3d8Srobert   // those requests first.  And if there is a thread that wanted to "resume
582*f6aab3d8Srobert   // before a public stop", let it get the first crack:
583*f6aab3d8Srobert   // There are two special kinds of thread that have priority for "StopOthers":
584*f6aab3d8Srobert   // a "ShouldRunBeforePublicStop thread, or the currently selected thread.  If
585*f6aab3d8Srobert   // we find one satisfying that critereon, put it here.
586*f6aab3d8Srobert   ThreadSP stop_others_thread_sp;
587061da546Spatrick 
588061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
589061da546Spatrick     ThreadSP thread_sp(*pos);
590061da546Spatrick     if (thread_sp->GetResumeState() != eStateSuspended &&
591061da546Spatrick         thread_sp->GetCurrentPlan()->StopOthers()) {
592061da546Spatrick       if ((*pos)->IsOperatingSystemPluginThread() &&
593061da546Spatrick           !(*pos)->GetBackingThread())
594061da546Spatrick         continue;
595061da546Spatrick 
596061da546Spatrick       // You can't say "stop others" and also want yourself to be suspended.
597061da546Spatrick       assert(thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
598061da546Spatrick       run_me_only_list.AddThread(thread_sp);
599*f6aab3d8Srobert 
600*f6aab3d8Srobert       if (thread_sp == GetSelectedThread())
601*f6aab3d8Srobert         stop_others_thread_sp = thread_sp;
602*f6aab3d8Srobert 
603*f6aab3d8Srobert       if (thread_sp->ShouldRunBeforePublicStop()) {
604*f6aab3d8Srobert         // This takes precedence, so if we find one of these, service it:
605*f6aab3d8Srobert         stop_others_thread_sp = thread_sp;
606061da546Spatrick         break;
607061da546Spatrick       }
608061da546Spatrick     }
609061da546Spatrick   }
610061da546Spatrick 
611061da546Spatrick   bool need_to_resume = true;
612061da546Spatrick 
613061da546Spatrick   if (run_me_only_list.GetSize(false) == 0) {
614061da546Spatrick     // Everybody runs as they wish:
615061da546Spatrick     for (pos = m_threads.begin(); pos != end; ++pos) {
616061da546Spatrick       ThreadSP thread_sp(*pos);
617061da546Spatrick       StateType run_state;
618061da546Spatrick       if (thread_sp->GetResumeState() != eStateSuspended)
619061da546Spatrick         run_state = thread_sp->GetCurrentPlan()->RunState();
620061da546Spatrick       else
621061da546Spatrick         run_state = eStateSuspended;
622061da546Spatrick       if (!thread_sp->ShouldResume(run_state))
623061da546Spatrick         need_to_resume = false;
624061da546Spatrick     }
625061da546Spatrick   } else {
626061da546Spatrick     ThreadSP thread_to_run;
627061da546Spatrick 
628*f6aab3d8Srobert     if (stop_others_thread_sp) {
629*f6aab3d8Srobert       thread_to_run = stop_others_thread_sp;
630061da546Spatrick     } else if (run_me_only_list.GetSize(false) == 1) {
631061da546Spatrick       thread_to_run = run_me_only_list.GetThreadAtIndex(0);
632061da546Spatrick     } else {
633061da546Spatrick       int random_thread =
634061da546Spatrick           (int)((run_me_only_list.GetSize(false) * (double)rand()) /
635061da546Spatrick                 (RAND_MAX + 1.0));
636061da546Spatrick       thread_to_run = run_me_only_list.GetThreadAtIndex(random_thread);
637061da546Spatrick     }
638061da546Spatrick 
639061da546Spatrick     for (pos = m_threads.begin(); pos != end; ++pos) {
640061da546Spatrick       ThreadSP thread_sp(*pos);
641061da546Spatrick       if (thread_sp == thread_to_run) {
642*f6aab3d8Srobert         // Note, a thread might be able to fulfil it's plan w/o actually
643*f6aab3d8Srobert         // resuming.  An example of this is a step that changes the current
644*f6aab3d8Srobert         // inlined function depth w/o moving the PC.  Check that here:
645061da546Spatrick         if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
646061da546Spatrick           need_to_resume = false;
647061da546Spatrick       } else
648061da546Spatrick         thread_sp->ShouldResume(eStateSuspended);
649061da546Spatrick     }
650061da546Spatrick   }
651061da546Spatrick 
652061da546Spatrick   return need_to_resume;
653061da546Spatrick }
654061da546Spatrick 
DidResume()655061da546Spatrick void ThreadList::DidResume() {
656061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
657061da546Spatrick   collection::iterator pos, end = m_threads.end();
658061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
659061da546Spatrick     // Don't clear out threads that aren't going to get a chance to run, rather
660061da546Spatrick     // leave their state for the next time around.
661061da546Spatrick     ThreadSP thread_sp(*pos);
662*f6aab3d8Srobert     if (thread_sp->GetTemporaryResumeState() != eStateSuspended)
663061da546Spatrick       thread_sp->DidResume();
664061da546Spatrick   }
665061da546Spatrick }
666061da546Spatrick 
DidStop()667061da546Spatrick void ThreadList::DidStop() {
668061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
669061da546Spatrick   collection::iterator pos, end = m_threads.end();
670061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos) {
671061da546Spatrick     // Notify threads that the process just stopped. Note, this currently
672061da546Spatrick     // assumes that all threads in the list stop when the process stops.  In
673061da546Spatrick     // the future we will want to support a debugging model where some threads
674061da546Spatrick     // continue to run while others are stopped.  We either need to handle that
675061da546Spatrick     // somehow here or create a special thread list containing only threads
676061da546Spatrick     // which will stop in the code that calls this method (currently
677061da546Spatrick     // Process::SetPrivateState).
678061da546Spatrick     ThreadSP thread_sp(*pos);
679061da546Spatrick     if (StateIsRunningState(thread_sp->GetState()))
680061da546Spatrick       thread_sp->DidStop();
681061da546Spatrick   }
682061da546Spatrick }
683061da546Spatrick 
GetSelectedThread()684061da546Spatrick ThreadSP ThreadList::GetSelectedThread() {
685061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
686061da546Spatrick   ThreadSP thread_sp = FindThreadByID(m_selected_tid);
687061da546Spatrick   if (!thread_sp.get()) {
688061da546Spatrick     if (m_threads.size() == 0)
689061da546Spatrick       return thread_sp;
690061da546Spatrick     m_selected_tid = m_threads[0]->GetID();
691061da546Spatrick     thread_sp = m_threads[0];
692061da546Spatrick   }
693061da546Spatrick   return thread_sp;
694061da546Spatrick }
695061da546Spatrick 
SetSelectedThreadByID(lldb::tid_t tid,bool notify)696061da546Spatrick bool ThreadList::SetSelectedThreadByID(lldb::tid_t tid, bool notify) {
697061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
698061da546Spatrick   ThreadSP selected_thread_sp(FindThreadByID(tid));
699061da546Spatrick   if (selected_thread_sp) {
700061da546Spatrick     m_selected_tid = tid;
701061da546Spatrick     selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
702061da546Spatrick   } else
703061da546Spatrick     m_selected_tid = LLDB_INVALID_THREAD_ID;
704061da546Spatrick 
705061da546Spatrick   if (notify)
706061da546Spatrick     NotifySelectedThreadChanged(m_selected_tid);
707061da546Spatrick 
708061da546Spatrick   return m_selected_tid != LLDB_INVALID_THREAD_ID;
709061da546Spatrick }
710061da546Spatrick 
SetSelectedThreadByIndexID(uint32_t index_id,bool notify)711061da546Spatrick bool ThreadList::SetSelectedThreadByIndexID(uint32_t index_id, bool notify) {
712061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
713061da546Spatrick   ThreadSP selected_thread_sp(FindThreadByIndexID(index_id));
714061da546Spatrick   if (selected_thread_sp.get()) {
715061da546Spatrick     m_selected_tid = selected_thread_sp->GetID();
716061da546Spatrick     selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
717061da546Spatrick   } else
718061da546Spatrick     m_selected_tid = LLDB_INVALID_THREAD_ID;
719061da546Spatrick 
720061da546Spatrick   if (notify)
721061da546Spatrick     NotifySelectedThreadChanged(m_selected_tid);
722061da546Spatrick 
723061da546Spatrick   return m_selected_tid != LLDB_INVALID_THREAD_ID;
724061da546Spatrick }
725061da546Spatrick 
NotifySelectedThreadChanged(lldb::tid_t tid)726061da546Spatrick void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid) {
727061da546Spatrick   ThreadSP selected_thread_sp(FindThreadByID(tid));
728061da546Spatrick   if (selected_thread_sp->EventTypeHasListeners(
729061da546Spatrick           Thread::eBroadcastBitThreadSelected))
730061da546Spatrick     selected_thread_sp->BroadcastEvent(
731061da546Spatrick         Thread::eBroadcastBitThreadSelected,
732061da546Spatrick         new Thread::ThreadEventData(selected_thread_sp));
733061da546Spatrick }
734061da546Spatrick 
Update(ThreadList & rhs)735061da546Spatrick void ThreadList::Update(ThreadList &rhs) {
736061da546Spatrick   if (this != &rhs) {
737061da546Spatrick     // Lock both mutexes to make sure neither side changes anyone on us while
738061da546Spatrick     // the assignment occurs
739061da546Spatrick     std::lock_guard<std::recursive_mutex> guard(GetMutex());
740061da546Spatrick 
741061da546Spatrick     m_process = rhs.m_process;
742061da546Spatrick     m_stop_id = rhs.m_stop_id;
743061da546Spatrick     m_threads.swap(rhs.m_threads);
744061da546Spatrick     m_selected_tid = rhs.m_selected_tid;
745061da546Spatrick 
746061da546Spatrick     // Now we look for threads that we are done with and make sure to clear
747061da546Spatrick     // them up as much as possible so anyone with a shared pointer will still
748061da546Spatrick     // have a reference, but the thread won't be of much use. Using
749061da546Spatrick     // std::weak_ptr for all backward references (such as a thread to a
750061da546Spatrick     // process) will eventually solve this issue for us, but for now, we need
751061da546Spatrick     // to work around the issue
752061da546Spatrick     collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
753061da546Spatrick     for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) {
754dda28197Spatrick       // If this thread has already been destroyed, we don't need to look for
755dda28197Spatrick       // it to destroy it again.
756dda28197Spatrick       if (!(*rhs_pos)->IsValid())
757dda28197Spatrick         continue;
758dda28197Spatrick 
759061da546Spatrick       const lldb::tid_t tid = (*rhs_pos)->GetID();
760061da546Spatrick       bool thread_is_alive = false;
761061da546Spatrick       const uint32_t num_threads = m_threads.size();
762061da546Spatrick       for (uint32_t idx = 0; idx < num_threads; ++idx) {
763061da546Spatrick         ThreadSP backing_thread = m_threads[idx]->GetBackingThread();
764061da546Spatrick         if (m_threads[idx]->GetID() == tid ||
765061da546Spatrick             (backing_thread && backing_thread->GetID() == tid)) {
766061da546Spatrick           thread_is_alive = true;
767061da546Spatrick           break;
768061da546Spatrick         }
769061da546Spatrick       }
770dda28197Spatrick       if (!thread_is_alive) {
771061da546Spatrick         (*rhs_pos)->DestroyThread();
772061da546Spatrick       }
773061da546Spatrick     }
774061da546Spatrick   }
775dda28197Spatrick }
776061da546Spatrick 
Flush()777061da546Spatrick void ThreadList::Flush() {
778061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(GetMutex());
779061da546Spatrick   collection::iterator pos, end = m_threads.end();
780061da546Spatrick   for (pos = m_threads.begin(); pos != end; ++pos)
781061da546Spatrick     (*pos)->Flush();
782061da546Spatrick }
783061da546Spatrick 
GetMutex() const784061da546Spatrick std::recursive_mutex &ThreadList::GetMutex() const {
785061da546Spatrick   return m_process->m_thread_mutex;
786061da546Spatrick }
787061da546Spatrick 
ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp)788061da546Spatrick ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
789061da546Spatrick     lldb::ThreadSP thread_sp)
790061da546Spatrick     : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
791061da546Spatrick   if (thread_sp) {
792061da546Spatrick     m_tid = thread_sp->GetID();
793061da546Spatrick     m_thread_list = &thread_sp->GetProcess()->GetThreadList();
794061da546Spatrick     m_thread_list->PushExpressionExecutionThread(m_tid);
795061da546Spatrick   }
796061da546Spatrick }
797