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