Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp
39587 views
1
//===-- ExecutionContext.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 "lldb/Target/ExecutionContext.h"
10
#include "lldb/Target/ExecutionContextScope.h"
11
#include "lldb/Target/Process.h"
12
#include "lldb/Target/StackFrame.h"
13
#include "lldb/Target/Target.h"
14
#include "lldb/Target/Thread.h"
15
#include "lldb/Utility/State.h"
16
17
using namespace lldb_private;
18
19
ExecutionContext::ExecutionContext()
20
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {}
21
22
ExecutionContext::ExecutionContext(const ExecutionContext &rhs) = default;
23
24
ExecutionContext::ExecutionContext(const lldb::TargetSP &target_sp,
25
bool get_process)
26
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
27
if (target_sp)
28
SetContext(target_sp, get_process);
29
}
30
31
ExecutionContext::ExecutionContext(const lldb::ProcessSP &process_sp)
32
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
33
if (process_sp)
34
SetContext(process_sp);
35
}
36
37
ExecutionContext::ExecutionContext(const lldb::ThreadSP &thread_sp)
38
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
39
if (thread_sp)
40
SetContext(thread_sp);
41
}
42
43
ExecutionContext::ExecutionContext(const lldb::StackFrameSP &frame_sp)
44
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
45
if (frame_sp)
46
SetContext(frame_sp);
47
}
48
49
ExecutionContext::ExecutionContext(const lldb::TargetWP &target_wp,
50
bool get_process)
51
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
52
lldb::TargetSP target_sp(target_wp.lock());
53
if (target_sp)
54
SetContext(target_sp, get_process);
55
}
56
57
ExecutionContext::ExecutionContext(const lldb::ProcessWP &process_wp)
58
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
59
lldb::ProcessSP process_sp(process_wp.lock());
60
if (process_sp)
61
SetContext(process_sp);
62
}
63
64
ExecutionContext::ExecutionContext(const lldb::ThreadWP &thread_wp)
65
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
66
lldb::ThreadSP thread_sp(thread_wp.lock());
67
if (thread_sp)
68
SetContext(thread_sp);
69
}
70
71
ExecutionContext::ExecutionContext(const lldb::StackFrameWP &frame_wp)
72
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
73
lldb::StackFrameSP frame_sp(frame_wp.lock());
74
if (frame_sp)
75
SetContext(frame_sp);
76
}
77
78
ExecutionContext::ExecutionContext(Target *t,
79
bool fill_current_process_thread_frame)
80
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
81
if (t) {
82
m_target_sp = t->shared_from_this();
83
if (fill_current_process_thread_frame) {
84
m_process_sp = t->GetProcessSP();
85
if (m_process_sp) {
86
m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread();
87
if (m_thread_sp)
88
m_frame_sp =
89
m_thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
90
}
91
}
92
}
93
}
94
95
ExecutionContext::ExecutionContext(Process *process, Thread *thread,
96
StackFrame *frame)
97
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
98
if (process) {
99
m_process_sp = process->shared_from_this();
100
m_target_sp = process->GetTarget().shared_from_this();
101
}
102
if (thread)
103
m_thread_sp = thread->shared_from_this();
104
if (frame)
105
m_frame_sp = frame->shared_from_this();
106
}
107
108
ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref)
109
: m_target_sp(exe_ctx_ref.GetTargetSP()),
110
m_process_sp(exe_ctx_ref.GetProcessSP()),
111
m_thread_sp(exe_ctx_ref.GetThreadSP()),
112
m_frame_sp(exe_ctx_ref.GetFrameSP()) {}
113
114
ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
115
bool thread_and_frame_only_if_stopped)
116
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
117
if (exe_ctx_ref_ptr) {
118
m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
119
m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
120
if (!thread_and_frame_only_if_stopped ||
121
(m_process_sp && StateIsStoppedState(m_process_sp->GetState(), true))) {
122
m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
123
m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
124
}
125
}
126
}
127
128
ExecutionContext::ExecutionContext(const ExecutionContextRef *exe_ctx_ref_ptr,
129
std::unique_lock<std::recursive_mutex> &lock)
130
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
131
if (exe_ctx_ref_ptr) {
132
m_target_sp = exe_ctx_ref_ptr->GetTargetSP();
133
if (m_target_sp) {
134
lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
135
136
m_process_sp = exe_ctx_ref_ptr->GetProcessSP();
137
m_thread_sp = exe_ctx_ref_ptr->GetThreadSP();
138
m_frame_sp = exe_ctx_ref_ptr->GetFrameSP();
139
}
140
}
141
}
142
143
ExecutionContext::ExecutionContext(const ExecutionContextRef &exe_ctx_ref,
144
std::unique_lock<std::recursive_mutex> &lock)
145
: m_target_sp(exe_ctx_ref.GetTargetSP()), m_process_sp(), m_thread_sp(),
146
m_frame_sp() {
147
if (m_target_sp) {
148
lock = std::unique_lock<std::recursive_mutex>(m_target_sp->GetAPIMutex());
149
150
m_process_sp = exe_ctx_ref.GetProcessSP();
151
m_thread_sp = exe_ctx_ref.GetThreadSP();
152
m_frame_sp = exe_ctx_ref.GetFrameSP();
153
}
154
}
155
156
ExecutionContext::ExecutionContext(ExecutionContextScope *exe_scope_ptr)
157
: m_target_sp(), m_process_sp(), m_thread_sp(), m_frame_sp() {
158
if (exe_scope_ptr)
159
exe_scope_ptr->CalculateExecutionContext(*this);
160
}
161
162
ExecutionContext::ExecutionContext(ExecutionContextScope &exe_scope_ref) {
163
exe_scope_ref.CalculateExecutionContext(*this);
164
}
165
166
void ExecutionContext::Clear() {
167
m_target_sp.reset();
168
m_process_sp.reset();
169
m_thread_sp.reset();
170
m_frame_sp.reset();
171
}
172
173
ExecutionContext::~ExecutionContext() = default;
174
175
uint32_t ExecutionContext::GetAddressByteSize() const {
176
if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
177
return m_target_sp->GetArchitecture().GetAddressByteSize();
178
if (m_process_sp)
179
return m_process_sp->GetAddressByteSize();
180
return sizeof(void *);
181
}
182
183
lldb::ByteOrder ExecutionContext::GetByteOrder() const {
184
if (m_target_sp && m_target_sp->GetArchitecture().IsValid())
185
return m_target_sp->GetArchitecture().GetByteOrder();
186
if (m_process_sp)
187
return m_process_sp->GetByteOrder();
188
return endian::InlHostByteOrder();
189
}
190
191
RegisterContext *ExecutionContext::GetRegisterContext() const {
192
if (m_frame_sp)
193
return m_frame_sp->GetRegisterContext().get();
194
else if (m_thread_sp)
195
return m_thread_sp->GetRegisterContext().get();
196
return nullptr;
197
}
198
199
Target *ExecutionContext::GetTargetPtr() const {
200
if (m_target_sp)
201
return m_target_sp.get();
202
if (m_process_sp)
203
return &m_process_sp->GetTarget();
204
return nullptr;
205
}
206
207
Process *ExecutionContext::GetProcessPtr() const {
208
if (m_process_sp)
209
return m_process_sp.get();
210
if (m_target_sp)
211
return m_target_sp->GetProcessSP().get();
212
return nullptr;
213
}
214
215
ExecutionContextScope *ExecutionContext::GetBestExecutionContextScope() const {
216
if (m_frame_sp)
217
return m_frame_sp.get();
218
if (m_thread_sp)
219
return m_thread_sp.get();
220
if (m_process_sp)
221
return m_process_sp.get();
222
return m_target_sp.get();
223
}
224
225
Target &ExecutionContext::GetTargetRef() const {
226
assert(m_target_sp);
227
return *m_target_sp;
228
}
229
230
Process &ExecutionContext::GetProcessRef() const {
231
assert(m_process_sp);
232
return *m_process_sp;
233
}
234
235
Thread &ExecutionContext::GetThreadRef() const {
236
assert(m_thread_sp);
237
return *m_thread_sp;
238
}
239
240
StackFrame &ExecutionContext::GetFrameRef() const {
241
assert(m_frame_sp);
242
return *m_frame_sp;
243
}
244
245
void ExecutionContext::SetTargetSP(const lldb::TargetSP &target_sp) {
246
m_target_sp = target_sp;
247
}
248
249
void ExecutionContext::SetProcessSP(const lldb::ProcessSP &process_sp) {
250
m_process_sp = process_sp;
251
}
252
253
void ExecutionContext::SetThreadSP(const lldb::ThreadSP &thread_sp) {
254
m_thread_sp = thread_sp;
255
}
256
257
void ExecutionContext::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
258
m_frame_sp = frame_sp;
259
}
260
261
void ExecutionContext::SetTargetPtr(Target *target) {
262
if (target)
263
m_target_sp = target->shared_from_this();
264
else
265
m_target_sp.reset();
266
}
267
268
void ExecutionContext::SetProcessPtr(Process *process) {
269
if (process)
270
m_process_sp = process->shared_from_this();
271
else
272
m_process_sp.reset();
273
}
274
275
void ExecutionContext::SetThreadPtr(Thread *thread) {
276
if (thread)
277
m_thread_sp = thread->shared_from_this();
278
else
279
m_thread_sp.reset();
280
}
281
282
void ExecutionContext::SetFramePtr(StackFrame *frame) {
283
if (frame)
284
m_frame_sp = frame->shared_from_this();
285
else
286
m_frame_sp.reset();
287
}
288
289
void ExecutionContext::SetContext(const lldb::TargetSP &target_sp,
290
bool get_process) {
291
m_target_sp = target_sp;
292
if (get_process && target_sp)
293
m_process_sp = target_sp->GetProcessSP();
294
else
295
m_process_sp.reset();
296
m_thread_sp.reset();
297
m_frame_sp.reset();
298
}
299
300
void ExecutionContext::SetContext(const lldb::ProcessSP &process_sp) {
301
m_process_sp = process_sp;
302
if (process_sp)
303
m_target_sp = process_sp->GetTarget().shared_from_this();
304
else
305
m_target_sp.reset();
306
m_thread_sp.reset();
307
m_frame_sp.reset();
308
}
309
310
void ExecutionContext::SetContext(const lldb::ThreadSP &thread_sp) {
311
m_frame_sp.reset();
312
m_thread_sp = thread_sp;
313
if (thread_sp) {
314
m_process_sp = thread_sp->GetProcess();
315
if (m_process_sp)
316
m_target_sp = m_process_sp->GetTarget().shared_from_this();
317
else
318
m_target_sp.reset();
319
} else {
320
m_target_sp.reset();
321
m_process_sp.reset();
322
}
323
}
324
325
void ExecutionContext::SetContext(const lldb::StackFrameSP &frame_sp) {
326
m_frame_sp = frame_sp;
327
if (frame_sp) {
328
m_thread_sp = frame_sp->CalculateThread();
329
if (m_thread_sp) {
330
m_process_sp = m_thread_sp->GetProcess();
331
if (m_process_sp)
332
m_target_sp = m_process_sp->GetTarget().shared_from_this();
333
else
334
m_target_sp.reset();
335
} else {
336
m_target_sp.reset();
337
m_process_sp.reset();
338
}
339
} else {
340
m_target_sp.reset();
341
m_process_sp.reset();
342
m_thread_sp.reset();
343
}
344
}
345
346
ExecutionContext &ExecutionContext::operator=(const ExecutionContext &rhs) {
347
if (this != &rhs) {
348
m_target_sp = rhs.m_target_sp;
349
m_process_sp = rhs.m_process_sp;
350
m_thread_sp = rhs.m_thread_sp;
351
m_frame_sp = rhs.m_frame_sp;
352
}
353
return *this;
354
}
355
356
bool ExecutionContext::operator==(const ExecutionContext &rhs) const {
357
// Check that the frame shared pointers match, or both are valid and their
358
// stack IDs match since sometimes we get new objects that represent the same
359
// frame within a thread.
360
if ((m_frame_sp == rhs.m_frame_sp) ||
361
(m_frame_sp && rhs.m_frame_sp &&
362
m_frame_sp->GetStackID() == rhs.m_frame_sp->GetStackID())) {
363
// Check that the thread shared pointers match, or both are valid and their
364
// thread IDs match since sometimes we get new objects that represent the
365
// same thread within a process.
366
if ((m_thread_sp == rhs.m_thread_sp) ||
367
(m_thread_sp && rhs.m_thread_sp &&
368
m_thread_sp->GetID() == rhs.m_thread_sp->GetID())) {
369
// Processes and targets don't change much
370
return m_process_sp == rhs.m_process_sp && m_target_sp == rhs.m_target_sp;
371
}
372
}
373
return false;
374
}
375
376
bool ExecutionContext::operator!=(const ExecutionContext &rhs) const {
377
return !(*this == rhs);
378
}
379
380
bool ExecutionContext::HasTargetScope() const {
381
return ((bool)m_target_sp && m_target_sp->IsValid());
382
}
383
384
bool ExecutionContext::HasProcessScope() const {
385
return (HasTargetScope() && ((bool)m_process_sp && m_process_sp->IsValid()));
386
}
387
388
bool ExecutionContext::HasThreadScope() const {
389
return (HasProcessScope() && ((bool)m_thread_sp && m_thread_sp->IsValid()));
390
}
391
392
bool ExecutionContext::HasFrameScope() const {
393
return HasThreadScope() && m_frame_sp;
394
}
395
396
ExecutionContextRef::ExecutionContextRef()
397
: m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {}
398
399
ExecutionContextRef::ExecutionContextRef(const ExecutionContext *exe_ctx)
400
: m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
401
if (exe_ctx)
402
*this = *exe_ctx;
403
}
404
405
ExecutionContextRef::ExecutionContextRef(const ExecutionContext &exe_ctx)
406
: m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
407
*this = exe_ctx;
408
}
409
410
ExecutionContextRef::ExecutionContextRef(Target *target, bool adopt_selected)
411
: m_target_wp(), m_process_wp(), m_thread_wp(), m_stack_id() {
412
SetTargetPtr(target, adopt_selected);
413
}
414
415
ExecutionContextRef::ExecutionContextRef(const ExecutionContextRef &rhs)
416
417
= default;
418
419
ExecutionContextRef &ExecutionContextRef::
420
operator=(const ExecutionContextRef &rhs) {
421
if (this != &rhs) {
422
m_target_wp = rhs.m_target_wp;
423
m_process_wp = rhs.m_process_wp;
424
m_thread_wp = rhs.m_thread_wp;
425
m_tid = rhs.m_tid;
426
m_stack_id = rhs.m_stack_id;
427
}
428
return *this;
429
}
430
431
ExecutionContextRef &ExecutionContextRef::
432
operator=(const ExecutionContext &exe_ctx) {
433
m_target_wp = exe_ctx.GetTargetSP();
434
m_process_wp = exe_ctx.GetProcessSP();
435
lldb::ThreadSP thread_sp(exe_ctx.GetThreadSP());
436
m_thread_wp = thread_sp;
437
if (thread_sp)
438
m_tid = thread_sp->GetID();
439
else
440
m_tid = LLDB_INVALID_THREAD_ID;
441
lldb::StackFrameSP frame_sp(exe_ctx.GetFrameSP());
442
if (frame_sp)
443
m_stack_id = frame_sp->GetStackID();
444
else
445
m_stack_id.Clear();
446
return *this;
447
}
448
449
void ExecutionContextRef::Clear() {
450
m_target_wp.reset();
451
m_process_wp.reset();
452
ClearThread();
453
ClearFrame();
454
}
455
456
ExecutionContextRef::~ExecutionContextRef() = default;
457
458
void ExecutionContextRef::SetTargetSP(const lldb::TargetSP &target_sp) {
459
m_target_wp = target_sp;
460
}
461
462
void ExecutionContextRef::SetProcessSP(const lldb::ProcessSP &process_sp) {
463
if (process_sp) {
464
m_process_wp = process_sp;
465
SetTargetSP(process_sp->GetTarget().shared_from_this());
466
} else {
467
m_process_wp.reset();
468
m_target_wp.reset();
469
}
470
}
471
472
void ExecutionContextRef::SetThreadSP(const lldb::ThreadSP &thread_sp) {
473
if (thread_sp) {
474
m_thread_wp = thread_sp;
475
m_tid = thread_sp->GetID();
476
SetProcessSP(thread_sp->GetProcess());
477
} else {
478
ClearThread();
479
m_process_wp.reset();
480
m_target_wp.reset();
481
}
482
}
483
484
void ExecutionContextRef::SetFrameSP(const lldb::StackFrameSP &frame_sp) {
485
if (frame_sp) {
486
m_stack_id = frame_sp->GetStackID();
487
SetThreadSP(frame_sp->GetThread());
488
} else {
489
ClearFrame();
490
ClearThread();
491
m_process_wp.reset();
492
m_target_wp.reset();
493
}
494
}
495
496
void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) {
497
Clear();
498
if (target) {
499
lldb::TargetSP target_sp(target->shared_from_this());
500
if (target_sp) {
501
m_target_wp = target_sp;
502
if (adopt_selected) {
503
lldb::ProcessSP process_sp(target_sp->GetProcessSP());
504
if (process_sp) {
505
m_process_wp = process_sp;
506
if (process_sp) {
507
// Only fill in the thread and frame if our process is stopped
508
// Don't just check the state, since we might be in the middle of
509
// resuming.
510
Process::StopLocker stop_locker;
511
512
if (stop_locker.TryLock(&process_sp->GetRunLock()) &&
513
StateIsStoppedState(process_sp->GetState(), true)) {
514
lldb::ThreadSP thread_sp(
515
process_sp->GetThreadList().GetSelectedThread());
516
if (!thread_sp)
517
thread_sp = process_sp->GetThreadList().GetThreadAtIndex(0);
518
519
if (thread_sp) {
520
SetThreadSP(thread_sp);
521
lldb::StackFrameSP frame_sp(
522
thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame));
523
if (!frame_sp)
524
frame_sp = thread_sp->GetStackFrameAtIndex(0);
525
if (frame_sp)
526
SetFrameSP(frame_sp);
527
}
528
}
529
}
530
}
531
}
532
}
533
}
534
}
535
536
void ExecutionContextRef::SetProcessPtr(Process *process) {
537
if (process) {
538
SetProcessSP(process->shared_from_this());
539
} else {
540
m_process_wp.reset();
541
m_target_wp.reset();
542
}
543
}
544
545
void ExecutionContextRef::SetThreadPtr(Thread *thread) {
546
if (thread) {
547
SetThreadSP(thread->shared_from_this());
548
} else {
549
ClearThread();
550
m_process_wp.reset();
551
m_target_wp.reset();
552
}
553
}
554
555
void ExecutionContextRef::SetFramePtr(StackFrame *frame) {
556
if (frame)
557
SetFrameSP(frame->shared_from_this());
558
else
559
Clear();
560
}
561
562
lldb::TargetSP ExecutionContextRef::GetTargetSP() const {
563
lldb::TargetSP target_sp(m_target_wp.lock());
564
if (target_sp && !target_sp->IsValid())
565
target_sp.reset();
566
return target_sp;
567
}
568
569
lldb::ProcessSP ExecutionContextRef::GetProcessSP() const {
570
lldb::ProcessSP process_sp(m_process_wp.lock());
571
if (process_sp && !process_sp->IsValid())
572
process_sp.reset();
573
return process_sp;
574
}
575
576
lldb::ThreadSP ExecutionContextRef::GetThreadSP() const {
577
lldb::ThreadSP thread_sp(m_thread_wp.lock());
578
579
if (m_tid != LLDB_INVALID_THREAD_ID) {
580
// We check if the thread has been destroyed in cases where clients might
581
// still have shared pointer to a thread, but the thread is not valid
582
// anymore (not part of the process)
583
if (!thread_sp || !thread_sp->IsValid()) {
584
lldb::ProcessSP process_sp(GetProcessSP());
585
if (process_sp && process_sp->IsValid()) {
586
thread_sp = process_sp->GetThreadList().FindThreadByID(m_tid);
587
m_thread_wp = thread_sp;
588
}
589
}
590
}
591
592
// Check that we aren't about to return an invalid thread sp. We might
593
// return a nullptr thread_sp, but don't return an invalid one.
594
595
if (thread_sp && !thread_sp->IsValid())
596
thread_sp.reset();
597
598
return thread_sp;
599
}
600
601
lldb::StackFrameSP ExecutionContextRef::GetFrameSP() const {
602
if (m_stack_id.IsValid()) {
603
lldb::ThreadSP thread_sp(GetThreadSP());
604
if (thread_sp)
605
return thread_sp->GetFrameWithStackID(m_stack_id);
606
}
607
return lldb::StackFrameSP();
608
}
609
610
ExecutionContext
611
ExecutionContextRef::Lock(bool thread_and_frame_only_if_stopped) const {
612
return ExecutionContext(this, thread_and_frame_only_if_stopped);
613
}
614
615