Path: blob/main/contrib/llvm-project/lldb/source/Target/ThreadList.cpp
39587 views
//===-- ThreadList.cpp ----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <cstdlib>910#include <algorithm>1112#include "lldb/Target/Process.h"13#include "lldb/Target/RegisterContext.h"14#include "lldb/Target/Thread.h"15#include "lldb/Target/ThreadList.h"16#include "lldb/Target/ThreadPlan.h"17#include "lldb/Utility/LLDBAssert.h"18#include "lldb/Utility/LLDBLog.h"19#include "lldb/Utility/Log.h"20#include "lldb/Utility/State.h"2122using namespace lldb;23using namespace lldb_private;2425ThreadList::ThreadList(Process &process)26: ThreadCollection(), m_process(process), m_stop_id(0),27m_selected_tid(LLDB_INVALID_THREAD_ID) {}2829ThreadList::ThreadList(const ThreadList &rhs)30: ThreadCollection(), m_process(rhs.m_process), m_stop_id(rhs.m_stop_id),31m_selected_tid() {32// Use the assignment operator since it uses the mutex33*this = rhs;34}3536const ThreadList &ThreadList::operator=(const ThreadList &rhs) {37if (this != &rhs) {38// We only allow assignments between thread lists describing the same39// process. Same process implies same mutex, which means it's enough to lock40// just the current object.41assert(&m_process == &rhs.m_process);42assert(&GetMutex() == &rhs.GetMutex());43std::lock_guard<std::recursive_mutex> guard(GetMutex());4445m_stop_id = rhs.m_stop_id;46m_threads = rhs.m_threads;47m_selected_tid = rhs.m_selected_tid;48}49return *this;50}5152ThreadList::~ThreadList() {53// Clear the thread list. Clear will take the mutex lock which will ensure54// that if anyone is using the list they won't get it removed while using it.55Clear();56}5758lldb::ThreadSP ThreadList::GetExpressionExecutionThread() {59if (m_expression_tid_stack.empty())60return GetSelectedThread();61ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back());62if (expr_thread_sp)63return expr_thread_sp;64else65return GetSelectedThread();66}6768void ThreadList::PushExpressionExecutionThread(lldb::tid_t tid) {69m_expression_tid_stack.push_back(tid);70}7172void ThreadList::PopExpressionExecutionThread(lldb::tid_t tid) {73assert(m_expression_tid_stack.back() == tid);74m_expression_tid_stack.pop_back();75}7677uint32_t ThreadList::GetStopID() const { return m_stop_id; }7879void ThreadList::SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }8081uint32_t ThreadList::GetSize(bool can_update) {82std::lock_guard<std::recursive_mutex> guard(GetMutex());8384if (can_update)85m_process.UpdateThreadListIfNeeded();86return m_threads.size();87}8889ThreadSP ThreadList::GetThreadAtIndex(uint32_t idx, bool can_update) {90std::lock_guard<std::recursive_mutex> guard(GetMutex());9192if (can_update)93m_process.UpdateThreadListIfNeeded();9495ThreadSP thread_sp;96if (idx < m_threads.size())97thread_sp = m_threads[idx];98return thread_sp;99}100101ThreadSP ThreadList::FindThreadByID(lldb::tid_t tid, bool can_update) {102std::lock_guard<std::recursive_mutex> guard(GetMutex());103104if (can_update)105m_process.UpdateThreadListIfNeeded();106107ThreadSP thread_sp;108uint32_t idx = 0;109const uint32_t num_threads = m_threads.size();110for (idx = 0; idx < num_threads; ++idx) {111if (m_threads[idx]->GetID() == tid) {112thread_sp = m_threads[idx];113break;114}115}116return thread_sp;117}118119ThreadSP ThreadList::FindThreadByProtocolID(lldb::tid_t tid, bool can_update) {120std::lock_guard<std::recursive_mutex> guard(GetMutex());121122if (can_update)123m_process.UpdateThreadListIfNeeded();124125ThreadSP thread_sp;126uint32_t idx = 0;127const uint32_t num_threads = m_threads.size();128for (idx = 0; idx < num_threads; ++idx) {129if (m_threads[idx]->GetProtocolID() == tid) {130thread_sp = m_threads[idx];131break;132}133}134return thread_sp;135}136137ThreadSP ThreadList::RemoveThreadByID(lldb::tid_t tid, bool can_update) {138std::lock_guard<std::recursive_mutex> guard(GetMutex());139140if (can_update)141m_process.UpdateThreadListIfNeeded();142143ThreadSP thread_sp;144uint32_t idx = 0;145const uint32_t num_threads = m_threads.size();146for (idx = 0; idx < num_threads; ++idx) {147if (m_threads[idx]->GetID() == tid) {148thread_sp = m_threads[idx];149m_threads.erase(m_threads.begin() + idx);150break;151}152}153return thread_sp;154}155156ThreadSP ThreadList::RemoveThreadByProtocolID(lldb::tid_t tid,157bool can_update) {158std::lock_guard<std::recursive_mutex> guard(GetMutex());159160if (can_update)161m_process.UpdateThreadListIfNeeded();162163ThreadSP thread_sp;164uint32_t idx = 0;165const uint32_t num_threads = m_threads.size();166for (idx = 0; idx < num_threads; ++idx) {167if (m_threads[idx]->GetProtocolID() == tid) {168thread_sp = m_threads[idx];169m_threads.erase(m_threads.begin() + idx);170break;171}172}173return thread_sp;174}175176ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {177ThreadSP thread_sp;178if (thread_ptr) {179std::lock_guard<std::recursive_mutex> guard(GetMutex());180181uint32_t idx = 0;182const uint32_t num_threads = m_threads.size();183for (idx = 0; idx < num_threads; ++idx) {184if (m_threads[idx].get() == thread_ptr) {185thread_sp = m_threads[idx];186break;187}188}189}190return thread_sp;191}192193ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) {194std::lock_guard<std::recursive_mutex> guard(GetMutex());195196ThreadSP thread_sp;197const uint32_t num_threads = m_threads.size();198for (uint32_t idx = 0; idx < num_threads; ++idx) {199if (m_threads[idx]->GetBackingThread() == real_thread) {200thread_sp = m_threads[idx];201break;202}203}204return thread_sp;205}206207ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) {208std::lock_guard<std::recursive_mutex> guard(GetMutex());209210if (can_update)211m_process.UpdateThreadListIfNeeded();212213ThreadSP thread_sp;214const uint32_t num_threads = m_threads.size();215for (uint32_t idx = 0; idx < num_threads; ++idx) {216if (m_threads[idx]->GetIndexID() == index_id) {217thread_sp = m_threads[idx];218break;219}220}221return thread_sp;222}223224bool ThreadList::ShouldStop(Event *event_ptr) {225// Running events should never stop, obviously...226227Log *log = GetLog(LLDBLog::Step);228229// The ShouldStop method of the threads can do a whole lot of work, figuring230// out whether the thread plan conditions are met. So we don't want to keep231// the ThreadList locked the whole time we are doing this.232// FIXME: It is possible that running code could cause new threads233// to be created. If that happens, we will miss asking them whether they234// should stop. This is not a big deal since we haven't had a chance to hang235// any interesting operations on those threads yet.236237collection threads_copy;238{239// Scope for locker240std::lock_guard<std::recursive_mutex> guard(GetMutex());241242m_process.UpdateThreadListIfNeeded();243for (lldb::ThreadSP thread_sp : m_threads) {244// This is an optimization... If we didn't let a thread run in between245// the previous stop and this one, we shouldn't have to consult it for246// ShouldStop. So just leave it off the list we are going to inspect.247// If the thread didn't run but had work to do before declaring a public248// stop, then also include it.249// On Linux, if a thread-specific conditional breakpoint was hit, it won't250// necessarily be the thread that hit the breakpoint itself that251// evaluates the conditional expression, so the thread that hit the252// breakpoint could still be asked to stop, even though it hasn't been253// allowed to run since the previous stop.254if (thread_sp->GetTemporaryResumeState() != eStateSuspended ||255thread_sp->IsStillAtLastBreakpointHit()256|| thread_sp->ShouldRunBeforePublicStop())257threads_copy.push_back(thread_sp);258}259260// It is possible the threads we were allowing to run all exited and then261// maybe the user interrupted or something, then fall back on looking at262// all threads:263264if (threads_copy.size() == 0)265threads_copy = m_threads;266}267268collection::iterator pos, end = threads_copy.end();269270if (log) {271log->PutCString("");272LLDB_LOGF(log,273"ThreadList::%s: %" PRIu64 " threads, %" PRIu64274" unsuspended threads",275__FUNCTION__, (uint64_t)m_threads.size(),276(uint64_t)threads_copy.size());277}278279bool did_anybody_stop_for_a_reason = false;280281// If the event is an Interrupt event, then we're going to stop no matter282// what. Otherwise, presume we won't stop.283bool should_stop = false;284if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {285LLDB_LOGF(286log, "ThreadList::%s handling interrupt event, should stop set to true",287__FUNCTION__);288289should_stop = true;290}291292// Now we run through all the threads and get their stop info's. We want to293// make sure to do this first before we start running the ShouldStop, because294// one thread's ShouldStop could destroy information (like deleting a thread295// specific breakpoint another thread had stopped at) which could lead us to296// compute the StopInfo incorrectly. We don't need to use it here, we just297// want to make sure it gets computed.298299for (pos = threads_copy.begin(); pos != end; ++pos) {300ThreadSP thread_sp(*pos);301thread_sp->GetStopInfo();302}303304// If a thread needs to finish some job that can be done just on this thread305// before broadcastion the stop, it will signal that by returning true for306// ShouldRunBeforePublicStop. This variable gathers the results from that.307bool a_thread_needs_to_run = false;308for (pos = threads_copy.begin(); pos != end; ++pos) {309ThreadSP thread_sp(*pos);310311// We should never get a stop for which no thread had a stop reason, but312// sometimes we do see this - for instance when we first connect to a313// remote stub. In that case we should stop, since we can't figure out the314// right thing to do and stopping gives the user control over what to do in315// this instance.316//317// Note, this causes a problem when you have a thread specific breakpoint,318// and a bunch of threads hit the breakpoint, but not the thread which we319// are waiting for. All the threads that are not "supposed" to hit the320// breakpoint are marked as having no stop reason, which is right, they321// should not show a stop reason. But that triggers this code and causes322// us to stop seemingly for no reason.323//324// Since the only way we ever saw this error was on first attach, I'm only325// going to trigger set did_anybody_stop_for_a_reason to true unless this326// is the first stop.327//328// If this becomes a problem, we'll have to have another StopReason like329// "StopInfoHidden" which will look invalid everywhere but at this check.330331if (thread_sp->GetProcess()->GetStopID() > 1)332did_anybody_stop_for_a_reason = true;333else334did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();335336const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);337338if (thread_should_stop)339should_stop |= true;340else {341bool this_thread_forces_run = thread_sp->ShouldRunBeforePublicStop();342a_thread_needs_to_run |= this_thread_forces_run;343if (this_thread_forces_run)344LLDB_LOG(log,345"ThreadList::{0} thread: {1:x}, "346"says it needs to run before public stop.",347__FUNCTION__, thread_sp->GetID());348}349}350351if (a_thread_needs_to_run) {352should_stop = false;353} else if (!should_stop && !did_anybody_stop_for_a_reason) {354should_stop = true;355LLDB_LOGF(log,356"ThreadList::%s we stopped but no threads had a stop reason, "357"overriding should_stop and stopping.",358__FUNCTION__);359}360361LLDB_LOGF(log, "ThreadList::%s overall should_stop = %i", __FUNCTION__,362should_stop);363364if (should_stop) {365for (pos = threads_copy.begin(); pos != end; ++pos) {366ThreadSP thread_sp(*pos);367thread_sp->WillStop();368}369}370371return should_stop;372}373374Vote ThreadList::ShouldReportStop(Event *event_ptr) {375std::lock_guard<std::recursive_mutex> guard(GetMutex());376377Vote result = eVoteNoOpinion;378m_process.UpdateThreadListIfNeeded();379collection::iterator pos, end = m_threads.end();380381Log *log = GetLog(LLDBLog::Step);382383LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__,384(uint64_t)m_threads.size());385386// Run through the threads and ask whether we should report this event. For387// stopping, a YES vote wins over everything. A NO vote wins over NO388// opinion. The exception is if a thread has work it needs to force before389// a public stop, which overrides everyone else's opinion:390for (pos = m_threads.begin(); pos != end; ++pos) {391ThreadSP thread_sp(*pos);392if (thread_sp->ShouldRunBeforePublicStop()) {393LLDB_LOG(log, "Thread {0:x} has private business to complete, overrode "394"the should report stop.", thread_sp->GetID());395result = eVoteNo;396break;397}398399const Vote vote = thread_sp->ShouldReportStop(event_ptr);400switch (vote) {401case eVoteNoOpinion:402continue;403404case eVoteYes:405result = eVoteYes;406break;407408case eVoteNo:409if (result == eVoteNoOpinion) {410result = eVoteNo;411} else {412LLDB_LOG(log,413"Thread {0:x} voted {1}, but lost out because result was {2}",414thread_sp->GetID(), vote, result);415}416break;417}418}419LLDB_LOG(log, "Returning {0}", result);420return result;421}422423void ThreadList::SetShouldReportStop(Vote vote) {424std::lock_guard<std::recursive_mutex> guard(GetMutex());425426m_process.UpdateThreadListIfNeeded();427collection::iterator pos, end = m_threads.end();428for (pos = m_threads.begin(); pos != end; ++pos) {429ThreadSP thread_sp(*pos);430thread_sp->SetShouldReportStop(vote);431}432}433434Vote ThreadList::ShouldReportRun(Event *event_ptr) {435436std::lock_guard<std::recursive_mutex> guard(GetMutex());437438Vote result = eVoteNoOpinion;439m_process.UpdateThreadListIfNeeded();440collection::iterator pos, end = m_threads.end();441442// Run through the threads and ask whether we should report this event. The443// rule is NO vote wins over everything, a YES vote wins over no opinion.444445Log *log = GetLog(LLDBLog::Step);446447for (pos = m_threads.begin(); pos != end; ++pos) {448if ((*pos)->GetResumeState() != eStateSuspended) {449switch ((*pos)->ShouldReportRun(event_ptr)) {450case eVoteNoOpinion:451continue;452case eVoteYes:453if (result == eVoteNoOpinion)454result = eVoteYes;455break;456case eVoteNo:457LLDB_LOGF(log,458"ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64459") says don't report.",460(*pos)->GetIndexID(), (*pos)->GetID());461result = eVoteNo;462break;463}464}465}466return result;467}468469void ThreadList::Clear() {470std::lock_guard<std::recursive_mutex> guard(GetMutex());471m_stop_id = 0;472m_threads.clear();473m_selected_tid = LLDB_INVALID_THREAD_ID;474}475476void ThreadList::Destroy() {477std::lock_guard<std::recursive_mutex> guard(GetMutex());478const uint32_t num_threads = m_threads.size();479for (uint32_t idx = 0; idx < num_threads; ++idx) {480m_threads[idx]->DestroyThread();481}482}483484void ThreadList::RefreshStateAfterStop() {485std::lock_guard<std::recursive_mutex> guard(GetMutex());486487m_process.UpdateThreadListIfNeeded();488489Log *log = GetLog(LLDBLog::Step);490if (log && log->GetVerbose())491LLDB_LOGF(log,492"Turning off notification of new threads while single stepping "493"a thread.");494495collection::iterator pos, end = m_threads.end();496for (pos = m_threads.begin(); pos != end; ++pos)497(*pos)->RefreshStateAfterStop();498}499500void ThreadList::DiscardThreadPlans() {501// You don't need to update the thread list here, because only threads that502// you currently know about have any thread plans.503std::lock_guard<std::recursive_mutex> guard(GetMutex());504505collection::iterator pos, end = m_threads.end();506for (pos = m_threads.begin(); pos != end; ++pos)507(*pos)->DiscardThreadPlans(true);508}509510bool ThreadList::WillResume() {511// Run through the threads and perform their momentary actions. But we only512// do this for threads that are running, user suspended threads stay where513// they are.514515std::lock_guard<std::recursive_mutex> guard(GetMutex());516m_process.UpdateThreadListIfNeeded();517518collection::iterator pos, end = m_threads.end();519520// See if any thread wants to run stopping others. If it does, then we won't521// setup the other threads for resume, since they aren't going to get a522// chance to run. This is necessary because the SetupForResume might add523// "StopOthers" plans which would then get to be part of the who-gets-to-run524// negotiation, but they're coming in after the fact, and the threads that525// are already set up should take priority.526527bool wants_solo_run = false;528529for (pos = m_threads.begin(); pos != end; ++pos) {530lldbassert((*pos)->GetCurrentPlan() &&531"thread should not have null thread plan");532if ((*pos)->GetResumeState() != eStateSuspended &&533(*pos)->GetCurrentPlan()->StopOthers()) {534if ((*pos)->IsOperatingSystemPluginThread() &&535!(*pos)->GetBackingThread())536continue;537wants_solo_run = true;538break;539}540}541542if (wants_solo_run) {543Log *log = GetLog(LLDBLog::Step);544if (log && log->GetVerbose())545LLDB_LOGF(log, "Turning on notification of new threads while single "546"stepping a thread.");547m_process.StartNoticingNewThreads();548} else {549Log *log = GetLog(LLDBLog::Step);550if (log && log->GetVerbose())551LLDB_LOGF(log, "Turning off notification of new threads while single "552"stepping a thread.");553m_process.StopNoticingNewThreads();554}555556// Give all the threads that are likely to run a last chance to set up their557// state before we negotiate who is actually going to get a chance to run...558// Don't set to resume suspended threads, and if any thread wanted to stop559// others, only call setup on the threads that request StopOthers...560561for (pos = m_threads.begin(); pos != end; ++pos) {562if ((*pos)->GetResumeState() != eStateSuspended &&563(!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) {564if ((*pos)->IsOperatingSystemPluginThread() &&565!(*pos)->GetBackingThread())566continue;567(*pos)->SetupForResume();568}569}570571// Now go through the threads and see if any thread wants to run just itself.572// if so then pick one and run it.573574ThreadList run_me_only_list(m_process);575576run_me_only_list.SetStopID(m_process.GetStopID());577578// One or more threads might want to "Stop Others". We want to handle all579// those requests first. And if there is a thread that wanted to "resume580// before a public stop", let it get the first crack:581// There are two special kinds of thread that have priority for "StopOthers":582// a "ShouldRunBeforePublicStop thread, or the currently selected thread. If583// we find one satisfying that critereon, put it here.584ThreadSP stop_others_thread_sp;585586for (pos = m_threads.begin(); pos != end; ++pos) {587ThreadSP thread_sp(*pos);588if (thread_sp->GetResumeState() != eStateSuspended &&589thread_sp->GetCurrentPlan()->StopOthers()) {590if ((*pos)->IsOperatingSystemPluginThread() &&591!(*pos)->GetBackingThread())592continue;593594// You can't say "stop others" and also want yourself to be suspended.595assert(thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);596run_me_only_list.AddThread(thread_sp);597598if (thread_sp == GetSelectedThread())599stop_others_thread_sp = thread_sp;600601if (thread_sp->ShouldRunBeforePublicStop()) {602// This takes precedence, so if we find one of these, service it:603stop_others_thread_sp = thread_sp;604break;605}606}607}608609bool need_to_resume = true;610611if (run_me_only_list.GetSize(false) == 0) {612// Everybody runs as they wish:613for (pos = m_threads.begin(); pos != end; ++pos) {614ThreadSP thread_sp(*pos);615StateType run_state;616if (thread_sp->GetResumeState() != eStateSuspended)617run_state = thread_sp->GetCurrentPlan()->RunState();618else619run_state = eStateSuspended;620if (!thread_sp->ShouldResume(run_state))621need_to_resume = false;622}623} else {624ThreadSP thread_to_run;625626if (stop_others_thread_sp) {627thread_to_run = stop_others_thread_sp;628} else if (run_me_only_list.GetSize(false) == 1) {629thread_to_run = run_me_only_list.GetThreadAtIndex(0);630} else {631int random_thread =632(int)((run_me_only_list.GetSize(false) * (double)rand()) /633(RAND_MAX + 1.0));634thread_to_run = run_me_only_list.GetThreadAtIndex(random_thread);635}636637for (pos = m_threads.begin(); pos != end; ++pos) {638ThreadSP thread_sp(*pos);639if (thread_sp == thread_to_run) {640// Note, a thread might be able to fulfil it's plan w/o actually641// resuming. An example of this is a step that changes the current642// inlined function depth w/o moving the PC. Check that here:643if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))644need_to_resume = false;645} else646thread_sp->ShouldResume(eStateSuspended);647}648}649650return need_to_resume;651}652653void ThreadList::DidResume() {654std::lock_guard<std::recursive_mutex> guard(GetMutex());655collection::iterator pos, end = m_threads.end();656for (pos = m_threads.begin(); pos != end; ++pos) {657// Don't clear out threads that aren't going to get a chance to run, rather658// leave their state for the next time around.659ThreadSP thread_sp(*pos);660if (thread_sp->GetTemporaryResumeState() != eStateSuspended)661thread_sp->DidResume();662}663}664665void ThreadList::DidStop() {666std::lock_guard<std::recursive_mutex> guard(GetMutex());667collection::iterator pos, end = m_threads.end();668for (pos = m_threads.begin(); pos != end; ++pos) {669// Notify threads that the process just stopped. Note, this currently670// assumes that all threads in the list stop when the process stops. In671// the future we will want to support a debugging model where some threads672// continue to run while others are stopped. We either need to handle that673// somehow here or create a special thread list containing only threads674// which will stop in the code that calls this method (currently675// Process::SetPrivateState).676ThreadSP thread_sp(*pos);677if (StateIsRunningState(thread_sp->GetState()))678thread_sp->DidStop();679}680}681682ThreadSP ThreadList::GetSelectedThread() {683std::lock_guard<std::recursive_mutex> guard(GetMutex());684ThreadSP thread_sp = FindThreadByID(m_selected_tid);685if (!thread_sp.get()) {686if (m_threads.size() == 0)687return thread_sp;688m_selected_tid = m_threads[0]->GetID();689thread_sp = m_threads[0];690}691return thread_sp;692}693694bool ThreadList::SetSelectedThreadByID(lldb::tid_t tid, bool notify) {695std::lock_guard<std::recursive_mutex> guard(GetMutex());696ThreadSP selected_thread_sp(FindThreadByID(tid));697if (selected_thread_sp) {698m_selected_tid = tid;699selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();700} else701m_selected_tid = LLDB_INVALID_THREAD_ID;702703if (notify)704NotifySelectedThreadChanged(m_selected_tid);705706return m_selected_tid != LLDB_INVALID_THREAD_ID;707}708709bool ThreadList::SetSelectedThreadByIndexID(uint32_t index_id, bool notify) {710std::lock_guard<std::recursive_mutex> guard(GetMutex());711ThreadSP selected_thread_sp(FindThreadByIndexID(index_id));712if (selected_thread_sp.get()) {713m_selected_tid = selected_thread_sp->GetID();714selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();715} else716m_selected_tid = LLDB_INVALID_THREAD_ID;717718if (notify)719NotifySelectedThreadChanged(m_selected_tid);720721return m_selected_tid != LLDB_INVALID_THREAD_ID;722}723724void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid) {725ThreadSP selected_thread_sp(FindThreadByID(tid));726if (selected_thread_sp->EventTypeHasListeners(727Thread::eBroadcastBitThreadSelected)) {728auto data_sp =729std::make_shared<Thread::ThreadEventData>(selected_thread_sp);730selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,731data_sp);732}733}734735void ThreadList::Update(ThreadList &rhs) {736if (this != &rhs) {737// We only allow assignments between thread lists describing the same738// process. Same process implies same mutex, which means it's enough to lock739// just the current object.740assert(&m_process == &rhs.m_process);741assert(&GetMutex() == &rhs.GetMutex());742std::lock_guard<std::recursive_mutex> guard(GetMutex());743744m_stop_id = rhs.m_stop_id;745m_threads.swap(rhs.m_threads);746m_selected_tid = rhs.m_selected_tid;747748// Now we look for threads that we are done with and make sure to clear749// them up as much as possible so anyone with a shared pointer will still750// have a reference, but the thread won't be of much use. Using751// std::weak_ptr for all backward references (such as a thread to a752// process) will eventually solve this issue for us, but for now, we need753// to work around the issue754collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();755for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) {756// If this thread has already been destroyed, we don't need to look for757// it to destroy it again.758if (!(*rhs_pos)->IsValid())759continue;760761const lldb::tid_t tid = (*rhs_pos)->GetID();762bool thread_is_alive = false;763const uint32_t num_threads = m_threads.size();764for (uint32_t idx = 0; idx < num_threads; ++idx) {765ThreadSP backing_thread = m_threads[idx]->GetBackingThread();766if (m_threads[idx]->GetID() == tid ||767(backing_thread && backing_thread->GetID() == tid)) {768thread_is_alive = true;769break;770}771}772if (!thread_is_alive) {773(*rhs_pos)->DestroyThread();774}775}776}777}778779void ThreadList::Flush() {780std::lock_guard<std::recursive_mutex> guard(GetMutex());781collection::iterator pos, end = m_threads.end();782for (pos = m_threads.begin(); pos != end; ++pos)783(*pos)->Flush();784}785786std::recursive_mutex &ThreadList::GetMutex() const {787return m_process.m_thread_mutex;788}789790ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(791lldb::ThreadSP thread_sp)792: m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {793if (thread_sp) {794m_tid = thread_sp->GetID();795m_thread_list = &thread_sp->GetProcess()->GetThreadList();796m_thread_list->PushExpressionExecutionThread(m_tid);797}798}799800801