1 //===-- ThreadList.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/RegisterContext.h"
15 #include "lldb/Target/Thread.h"
16 #include "lldb/Target/ThreadList.h"
17 #include "lldb/Target/ThreadPlan.h"
18 #include "lldb/Utility/LLDBAssert.h"
19 #include "lldb/Utility/LLDBLog.h"
20 #include "lldb/Utility/Log.h"
21 #include "lldb/Utility/State.h"
24 using namespace lldb_private
;
26 ThreadList::ThreadList(Process
*process
)
27 : ThreadCollection(), m_process(process
), m_stop_id(0),
28 m_selected_tid(LLDB_INVALID_THREAD_ID
) {}
30 ThreadList::ThreadList(const ThreadList
&rhs
)
31 : ThreadCollection(), m_process(rhs
.m_process
), m_stop_id(rhs
.m_stop_id
),
33 // Use the assignment operator since it uses the mutex
37 const ThreadList
&ThreadList::operator=(const ThreadList
&rhs
) {
39 // Lock both mutexes to make sure neither side changes anyone on us while
40 // the assignment occurs
41 std::lock(GetMutex(), rhs
.GetMutex());
42 std::lock_guard
<std::recursive_mutex
> guard(GetMutex(), std::adopt_lock
);
43 std::lock_guard
<std::recursive_mutex
> rhs_guard(rhs
.GetMutex(),
46 m_process
= rhs
.m_process
;
47 m_stop_id
= rhs
.m_stop_id
;
48 m_threads
= rhs
.m_threads
;
49 m_selected_tid
= rhs
.m_selected_tid
;
54 ThreadList::~ThreadList() {
55 // Clear the thread list. Clear will take the mutex lock which will ensure
56 // that if anyone is using the list they won't get it removed while using it.
60 lldb::ThreadSP
ThreadList::GetExpressionExecutionThread() {
61 if (m_expression_tid_stack
.empty())
62 return GetSelectedThread();
63 ThreadSP expr_thread_sp
= FindThreadByID(m_expression_tid_stack
.back());
65 return expr_thread_sp
;
67 return GetSelectedThread();
70 void ThreadList::PushExpressionExecutionThread(lldb::tid_t tid
) {
71 m_expression_tid_stack
.push_back(tid
);
74 void ThreadList::PopExpressionExecutionThread(lldb::tid_t tid
) {
75 assert(m_expression_tid_stack
.back() == tid
);
76 m_expression_tid_stack
.pop_back();
79 uint32_t ThreadList::GetStopID() const { return m_stop_id
; }
81 void ThreadList::SetStopID(uint32_t stop_id
) { m_stop_id
= stop_id
; }
83 uint32_t ThreadList::GetSize(bool can_update
) {
84 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
87 m_process
->UpdateThreadListIfNeeded();
88 return m_threads
.size();
91 ThreadSP
ThreadList::GetThreadAtIndex(uint32_t idx
, bool can_update
) {
92 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
95 m_process
->UpdateThreadListIfNeeded();
98 if (idx
< m_threads
.size())
99 thread_sp
= m_threads
[idx
];
103 ThreadSP
ThreadList::FindThreadByID(lldb::tid_t tid
, bool can_update
) {
104 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
107 m_process
->UpdateThreadListIfNeeded();
111 const uint32_t num_threads
= m_threads
.size();
112 for (idx
= 0; idx
< num_threads
; ++idx
) {
113 if (m_threads
[idx
]->GetID() == tid
) {
114 thread_sp
= m_threads
[idx
];
121 ThreadSP
ThreadList::FindThreadByProtocolID(lldb::tid_t tid
, bool can_update
) {
122 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
125 m_process
->UpdateThreadListIfNeeded();
129 const uint32_t num_threads
= m_threads
.size();
130 for (idx
= 0; idx
< num_threads
; ++idx
) {
131 if (m_threads
[idx
]->GetProtocolID() == tid
) {
132 thread_sp
= m_threads
[idx
];
139 ThreadSP
ThreadList::RemoveThreadByID(lldb::tid_t tid
, bool can_update
) {
140 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
143 m_process
->UpdateThreadListIfNeeded();
147 const uint32_t num_threads
= m_threads
.size();
148 for (idx
= 0; idx
< num_threads
; ++idx
) {
149 if (m_threads
[idx
]->GetID() == tid
) {
150 thread_sp
= m_threads
[idx
];
151 m_threads
.erase(m_threads
.begin() + idx
);
158 ThreadSP
ThreadList::RemoveThreadByProtocolID(lldb::tid_t tid
,
160 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
163 m_process
->UpdateThreadListIfNeeded();
167 const uint32_t num_threads
= m_threads
.size();
168 for (idx
= 0; idx
< num_threads
; ++idx
) {
169 if (m_threads
[idx
]->GetProtocolID() == tid
) {
170 thread_sp
= m_threads
[idx
];
171 m_threads
.erase(m_threads
.begin() + idx
);
178 ThreadSP
ThreadList::GetThreadSPForThreadPtr(Thread
*thread_ptr
) {
181 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
184 const uint32_t num_threads
= m_threads
.size();
185 for (idx
= 0; idx
< num_threads
; ++idx
) {
186 if (m_threads
[idx
].get() == thread_ptr
) {
187 thread_sp
= m_threads
[idx
];
195 ThreadSP
ThreadList::GetBackingThread(const ThreadSP
&real_thread
) {
196 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
199 const uint32_t num_threads
= m_threads
.size();
200 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
201 if (m_threads
[idx
]->GetBackingThread() == real_thread
) {
202 thread_sp
= m_threads
[idx
];
209 ThreadSP
ThreadList::FindThreadByIndexID(uint32_t index_id
, bool can_update
) {
210 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
213 m_process
->UpdateThreadListIfNeeded();
216 const uint32_t num_threads
= m_threads
.size();
217 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
218 if (m_threads
[idx
]->GetIndexID() == index_id
) {
219 thread_sp
= m_threads
[idx
];
226 bool ThreadList::ShouldStop(Event
*event_ptr
) {
227 // Running events should never stop, obviously...
229 Log
*log
= GetLog(LLDBLog::Step
);
231 // The ShouldStop method of the threads can do a whole lot of work, figuring
232 // out whether the thread plan conditions are met. So we don't want to keep
233 // the ThreadList locked the whole time we are doing this.
234 // FIXME: It is possible that running code could cause new threads
235 // to be created. If that happens, we will miss asking them whether they
236 // should stop. This is not a big deal since we haven't had a chance to hang
237 // any interesting operations on those threads yet.
239 collection threads_copy
;
242 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
244 m_process
->UpdateThreadListIfNeeded();
245 for (lldb::ThreadSP thread_sp
: m_threads
) {
246 // This is an optimization... If we didn't let a thread run in between
247 // the previous stop and this one, we shouldn't have to consult it for
248 // ShouldStop. So just leave it off the list we are going to inspect.
249 // If the thread didn't run but had work to do before declaring a public
250 // stop, then also include it.
251 // On Linux, if a thread-specific conditional breakpoint was hit, it won't
252 // necessarily be the thread that hit the breakpoint itself that
253 // evaluates the conditional expression, so the thread that hit the
254 // breakpoint could still be asked to stop, even though it hasn't been
255 // allowed to run since the previous stop.
256 if (thread_sp
->GetTemporaryResumeState() != eStateSuspended
||
257 thread_sp
->IsStillAtLastBreakpointHit()
258 || thread_sp
->ShouldRunBeforePublicStop())
259 threads_copy
.push_back(thread_sp
);
262 // It is possible the threads we were allowing to run all exited and then
263 // maybe the user interrupted or something, then fall back on looking at
266 if (threads_copy
.size() == 0)
267 threads_copy
= m_threads
;
270 collection::iterator pos
, end
= threads_copy
.end();
275 "ThreadList::%s: %" PRIu64
" threads, %" PRIu64
276 " unsuspended threads",
277 __FUNCTION__
, (uint64_t)m_threads
.size(),
278 (uint64_t)threads_copy
.size());
281 bool did_anybody_stop_for_a_reason
= false;
283 // If the event is an Interrupt event, then we're going to stop no matter
284 // what. Otherwise, presume we won't stop.
285 bool should_stop
= false;
286 if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr
)) {
288 log
, "ThreadList::%s handling interrupt event, should stop set to true",
294 // Now we run through all the threads and get their stop info's. We want to
295 // make sure to do this first before we start running the ShouldStop, because
296 // one thread's ShouldStop could destroy information (like deleting a thread
297 // specific breakpoint another thread had stopped at) which could lead us to
298 // compute the StopInfo incorrectly. We don't need to use it here, we just
299 // want to make sure it gets computed.
301 for (pos
= threads_copy
.begin(); pos
!= end
; ++pos
) {
302 ThreadSP
thread_sp(*pos
);
303 thread_sp
->GetStopInfo();
306 // If a thread needs to finish some job that can be done just on this thread
307 // before broadcastion the stop, it will signal that by returning true for
308 // ShouldRunBeforePublicStop. This variable gathers the results from that.
309 bool a_thread_needs_to_run
= false;
310 for (pos
= threads_copy
.begin(); pos
!= end
; ++pos
) {
311 ThreadSP
thread_sp(*pos
);
313 // We should never get a stop for which no thread had a stop reason, but
314 // sometimes we do see this - for instance when we first connect to a
315 // remote stub. In that case we should stop, since we can't figure out the
316 // right thing to do and stopping gives the user control over what to do in
319 // Note, this causes a problem when you have a thread specific breakpoint,
320 // and a bunch of threads hit the breakpoint, but not the thread which we
321 // are waiting for. All the threads that are not "supposed" to hit the
322 // breakpoint are marked as having no stop reason, which is right, they
323 // should not show a stop reason. But that triggers this code and causes
324 // us to stop seemingly for no reason.
326 // Since the only way we ever saw this error was on first attach, I'm only
327 // going to trigger set did_anybody_stop_for_a_reason to true unless this
328 // is the first stop.
330 // If this becomes a problem, we'll have to have another StopReason like
331 // "StopInfoHidden" which will look invalid everywhere but at this check.
333 if (thread_sp
->GetProcess()->GetStopID() > 1)
334 did_anybody_stop_for_a_reason
= true;
336 did_anybody_stop_for_a_reason
|= thread_sp
->ThreadStoppedForAReason();
338 const bool thread_should_stop
= thread_sp
->ShouldStop(event_ptr
);
340 if (thread_should_stop
)
343 bool this_thread_forces_run
= thread_sp
->ShouldRunBeforePublicStop();
344 a_thread_needs_to_run
|= this_thread_forces_run
;
345 if (this_thread_forces_run
)
347 "ThreadList::{0} thread: {1:x}, "
348 "says it needs to run before public stop.",
349 __FUNCTION__
, thread_sp
->GetID());
353 if (a_thread_needs_to_run
) {
355 } else if (!should_stop
&& !did_anybody_stop_for_a_reason
) {
358 "ThreadList::%s we stopped but no threads had a stop reason, "
359 "overriding should_stop and stopping.",
363 LLDB_LOGF(log
, "ThreadList::%s overall should_stop = %i", __FUNCTION__
,
367 for (pos
= threads_copy
.begin(); pos
!= end
; ++pos
) {
368 ThreadSP
thread_sp(*pos
);
369 thread_sp
->WillStop();
376 Vote
ThreadList::ShouldReportStop(Event
*event_ptr
) {
377 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
379 Vote result
= eVoteNoOpinion
;
380 m_process
->UpdateThreadListIfNeeded();
381 collection::iterator pos
, end
= m_threads
.end();
383 Log
*log
= GetLog(LLDBLog::Step
);
385 LLDB_LOGF(log
, "ThreadList::%s %" PRIu64
" threads", __FUNCTION__
,
386 (uint64_t)m_threads
.size());
388 // Run through the threads and ask whether we should report this event. For
389 // stopping, a YES vote wins over everything. A NO vote wins over NO
390 // opinion. The exception is if a thread has work it needs to force before
391 // a public stop, which overrides everyone else's opinion:
392 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
393 ThreadSP
thread_sp(*pos
);
394 if (thread_sp
->ShouldRunBeforePublicStop()) {
395 LLDB_LOG(log
, "Thread {0:x} has private business to complete, overrode "
396 "the should report stop.", thread_sp
->GetID());
401 const Vote vote
= thread_sp
->ShouldReportStop(event_ptr
);
411 if (result
== eVoteNoOpinion
) {
415 "Thread {0:x} voted {1}, but lost out because result was {2}",
416 thread_sp
->GetID(), vote
, result
);
421 LLDB_LOG(log
, "Returning {0}", result
);
425 void ThreadList::SetShouldReportStop(Vote vote
) {
426 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
428 m_process
->UpdateThreadListIfNeeded();
429 collection::iterator pos
, end
= m_threads
.end();
430 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
431 ThreadSP
thread_sp(*pos
);
432 thread_sp
->SetShouldReportStop(vote
);
436 Vote
ThreadList::ShouldReportRun(Event
*event_ptr
) {
438 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
440 Vote result
= eVoteNoOpinion
;
441 m_process
->UpdateThreadListIfNeeded();
442 collection::iterator pos
, end
= m_threads
.end();
444 // Run through the threads and ask whether we should report this event. The
445 // rule is NO vote wins over everything, a YES vote wins over no opinion.
447 Log
*log
= GetLog(LLDBLog::Step
);
449 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
450 if ((*pos
)->GetResumeState() != eStateSuspended
) {
451 switch ((*pos
)->ShouldReportRun(event_ptr
)) {
455 if (result
== eVoteNoOpinion
)
460 "ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
461 ") says don't report.",
462 (*pos
)->GetIndexID(), (*pos
)->GetID());
471 void ThreadList::Clear() {
472 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
475 m_selected_tid
= LLDB_INVALID_THREAD_ID
;
478 void ThreadList::Destroy() {
479 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
480 const uint32_t num_threads
= m_threads
.size();
481 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
482 m_threads
[idx
]->DestroyThread();
486 void ThreadList::RefreshStateAfterStop() {
487 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
489 m_process
->UpdateThreadListIfNeeded();
491 Log
*log
= GetLog(LLDBLog::Step
);
492 if (log
&& log
->GetVerbose())
494 "Turning off notification of new threads while single stepping "
497 collection::iterator pos
, end
= m_threads
.end();
498 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
)
499 (*pos
)->RefreshStateAfterStop();
502 void ThreadList::DiscardThreadPlans() {
503 // You don't need to update the thread list here, because only threads that
504 // you currently know about have any thread plans.
505 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
507 collection::iterator pos
, end
= m_threads
.end();
508 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
)
509 (*pos
)->DiscardThreadPlans(true);
512 bool ThreadList::WillResume() {
513 // Run through the threads and perform their momentary actions. But we only
514 // do this for threads that are running, user suspended threads stay where
517 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
518 m_process
->UpdateThreadListIfNeeded();
520 collection::iterator pos
, end
= m_threads
.end();
522 // See if any thread wants to run stopping others. If it does, then we won't
523 // setup the other threads for resume, since they aren't going to get a
524 // chance to run. This is necessary because the SetupForResume might add
525 // "StopOthers" plans which would then get to be part of the who-gets-to-run
526 // negotiation, but they're coming in after the fact, and the threads that
527 // are already set up should take priority.
529 bool wants_solo_run
= false;
531 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
532 lldbassert((*pos
)->GetCurrentPlan() &&
533 "thread should not have null thread plan");
534 if ((*pos
)->GetResumeState() != eStateSuspended
&&
535 (*pos
)->GetCurrentPlan()->StopOthers()) {
536 if ((*pos
)->IsOperatingSystemPluginThread() &&
537 !(*pos
)->GetBackingThread())
539 wants_solo_run
= true;
544 if (wants_solo_run
) {
545 Log
*log
= GetLog(LLDBLog::Step
);
546 if (log
&& log
->GetVerbose())
547 LLDB_LOGF(log
, "Turning on notification of new threads while single "
548 "stepping a thread.");
549 m_process
->StartNoticingNewThreads();
551 Log
*log
= GetLog(LLDBLog::Step
);
552 if (log
&& log
->GetVerbose())
553 LLDB_LOGF(log
, "Turning off notification of new threads while single "
554 "stepping a thread.");
555 m_process
->StopNoticingNewThreads();
558 // Give all the threads that are likely to run a last chance to set up their
559 // state before we negotiate who is actually going to get a chance to run...
560 // Don't set to resume suspended threads, and if any thread wanted to stop
561 // others, only call setup on the threads that request StopOthers...
563 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
564 if ((*pos
)->GetResumeState() != eStateSuspended
&&
565 (!wants_solo_run
|| (*pos
)->GetCurrentPlan()->StopOthers())) {
566 if ((*pos
)->IsOperatingSystemPluginThread() &&
567 !(*pos
)->GetBackingThread())
569 (*pos
)->SetupForResume();
573 // Now go through the threads and see if any thread wants to run just itself.
574 // if so then pick one and run it.
576 ThreadList
run_me_only_list(m_process
);
578 run_me_only_list
.SetStopID(m_process
->GetStopID());
580 // One or more threads might want to "Stop Others". We want to handle all
581 // those requests first. And if there is a thread that wanted to "resume
582 // before a public stop", let it get the first crack:
583 // There are two special kinds of thread that have priority for "StopOthers":
584 // a "ShouldRunBeforePublicStop thread, or the currently selected thread. If
585 // we find one satisfying that critereon, put it here.
586 ThreadSP stop_others_thread_sp
;
588 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
589 ThreadSP
thread_sp(*pos
);
590 if (thread_sp
->GetResumeState() != eStateSuspended
&&
591 thread_sp
->GetCurrentPlan()->StopOthers()) {
592 if ((*pos
)->IsOperatingSystemPluginThread() &&
593 !(*pos
)->GetBackingThread())
596 // You can't say "stop others" and also want yourself to be suspended.
597 assert(thread_sp
->GetCurrentPlan()->RunState() != eStateSuspended
);
598 run_me_only_list
.AddThread(thread_sp
);
600 if (thread_sp
== GetSelectedThread())
601 stop_others_thread_sp
= thread_sp
;
603 if (thread_sp
->ShouldRunBeforePublicStop()) {
604 // This takes precedence, so if we find one of these, service it:
605 stop_others_thread_sp
= thread_sp
;
611 bool need_to_resume
= true;
613 if (run_me_only_list
.GetSize(false) == 0) {
614 // Everybody runs as they wish:
615 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
616 ThreadSP
thread_sp(*pos
);
618 if (thread_sp
->GetResumeState() != eStateSuspended
)
619 run_state
= thread_sp
->GetCurrentPlan()->RunState();
621 run_state
= eStateSuspended
;
622 if (!thread_sp
->ShouldResume(run_state
))
623 need_to_resume
= false;
626 ThreadSP thread_to_run
;
628 if (stop_others_thread_sp
) {
629 thread_to_run
= stop_others_thread_sp
;
630 } else if (run_me_only_list
.GetSize(false) == 1) {
631 thread_to_run
= run_me_only_list
.GetThreadAtIndex(0);
634 (int)((run_me_only_list
.GetSize(false) * (double)rand()) /
636 thread_to_run
= run_me_only_list
.GetThreadAtIndex(random_thread
);
639 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
640 ThreadSP
thread_sp(*pos
);
641 if (thread_sp
== thread_to_run
) {
642 // Note, a thread might be able to fulfil it's plan w/o actually
643 // resuming. An example of this is a step that changes the current
644 // inlined function depth w/o moving the PC. Check that here:
645 if (!thread_sp
->ShouldResume(thread_sp
->GetCurrentPlan()->RunState()))
646 need_to_resume
= false;
648 thread_sp
->ShouldResume(eStateSuspended
);
652 return need_to_resume
;
655 void ThreadList::DidResume() {
656 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
657 collection::iterator pos
, end
= m_threads
.end();
658 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
659 // Don't clear out threads that aren't going to get a chance to run, rather
660 // leave their state for the next time around.
661 ThreadSP
thread_sp(*pos
);
662 if (thread_sp
->GetTemporaryResumeState() != eStateSuspended
)
663 thread_sp
->DidResume();
667 void ThreadList::DidStop() {
668 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
669 collection::iterator pos
, end
= m_threads
.end();
670 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
) {
671 // Notify threads that the process just stopped. Note, this currently
672 // assumes that all threads in the list stop when the process stops. In
673 // the future we will want to support a debugging model where some threads
674 // continue to run while others are stopped. We either need to handle that
675 // somehow here or create a special thread list containing only threads
676 // which will stop in the code that calls this method (currently
677 // Process::SetPrivateState).
678 ThreadSP
thread_sp(*pos
);
679 if (StateIsRunningState(thread_sp
->GetState()))
680 thread_sp
->DidStop();
684 ThreadSP
ThreadList::GetSelectedThread() {
685 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
686 ThreadSP thread_sp
= FindThreadByID(m_selected_tid
);
687 if (!thread_sp
.get()) {
688 if (m_threads
.size() == 0)
690 m_selected_tid
= m_threads
[0]->GetID();
691 thread_sp
= m_threads
[0];
696 bool ThreadList::SetSelectedThreadByID(lldb::tid_t tid
, bool notify
) {
697 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
698 ThreadSP
selected_thread_sp(FindThreadByID(tid
));
699 if (selected_thread_sp
) {
700 m_selected_tid
= tid
;
701 selected_thread_sp
->SetDefaultFileAndLineToSelectedFrame();
703 m_selected_tid
= LLDB_INVALID_THREAD_ID
;
706 NotifySelectedThreadChanged(m_selected_tid
);
708 return m_selected_tid
!= LLDB_INVALID_THREAD_ID
;
711 bool ThreadList::SetSelectedThreadByIndexID(uint32_t index_id
, bool notify
) {
712 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
713 ThreadSP
selected_thread_sp(FindThreadByIndexID(index_id
));
714 if (selected_thread_sp
.get()) {
715 m_selected_tid
= selected_thread_sp
->GetID();
716 selected_thread_sp
->SetDefaultFileAndLineToSelectedFrame();
718 m_selected_tid
= LLDB_INVALID_THREAD_ID
;
721 NotifySelectedThreadChanged(m_selected_tid
);
723 return m_selected_tid
!= LLDB_INVALID_THREAD_ID
;
726 void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid
) {
727 ThreadSP
selected_thread_sp(FindThreadByID(tid
));
728 if (selected_thread_sp
->EventTypeHasListeners(
729 Thread::eBroadcastBitThreadSelected
))
730 selected_thread_sp
->BroadcastEvent(
731 Thread::eBroadcastBitThreadSelected
,
732 new Thread::ThreadEventData(selected_thread_sp
));
735 void ThreadList::Update(ThreadList
&rhs
) {
737 // Lock both mutexes to make sure neither side changes anyone on us while
738 // the assignment occurs
739 std::scoped_lock
<std::recursive_mutex
, std::recursive_mutex
> guard(GetMutex(), rhs
.GetMutex());
741 m_process
= rhs
.m_process
;
742 m_stop_id
= rhs
.m_stop_id
;
743 m_threads
.swap(rhs
.m_threads
);
744 m_selected_tid
= rhs
.m_selected_tid
;
746 // Now we look for threads that we are done with and make sure to clear
747 // them up as much as possible so anyone with a shared pointer will still
748 // have a reference, but the thread won't be of much use. Using
749 // std::weak_ptr for all backward references (such as a thread to a
750 // process) will eventually solve this issue for us, but for now, we need
751 // to work around the issue
752 collection::iterator rhs_pos
, rhs_end
= rhs
.m_threads
.end();
753 for (rhs_pos
= rhs
.m_threads
.begin(); rhs_pos
!= rhs_end
; ++rhs_pos
) {
754 // If this thread has already been destroyed, we don't need to look for
755 // it to destroy it again.
756 if (!(*rhs_pos
)->IsValid())
759 const lldb::tid_t tid
= (*rhs_pos
)->GetID();
760 bool thread_is_alive
= false;
761 const uint32_t num_threads
= m_threads
.size();
762 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
763 ThreadSP backing_thread
= m_threads
[idx
]->GetBackingThread();
764 if (m_threads
[idx
]->GetID() == tid
||
765 (backing_thread
&& backing_thread
->GetID() == tid
)) {
766 thread_is_alive
= true;
770 if (!thread_is_alive
) {
771 (*rhs_pos
)->DestroyThread();
777 void ThreadList::Flush() {
778 std::lock_guard
<std::recursive_mutex
> guard(GetMutex());
779 collection::iterator pos
, end
= m_threads
.end();
780 for (pos
= m_threads
.begin(); pos
!= end
; ++pos
)
784 std::recursive_mutex
&ThreadList::GetMutex() const {
785 return m_process
->m_thread_mutex
;
788 ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
789 lldb::ThreadSP thread_sp
)
790 : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID
) {
792 m_tid
= thread_sp
->GetID();
793 m_thread_list
= &thread_sp
->GetProcess()->GetThreadList();
794 m_thread_list
->PushExpressionExecutionThread(m_tid
);