Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Target/ThreadList.cpp
39587 views
1
//===-- ThreadList.cpp ----------------------------------------------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include <cstdlib>
10
11
#include <algorithm>
12
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"
22
23
using namespace lldb;
24
using namespace lldb_private;
25
26
ThreadList::ThreadList(Process &process)
27
: ThreadCollection(), m_process(process), m_stop_id(0),
28
m_selected_tid(LLDB_INVALID_THREAD_ID) {}
29
30
ThreadList::ThreadList(const ThreadList &rhs)
31
: ThreadCollection(), m_process(rhs.m_process), m_stop_id(rhs.m_stop_id),
32
m_selected_tid() {
33
// Use the assignment operator since it uses the mutex
34
*this = rhs;
35
}
36
37
const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
38
if (this != &rhs) {
39
// We only allow assignments between thread lists describing the same
40
// process. Same process implies same mutex, which means it's enough to lock
41
// just the current object.
42
assert(&m_process == &rhs.m_process);
43
assert(&GetMutex() == &rhs.GetMutex());
44
std::lock_guard<std::recursive_mutex> guard(GetMutex());
45
46
m_stop_id = rhs.m_stop_id;
47
m_threads = rhs.m_threads;
48
m_selected_tid = rhs.m_selected_tid;
49
}
50
return *this;
51
}
52
53
ThreadList::~ThreadList() {
54
// Clear the thread list. Clear will take the mutex lock which will ensure
55
// that if anyone is using the list they won't get it removed while using it.
56
Clear();
57
}
58
59
lldb::ThreadSP ThreadList::GetExpressionExecutionThread() {
60
if (m_expression_tid_stack.empty())
61
return GetSelectedThread();
62
ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back());
63
if (expr_thread_sp)
64
return expr_thread_sp;
65
else
66
return GetSelectedThread();
67
}
68
69
void ThreadList::PushExpressionExecutionThread(lldb::tid_t tid) {
70
m_expression_tid_stack.push_back(tid);
71
}
72
73
void ThreadList::PopExpressionExecutionThread(lldb::tid_t tid) {
74
assert(m_expression_tid_stack.back() == tid);
75
m_expression_tid_stack.pop_back();
76
}
77
78
uint32_t ThreadList::GetStopID() const { return m_stop_id; }
79
80
void ThreadList::SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
81
82
uint32_t ThreadList::GetSize(bool can_update) {
83
std::lock_guard<std::recursive_mutex> guard(GetMutex());
84
85
if (can_update)
86
m_process.UpdateThreadListIfNeeded();
87
return m_threads.size();
88
}
89
90
ThreadSP ThreadList::GetThreadAtIndex(uint32_t idx, bool can_update) {
91
std::lock_guard<std::recursive_mutex> guard(GetMutex());
92
93
if (can_update)
94
m_process.UpdateThreadListIfNeeded();
95
96
ThreadSP thread_sp;
97
if (idx < m_threads.size())
98
thread_sp = m_threads[idx];
99
return thread_sp;
100
}
101
102
ThreadSP ThreadList::FindThreadByID(lldb::tid_t tid, bool can_update) {
103
std::lock_guard<std::recursive_mutex> guard(GetMutex());
104
105
if (can_update)
106
m_process.UpdateThreadListIfNeeded();
107
108
ThreadSP thread_sp;
109
uint32_t idx = 0;
110
const uint32_t num_threads = m_threads.size();
111
for (idx = 0; idx < num_threads; ++idx) {
112
if (m_threads[idx]->GetID() == tid) {
113
thread_sp = m_threads[idx];
114
break;
115
}
116
}
117
return thread_sp;
118
}
119
120
ThreadSP ThreadList::FindThreadByProtocolID(lldb::tid_t tid, bool can_update) {
121
std::lock_guard<std::recursive_mutex> guard(GetMutex());
122
123
if (can_update)
124
m_process.UpdateThreadListIfNeeded();
125
126
ThreadSP thread_sp;
127
uint32_t idx = 0;
128
const uint32_t num_threads = m_threads.size();
129
for (idx = 0; idx < num_threads; ++idx) {
130
if (m_threads[idx]->GetProtocolID() == tid) {
131
thread_sp = m_threads[idx];
132
break;
133
}
134
}
135
return thread_sp;
136
}
137
138
ThreadSP ThreadList::RemoveThreadByID(lldb::tid_t tid, bool can_update) {
139
std::lock_guard<std::recursive_mutex> guard(GetMutex());
140
141
if (can_update)
142
m_process.UpdateThreadListIfNeeded();
143
144
ThreadSP thread_sp;
145
uint32_t idx = 0;
146
const uint32_t num_threads = m_threads.size();
147
for (idx = 0; idx < num_threads; ++idx) {
148
if (m_threads[idx]->GetID() == tid) {
149
thread_sp = m_threads[idx];
150
m_threads.erase(m_threads.begin() + idx);
151
break;
152
}
153
}
154
return thread_sp;
155
}
156
157
ThreadSP ThreadList::RemoveThreadByProtocolID(lldb::tid_t tid,
158
bool can_update) {
159
std::lock_guard<std::recursive_mutex> guard(GetMutex());
160
161
if (can_update)
162
m_process.UpdateThreadListIfNeeded();
163
164
ThreadSP thread_sp;
165
uint32_t idx = 0;
166
const uint32_t num_threads = m_threads.size();
167
for (idx = 0; idx < num_threads; ++idx) {
168
if (m_threads[idx]->GetProtocolID() == tid) {
169
thread_sp = m_threads[idx];
170
m_threads.erase(m_threads.begin() + idx);
171
break;
172
}
173
}
174
return thread_sp;
175
}
176
177
ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {
178
ThreadSP thread_sp;
179
if (thread_ptr) {
180
std::lock_guard<std::recursive_mutex> guard(GetMutex());
181
182
uint32_t idx = 0;
183
const uint32_t num_threads = m_threads.size();
184
for (idx = 0; idx < num_threads; ++idx) {
185
if (m_threads[idx].get() == thread_ptr) {
186
thread_sp = m_threads[idx];
187
break;
188
}
189
}
190
}
191
return thread_sp;
192
}
193
194
ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) {
195
std::lock_guard<std::recursive_mutex> guard(GetMutex());
196
197
ThreadSP thread_sp;
198
const uint32_t num_threads = m_threads.size();
199
for (uint32_t idx = 0; idx < num_threads; ++idx) {
200
if (m_threads[idx]->GetBackingThread() == real_thread) {
201
thread_sp = m_threads[idx];
202
break;
203
}
204
}
205
return thread_sp;
206
}
207
208
ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) {
209
std::lock_guard<std::recursive_mutex> guard(GetMutex());
210
211
if (can_update)
212
m_process.UpdateThreadListIfNeeded();
213
214
ThreadSP thread_sp;
215
const uint32_t num_threads = m_threads.size();
216
for (uint32_t idx = 0; idx < num_threads; ++idx) {
217
if (m_threads[idx]->GetIndexID() == index_id) {
218
thread_sp = m_threads[idx];
219
break;
220
}
221
}
222
return thread_sp;
223
}
224
225
bool ThreadList::ShouldStop(Event *event_ptr) {
226
// Running events should never stop, obviously...
227
228
Log *log = GetLog(LLDBLog::Step);
229
230
// The ShouldStop method of the threads can do a whole lot of work, figuring
231
// out whether the thread plan conditions are met. So we don't want to keep
232
// the ThreadList locked the whole time we are doing this.
233
// FIXME: It is possible that running code could cause new threads
234
// to be created. If that happens, we will miss asking them whether they
235
// should stop. This is not a big deal since we haven't had a chance to hang
236
// any interesting operations on those threads yet.
237
238
collection threads_copy;
239
{
240
// Scope for locker
241
std::lock_guard<std::recursive_mutex> guard(GetMutex());
242
243
m_process.UpdateThreadListIfNeeded();
244
for (lldb::ThreadSP thread_sp : m_threads) {
245
// This is an optimization... If we didn't let a thread run in between
246
// the previous stop and this one, we shouldn't have to consult it for
247
// ShouldStop. So just leave it off the list we are going to inspect.
248
// If the thread didn't run but had work to do before declaring a public
249
// stop, then also include it.
250
// On Linux, if a thread-specific conditional breakpoint was hit, it won't
251
// necessarily be the thread that hit the breakpoint itself that
252
// evaluates the conditional expression, so the thread that hit the
253
// breakpoint could still be asked to stop, even though it hasn't been
254
// allowed to run since the previous stop.
255
if (thread_sp->GetTemporaryResumeState() != eStateSuspended ||
256
thread_sp->IsStillAtLastBreakpointHit()
257
|| thread_sp->ShouldRunBeforePublicStop())
258
threads_copy.push_back(thread_sp);
259
}
260
261
// It is possible the threads we were allowing to run all exited and then
262
// maybe the user interrupted or something, then fall back on looking at
263
// all threads:
264
265
if (threads_copy.size() == 0)
266
threads_copy = m_threads;
267
}
268
269
collection::iterator pos, end = threads_copy.end();
270
271
if (log) {
272
log->PutCString("");
273
LLDB_LOGF(log,
274
"ThreadList::%s: %" PRIu64 " threads, %" PRIu64
275
" unsuspended threads",
276
__FUNCTION__, (uint64_t)m_threads.size(),
277
(uint64_t)threads_copy.size());
278
}
279
280
bool did_anybody_stop_for_a_reason = false;
281
282
// If the event is an Interrupt event, then we're going to stop no matter
283
// what. Otherwise, presume we won't stop.
284
bool should_stop = false;
285
if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
286
LLDB_LOGF(
287
log, "ThreadList::%s handling interrupt event, should stop set to true",
288
__FUNCTION__);
289
290
should_stop = true;
291
}
292
293
// Now we run through all the threads and get their stop info's. We want to
294
// make sure to do this first before we start running the ShouldStop, because
295
// one thread's ShouldStop could destroy information (like deleting a thread
296
// specific breakpoint another thread had stopped at) which could lead us to
297
// compute the StopInfo incorrectly. We don't need to use it here, we just
298
// want to make sure it gets computed.
299
300
for (pos = threads_copy.begin(); pos != end; ++pos) {
301
ThreadSP thread_sp(*pos);
302
thread_sp->GetStopInfo();
303
}
304
305
// If a thread needs to finish some job that can be done just on this thread
306
// before broadcastion the stop, it will signal that by returning true for
307
// ShouldRunBeforePublicStop. This variable gathers the results from that.
308
bool a_thread_needs_to_run = false;
309
for (pos = threads_copy.begin(); pos != end; ++pos) {
310
ThreadSP thread_sp(*pos);
311
312
// We should never get a stop for which no thread had a stop reason, but
313
// sometimes we do see this - for instance when we first connect to a
314
// remote stub. In that case we should stop, since we can't figure out the
315
// right thing to do and stopping gives the user control over what to do in
316
// this instance.
317
//
318
// Note, this causes a problem when you have a thread specific breakpoint,
319
// and a bunch of threads hit the breakpoint, but not the thread which we
320
// are waiting for. All the threads that are not "supposed" to hit the
321
// breakpoint are marked as having no stop reason, which is right, they
322
// should not show a stop reason. But that triggers this code and causes
323
// us to stop seemingly for no reason.
324
//
325
// Since the only way we ever saw this error was on first attach, I'm only
326
// going to trigger set did_anybody_stop_for_a_reason to true unless this
327
// is the first stop.
328
//
329
// If this becomes a problem, we'll have to have another StopReason like
330
// "StopInfoHidden" which will look invalid everywhere but at this check.
331
332
if (thread_sp->GetProcess()->GetStopID() > 1)
333
did_anybody_stop_for_a_reason = true;
334
else
335
did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
336
337
const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
338
339
if (thread_should_stop)
340
should_stop |= true;
341
else {
342
bool this_thread_forces_run = thread_sp->ShouldRunBeforePublicStop();
343
a_thread_needs_to_run |= this_thread_forces_run;
344
if (this_thread_forces_run)
345
LLDB_LOG(log,
346
"ThreadList::{0} thread: {1:x}, "
347
"says it needs to run before public stop.",
348
__FUNCTION__, thread_sp->GetID());
349
}
350
}
351
352
if (a_thread_needs_to_run) {
353
should_stop = false;
354
} else if (!should_stop && !did_anybody_stop_for_a_reason) {
355
should_stop = true;
356
LLDB_LOGF(log,
357
"ThreadList::%s we stopped but no threads had a stop reason, "
358
"overriding should_stop and stopping.",
359
__FUNCTION__);
360
}
361
362
LLDB_LOGF(log, "ThreadList::%s overall should_stop = %i", __FUNCTION__,
363
should_stop);
364
365
if (should_stop) {
366
for (pos = threads_copy.begin(); pos != end; ++pos) {
367
ThreadSP thread_sp(*pos);
368
thread_sp->WillStop();
369
}
370
}
371
372
return should_stop;
373
}
374
375
Vote ThreadList::ShouldReportStop(Event *event_ptr) {
376
std::lock_guard<std::recursive_mutex> guard(GetMutex());
377
378
Vote result = eVoteNoOpinion;
379
m_process.UpdateThreadListIfNeeded();
380
collection::iterator pos, end = m_threads.end();
381
382
Log *log = GetLog(LLDBLog::Step);
383
384
LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
385
(uint64_t)m_threads.size());
386
387
// Run through the threads and ask whether we should report this event. For
388
// stopping, a YES vote wins over everything. A NO vote wins over NO
389
// opinion. The exception is if a thread has work it needs to force before
390
// a public stop, which overrides everyone else's opinion:
391
for (pos = m_threads.begin(); pos != end; ++pos) {
392
ThreadSP thread_sp(*pos);
393
if (thread_sp->ShouldRunBeforePublicStop()) {
394
LLDB_LOG(log, "Thread {0:x} has private business to complete, overrode "
395
"the should report stop.", thread_sp->GetID());
396
result = eVoteNo;
397
break;
398
}
399
400
const Vote vote = thread_sp->ShouldReportStop(event_ptr);
401
switch (vote) {
402
case eVoteNoOpinion:
403
continue;
404
405
case eVoteYes:
406
result = eVoteYes;
407
break;
408
409
case eVoteNo:
410
if (result == eVoteNoOpinion) {
411
result = eVoteNo;
412
} else {
413
LLDB_LOG(log,
414
"Thread {0:x} voted {1}, but lost out because result was {2}",
415
thread_sp->GetID(), vote, result);
416
}
417
break;
418
}
419
}
420
LLDB_LOG(log, "Returning {0}", result);
421
return result;
422
}
423
424
void ThreadList::SetShouldReportStop(Vote vote) {
425
std::lock_guard<std::recursive_mutex> guard(GetMutex());
426
427
m_process.UpdateThreadListIfNeeded();
428
collection::iterator pos, end = m_threads.end();
429
for (pos = m_threads.begin(); pos != end; ++pos) {
430
ThreadSP thread_sp(*pos);
431
thread_sp->SetShouldReportStop(vote);
432
}
433
}
434
435
Vote ThreadList::ShouldReportRun(Event *event_ptr) {
436
437
std::lock_guard<std::recursive_mutex> guard(GetMutex());
438
439
Vote result = eVoteNoOpinion;
440
m_process.UpdateThreadListIfNeeded();
441
collection::iterator pos, end = m_threads.end();
442
443
// Run through the threads and ask whether we should report this event. The
444
// rule is NO vote wins over everything, a YES vote wins over no opinion.
445
446
Log *log = GetLog(LLDBLog::Step);
447
448
for (pos = m_threads.begin(); pos != end; ++pos) {
449
if ((*pos)->GetResumeState() != eStateSuspended) {
450
switch ((*pos)->ShouldReportRun(event_ptr)) {
451
case eVoteNoOpinion:
452
continue;
453
case eVoteYes:
454
if (result == eVoteNoOpinion)
455
result = eVoteYes;
456
break;
457
case eVoteNo:
458
LLDB_LOGF(log,
459
"ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
460
") says don't report.",
461
(*pos)->GetIndexID(), (*pos)->GetID());
462
result = eVoteNo;
463
break;
464
}
465
}
466
}
467
return result;
468
}
469
470
void ThreadList::Clear() {
471
std::lock_guard<std::recursive_mutex> guard(GetMutex());
472
m_stop_id = 0;
473
m_threads.clear();
474
m_selected_tid = LLDB_INVALID_THREAD_ID;
475
}
476
477
void ThreadList::Destroy() {
478
std::lock_guard<std::recursive_mutex> guard(GetMutex());
479
const uint32_t num_threads = m_threads.size();
480
for (uint32_t idx = 0; idx < num_threads; ++idx) {
481
m_threads[idx]->DestroyThread();
482
}
483
}
484
485
void ThreadList::RefreshStateAfterStop() {
486
std::lock_guard<std::recursive_mutex> guard(GetMutex());
487
488
m_process.UpdateThreadListIfNeeded();
489
490
Log *log = GetLog(LLDBLog::Step);
491
if (log && log->GetVerbose())
492
LLDB_LOGF(log,
493
"Turning off notification of new threads while single stepping "
494
"a thread.");
495
496
collection::iterator pos, end = m_threads.end();
497
for (pos = m_threads.begin(); pos != end; ++pos)
498
(*pos)->RefreshStateAfterStop();
499
}
500
501
void ThreadList::DiscardThreadPlans() {
502
// You don't need to update the thread list here, because only threads that
503
// you currently know about have any thread plans.
504
std::lock_guard<std::recursive_mutex> guard(GetMutex());
505
506
collection::iterator pos, end = m_threads.end();
507
for (pos = m_threads.begin(); pos != end; ++pos)
508
(*pos)->DiscardThreadPlans(true);
509
}
510
511
bool ThreadList::WillResume() {
512
// Run through the threads and perform their momentary actions. But we only
513
// do this for threads that are running, user suspended threads stay where
514
// they are.
515
516
std::lock_guard<std::recursive_mutex> guard(GetMutex());
517
m_process.UpdateThreadListIfNeeded();
518
519
collection::iterator pos, end = m_threads.end();
520
521
// See if any thread wants to run stopping others. If it does, then we won't
522
// setup the other threads for resume, since they aren't going to get a
523
// chance to run. This is necessary because the SetupForResume might add
524
// "StopOthers" plans which would then get to be part of the who-gets-to-run
525
// negotiation, but they're coming in after the fact, and the threads that
526
// are already set up should take priority.
527
528
bool wants_solo_run = false;
529
530
for (pos = m_threads.begin(); pos != end; ++pos) {
531
lldbassert((*pos)->GetCurrentPlan() &&
532
"thread should not have null thread plan");
533
if ((*pos)->GetResumeState() != eStateSuspended &&
534
(*pos)->GetCurrentPlan()->StopOthers()) {
535
if ((*pos)->IsOperatingSystemPluginThread() &&
536
!(*pos)->GetBackingThread())
537
continue;
538
wants_solo_run = true;
539
break;
540
}
541
}
542
543
if (wants_solo_run) {
544
Log *log = GetLog(LLDBLog::Step);
545
if (log && log->GetVerbose())
546
LLDB_LOGF(log, "Turning on notification of new threads while single "
547
"stepping a thread.");
548
m_process.StartNoticingNewThreads();
549
} else {
550
Log *log = GetLog(LLDBLog::Step);
551
if (log && log->GetVerbose())
552
LLDB_LOGF(log, "Turning off notification of new threads while single "
553
"stepping a thread.");
554
m_process.StopNoticingNewThreads();
555
}
556
557
// Give all the threads that are likely to run a last chance to set up their
558
// state before we negotiate who is actually going to get a chance to run...
559
// Don't set to resume suspended threads, and if any thread wanted to stop
560
// others, only call setup on the threads that request StopOthers...
561
562
for (pos = m_threads.begin(); pos != end; ++pos) {
563
if ((*pos)->GetResumeState() != eStateSuspended &&
564
(!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) {
565
if ((*pos)->IsOperatingSystemPluginThread() &&
566
!(*pos)->GetBackingThread())
567
continue;
568
(*pos)->SetupForResume();
569
}
570
}
571
572
// Now go through the threads and see if any thread wants to run just itself.
573
// if so then pick one and run it.
574
575
ThreadList run_me_only_list(m_process);
576
577
run_me_only_list.SetStopID(m_process.GetStopID());
578
579
// One or more threads might want to "Stop Others". We want to handle all
580
// those requests first. And if there is a thread that wanted to "resume
581
// before a public stop", let it get the first crack:
582
// There are two special kinds of thread that have priority for "StopOthers":
583
// a "ShouldRunBeforePublicStop thread, or the currently selected thread. If
584
// we find one satisfying that critereon, put it here.
585
ThreadSP stop_others_thread_sp;
586
587
for (pos = m_threads.begin(); pos != end; ++pos) {
588
ThreadSP thread_sp(*pos);
589
if (thread_sp->GetResumeState() != eStateSuspended &&
590
thread_sp->GetCurrentPlan()->StopOthers()) {
591
if ((*pos)->IsOperatingSystemPluginThread() &&
592
!(*pos)->GetBackingThread())
593
continue;
594
595
// You can't say "stop others" and also want yourself to be suspended.
596
assert(thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
597
run_me_only_list.AddThread(thread_sp);
598
599
if (thread_sp == GetSelectedThread())
600
stop_others_thread_sp = thread_sp;
601
602
if (thread_sp->ShouldRunBeforePublicStop()) {
603
// This takes precedence, so if we find one of these, service it:
604
stop_others_thread_sp = thread_sp;
605
break;
606
}
607
}
608
}
609
610
bool need_to_resume = true;
611
612
if (run_me_only_list.GetSize(false) == 0) {
613
// Everybody runs as they wish:
614
for (pos = m_threads.begin(); pos != end; ++pos) {
615
ThreadSP thread_sp(*pos);
616
StateType run_state;
617
if (thread_sp->GetResumeState() != eStateSuspended)
618
run_state = thread_sp->GetCurrentPlan()->RunState();
619
else
620
run_state = eStateSuspended;
621
if (!thread_sp->ShouldResume(run_state))
622
need_to_resume = false;
623
}
624
} else {
625
ThreadSP thread_to_run;
626
627
if (stop_others_thread_sp) {
628
thread_to_run = stop_others_thread_sp;
629
} else if (run_me_only_list.GetSize(false) == 1) {
630
thread_to_run = run_me_only_list.GetThreadAtIndex(0);
631
} else {
632
int random_thread =
633
(int)((run_me_only_list.GetSize(false) * (double)rand()) /
634
(RAND_MAX + 1.0));
635
thread_to_run = run_me_only_list.GetThreadAtIndex(random_thread);
636
}
637
638
for (pos = m_threads.begin(); pos != end; ++pos) {
639
ThreadSP thread_sp(*pos);
640
if (thread_sp == thread_to_run) {
641
// Note, a thread might be able to fulfil it's plan w/o actually
642
// resuming. An example of this is a step that changes the current
643
// inlined function depth w/o moving the PC. Check that here:
644
if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
645
need_to_resume = false;
646
} else
647
thread_sp->ShouldResume(eStateSuspended);
648
}
649
}
650
651
return need_to_resume;
652
}
653
654
void ThreadList::DidResume() {
655
std::lock_guard<std::recursive_mutex> guard(GetMutex());
656
collection::iterator pos, end = m_threads.end();
657
for (pos = m_threads.begin(); pos != end; ++pos) {
658
// Don't clear out threads that aren't going to get a chance to run, rather
659
// leave their state for the next time around.
660
ThreadSP thread_sp(*pos);
661
if (thread_sp->GetTemporaryResumeState() != eStateSuspended)
662
thread_sp->DidResume();
663
}
664
}
665
666
void ThreadList::DidStop() {
667
std::lock_guard<std::recursive_mutex> guard(GetMutex());
668
collection::iterator pos, end = m_threads.end();
669
for (pos = m_threads.begin(); pos != end; ++pos) {
670
// Notify threads that the process just stopped. Note, this currently
671
// assumes that all threads in the list stop when the process stops. In
672
// the future we will want to support a debugging model where some threads
673
// continue to run while others are stopped. We either need to handle that
674
// somehow here or create a special thread list containing only threads
675
// which will stop in the code that calls this method (currently
676
// Process::SetPrivateState).
677
ThreadSP thread_sp(*pos);
678
if (StateIsRunningState(thread_sp->GetState()))
679
thread_sp->DidStop();
680
}
681
}
682
683
ThreadSP ThreadList::GetSelectedThread() {
684
std::lock_guard<std::recursive_mutex> guard(GetMutex());
685
ThreadSP thread_sp = FindThreadByID(m_selected_tid);
686
if (!thread_sp.get()) {
687
if (m_threads.size() == 0)
688
return thread_sp;
689
m_selected_tid = m_threads[0]->GetID();
690
thread_sp = m_threads[0];
691
}
692
return thread_sp;
693
}
694
695
bool ThreadList::SetSelectedThreadByID(lldb::tid_t tid, bool notify) {
696
std::lock_guard<std::recursive_mutex> guard(GetMutex());
697
ThreadSP selected_thread_sp(FindThreadByID(tid));
698
if (selected_thread_sp) {
699
m_selected_tid = tid;
700
selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
701
} else
702
m_selected_tid = LLDB_INVALID_THREAD_ID;
703
704
if (notify)
705
NotifySelectedThreadChanged(m_selected_tid);
706
707
return m_selected_tid != LLDB_INVALID_THREAD_ID;
708
}
709
710
bool ThreadList::SetSelectedThreadByIndexID(uint32_t index_id, bool notify) {
711
std::lock_guard<std::recursive_mutex> guard(GetMutex());
712
ThreadSP selected_thread_sp(FindThreadByIndexID(index_id));
713
if (selected_thread_sp.get()) {
714
m_selected_tid = selected_thread_sp->GetID();
715
selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
716
} else
717
m_selected_tid = LLDB_INVALID_THREAD_ID;
718
719
if (notify)
720
NotifySelectedThreadChanged(m_selected_tid);
721
722
return m_selected_tid != LLDB_INVALID_THREAD_ID;
723
}
724
725
void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid) {
726
ThreadSP selected_thread_sp(FindThreadByID(tid));
727
if (selected_thread_sp->EventTypeHasListeners(
728
Thread::eBroadcastBitThreadSelected)) {
729
auto data_sp =
730
std::make_shared<Thread::ThreadEventData>(selected_thread_sp);
731
selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
732
data_sp);
733
}
734
}
735
736
void ThreadList::Update(ThreadList &rhs) {
737
if (this != &rhs) {
738
// We only allow assignments between thread lists describing the same
739
// process. Same process implies same mutex, which means it's enough to lock
740
// just the current object.
741
assert(&m_process == &rhs.m_process);
742
assert(&GetMutex() == &rhs.GetMutex());
743
std::lock_guard<std::recursive_mutex> guard(GetMutex());
744
745
m_stop_id = rhs.m_stop_id;
746
m_threads.swap(rhs.m_threads);
747
m_selected_tid = rhs.m_selected_tid;
748
749
// Now we look for threads that we are done with and make sure to clear
750
// them up as much as possible so anyone with a shared pointer will still
751
// have a reference, but the thread won't be of much use. Using
752
// std::weak_ptr for all backward references (such as a thread to a
753
// process) will eventually solve this issue for us, but for now, we need
754
// to work around the issue
755
collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
756
for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) {
757
// If this thread has already been destroyed, we don't need to look for
758
// it to destroy it again.
759
if (!(*rhs_pos)->IsValid())
760
continue;
761
762
const lldb::tid_t tid = (*rhs_pos)->GetID();
763
bool thread_is_alive = false;
764
const uint32_t num_threads = m_threads.size();
765
for (uint32_t idx = 0; idx < num_threads; ++idx) {
766
ThreadSP backing_thread = m_threads[idx]->GetBackingThread();
767
if (m_threads[idx]->GetID() == tid ||
768
(backing_thread && backing_thread->GetID() == tid)) {
769
thread_is_alive = true;
770
break;
771
}
772
}
773
if (!thread_is_alive) {
774
(*rhs_pos)->DestroyThread();
775
}
776
}
777
}
778
}
779
780
void ThreadList::Flush() {
781
std::lock_guard<std::recursive_mutex> guard(GetMutex());
782
collection::iterator pos, end = m_threads.end();
783
for (pos = m_threads.begin(); pos != end; ++pos)
784
(*pos)->Flush();
785
}
786
787
std::recursive_mutex &ThreadList::GetMutex() const {
788
return m_process.m_thread_mutex;
789
}
790
791
ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
792
lldb::ThreadSP thread_sp)
793
: m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
794
if (thread_sp) {
795
m_tid = thread_sp->GetID();
796
m_thread_list = &thread_sp->GetProcess()->GetThreadList();
797
m_thread_list->PushExpressionExecutionThread(m_tid);
798
}
799
}
800
801