Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/API/SBFrame.cpp
39587 views
1
//===-- SBFrame.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 <algorithm>
10
#include <set>
11
#include <string>
12
13
#include "lldb/API/SBFrame.h"
14
15
#include "lldb/lldb-types.h"
16
17
#include "Utils.h"
18
#include "lldb/Core/Address.h"
19
#include "lldb/Core/Debugger.h"
20
#include "lldb/Core/ValueObjectRegister.h"
21
#include "lldb/Core/ValueObjectVariable.h"
22
#include "lldb/Core/ValueObjectConstResult.h"
23
#include "lldb/Expression/ExpressionVariable.h"
24
#include "lldb/Expression/UserExpression.h"
25
#include "lldb/Host/Host.h"
26
#include "lldb/Symbol/Block.h"
27
#include "lldb/Symbol/Function.h"
28
#include "lldb/Symbol/Symbol.h"
29
#include "lldb/Symbol/SymbolContext.h"
30
#include "lldb/Symbol/Variable.h"
31
#include "lldb/Symbol/VariableList.h"
32
#include "lldb/Target/ExecutionContext.h"
33
#include "lldb/Target/Process.h"
34
#include "lldb/Target/RegisterContext.h"
35
#include "lldb/Target/StackFrame.h"
36
#include "lldb/Target/StackFrameRecognizer.h"
37
#include "lldb/Target/StackID.h"
38
#include "lldb/Target/Target.h"
39
#include "lldb/Target/Thread.h"
40
#include "lldb/Utility/ConstString.h"
41
#include "lldb/Utility/Instrumentation.h"
42
#include "lldb/Utility/LLDBLog.h"
43
#include "lldb/Utility/Stream.h"
44
45
#include "lldb/API/SBAddress.h"
46
#include "lldb/API/SBDebugger.h"
47
#include "lldb/API/SBExpressionOptions.h"
48
#include "lldb/API/SBFormat.h"
49
#include "lldb/API/SBStream.h"
50
#include "lldb/API/SBSymbolContext.h"
51
#include "lldb/API/SBThread.h"
52
#include "lldb/API/SBValue.h"
53
#include "lldb/API/SBVariablesOptions.h"
54
55
#include "llvm/Support/PrettyStackTrace.h"
56
57
using namespace lldb;
58
using namespace lldb_private;
59
60
SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
61
LLDB_INSTRUMENT_VA(this);
62
}
63
64
SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
65
: m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
66
LLDB_INSTRUMENT_VA(this, lldb_object_sp);
67
}
68
69
SBFrame::SBFrame(const SBFrame &rhs) {
70
LLDB_INSTRUMENT_VA(this, rhs);
71
72
m_opaque_sp = clone(rhs.m_opaque_sp);
73
}
74
75
SBFrame::~SBFrame() = default;
76
77
const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
78
LLDB_INSTRUMENT_VA(this, rhs);
79
80
if (this != &rhs)
81
m_opaque_sp = clone(rhs.m_opaque_sp);
82
return *this;
83
}
84
85
StackFrameSP SBFrame::GetFrameSP() const {
86
return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
87
}
88
89
void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
90
return m_opaque_sp->SetFrameSP(lldb_object_sp);
91
}
92
93
bool SBFrame::IsValid() const {
94
LLDB_INSTRUMENT_VA(this);
95
return this->operator bool();
96
}
97
SBFrame::operator bool() const {
98
LLDB_INSTRUMENT_VA(this);
99
100
std::unique_lock<std::recursive_mutex> lock;
101
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
102
103
Target *target = exe_ctx.GetTargetPtr();
104
Process *process = exe_ctx.GetProcessPtr();
105
if (target && process) {
106
Process::StopLocker stop_locker;
107
if (stop_locker.TryLock(&process->GetRunLock()))
108
return GetFrameSP().get() != nullptr;
109
}
110
111
// Without a target & process we can't have a valid stack frame.
112
return false;
113
}
114
115
SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
116
LLDB_INSTRUMENT_VA(this, resolve_scope);
117
118
SBSymbolContext sb_sym_ctx;
119
std::unique_lock<std::recursive_mutex> lock;
120
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
121
SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
122
Target *target = exe_ctx.GetTargetPtr();
123
Process *process = exe_ctx.GetProcessPtr();
124
if (target && process) {
125
Process::StopLocker stop_locker;
126
if (stop_locker.TryLock(&process->GetRunLock())) {
127
if (StackFrame *frame = exe_ctx.GetFramePtr())
128
sb_sym_ctx = frame->GetSymbolContext(scope);
129
}
130
}
131
132
return sb_sym_ctx;
133
}
134
135
SBModule SBFrame::GetModule() const {
136
LLDB_INSTRUMENT_VA(this);
137
138
SBModule sb_module;
139
ModuleSP module_sp;
140
std::unique_lock<std::recursive_mutex> lock;
141
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
142
143
StackFrame *frame = nullptr;
144
Target *target = exe_ctx.GetTargetPtr();
145
Process *process = exe_ctx.GetProcessPtr();
146
if (target && process) {
147
Process::StopLocker stop_locker;
148
if (stop_locker.TryLock(&process->GetRunLock())) {
149
frame = exe_ctx.GetFramePtr();
150
if (frame) {
151
module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
152
sb_module.SetSP(module_sp);
153
}
154
}
155
}
156
157
return sb_module;
158
}
159
160
SBCompileUnit SBFrame::GetCompileUnit() const {
161
LLDB_INSTRUMENT_VA(this);
162
163
SBCompileUnit sb_comp_unit;
164
std::unique_lock<std::recursive_mutex> lock;
165
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
166
167
StackFrame *frame = nullptr;
168
Target *target = exe_ctx.GetTargetPtr();
169
Process *process = exe_ctx.GetProcessPtr();
170
if (target && process) {
171
Process::StopLocker stop_locker;
172
if (stop_locker.TryLock(&process->GetRunLock())) {
173
frame = exe_ctx.GetFramePtr();
174
if (frame) {
175
sb_comp_unit.reset(
176
frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
177
}
178
}
179
}
180
181
return sb_comp_unit;
182
}
183
184
SBFunction SBFrame::GetFunction() const {
185
LLDB_INSTRUMENT_VA(this);
186
187
SBFunction sb_function;
188
std::unique_lock<std::recursive_mutex> lock;
189
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
190
191
StackFrame *frame = nullptr;
192
Target *target = exe_ctx.GetTargetPtr();
193
Process *process = exe_ctx.GetProcessPtr();
194
if (target && process) {
195
Process::StopLocker stop_locker;
196
if (stop_locker.TryLock(&process->GetRunLock())) {
197
frame = exe_ctx.GetFramePtr();
198
if (frame) {
199
sb_function.reset(
200
frame->GetSymbolContext(eSymbolContextFunction).function);
201
}
202
}
203
}
204
205
return sb_function;
206
}
207
208
SBSymbol SBFrame::GetSymbol() const {
209
LLDB_INSTRUMENT_VA(this);
210
211
SBSymbol sb_symbol;
212
std::unique_lock<std::recursive_mutex> lock;
213
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
214
215
StackFrame *frame = nullptr;
216
Target *target = exe_ctx.GetTargetPtr();
217
Process *process = exe_ctx.GetProcessPtr();
218
if (target && process) {
219
Process::StopLocker stop_locker;
220
if (stop_locker.TryLock(&process->GetRunLock())) {
221
frame = exe_ctx.GetFramePtr();
222
if (frame) {
223
sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
224
}
225
}
226
}
227
228
return sb_symbol;
229
}
230
231
SBBlock SBFrame::GetBlock() const {
232
LLDB_INSTRUMENT_VA(this);
233
234
SBBlock sb_block;
235
std::unique_lock<std::recursive_mutex> lock;
236
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
237
238
StackFrame *frame = nullptr;
239
Target *target = exe_ctx.GetTargetPtr();
240
Process *process = exe_ctx.GetProcessPtr();
241
if (target && process) {
242
Process::StopLocker stop_locker;
243
if (stop_locker.TryLock(&process->GetRunLock())) {
244
frame = exe_ctx.GetFramePtr();
245
if (frame)
246
sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
247
}
248
}
249
return sb_block;
250
}
251
252
SBBlock SBFrame::GetFrameBlock() const {
253
LLDB_INSTRUMENT_VA(this);
254
255
SBBlock sb_block;
256
std::unique_lock<std::recursive_mutex> lock;
257
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
258
259
StackFrame *frame = nullptr;
260
Target *target = exe_ctx.GetTargetPtr();
261
Process *process = exe_ctx.GetProcessPtr();
262
if (target && process) {
263
Process::StopLocker stop_locker;
264
if (stop_locker.TryLock(&process->GetRunLock())) {
265
frame = exe_ctx.GetFramePtr();
266
if (frame)
267
sb_block.SetPtr(frame->GetFrameBlock());
268
}
269
}
270
return sb_block;
271
}
272
273
SBLineEntry SBFrame::GetLineEntry() const {
274
LLDB_INSTRUMENT_VA(this);
275
276
SBLineEntry sb_line_entry;
277
std::unique_lock<std::recursive_mutex> lock;
278
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
279
280
StackFrame *frame = nullptr;
281
Target *target = exe_ctx.GetTargetPtr();
282
Process *process = exe_ctx.GetProcessPtr();
283
if (target && process) {
284
Process::StopLocker stop_locker;
285
if (stop_locker.TryLock(&process->GetRunLock())) {
286
frame = exe_ctx.GetFramePtr();
287
if (frame) {
288
sb_line_entry.SetLineEntry(
289
frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
290
}
291
}
292
}
293
return sb_line_entry;
294
}
295
296
uint32_t SBFrame::GetFrameID() const {
297
LLDB_INSTRUMENT_VA(this);
298
299
uint32_t frame_idx = UINT32_MAX;
300
301
std::unique_lock<std::recursive_mutex> lock;
302
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
303
304
StackFrame *frame = exe_ctx.GetFramePtr();
305
if (frame)
306
frame_idx = frame->GetFrameIndex();
307
308
return frame_idx;
309
}
310
311
lldb::addr_t SBFrame::GetCFA() const {
312
LLDB_INSTRUMENT_VA(this);
313
314
std::unique_lock<std::recursive_mutex> lock;
315
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
316
317
StackFrame *frame = exe_ctx.GetFramePtr();
318
if (frame)
319
return frame->GetStackID().GetCallFrameAddress();
320
return LLDB_INVALID_ADDRESS;
321
}
322
323
addr_t SBFrame::GetPC() const {
324
LLDB_INSTRUMENT_VA(this);
325
326
addr_t addr = LLDB_INVALID_ADDRESS;
327
std::unique_lock<std::recursive_mutex> lock;
328
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
329
330
StackFrame *frame = nullptr;
331
Target *target = exe_ctx.GetTargetPtr();
332
Process *process = exe_ctx.GetProcessPtr();
333
if (target && process) {
334
Process::StopLocker stop_locker;
335
if (stop_locker.TryLock(&process->GetRunLock())) {
336
frame = exe_ctx.GetFramePtr();
337
if (frame) {
338
addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
339
target, AddressClass::eCode);
340
}
341
}
342
}
343
344
return addr;
345
}
346
347
bool SBFrame::SetPC(addr_t new_pc) {
348
LLDB_INSTRUMENT_VA(this, new_pc);
349
350
bool ret_val = false;
351
std::unique_lock<std::recursive_mutex> lock;
352
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
353
354
Target *target = exe_ctx.GetTargetPtr();
355
Process *process = exe_ctx.GetProcessPtr();
356
if (target && process) {
357
Process::StopLocker stop_locker;
358
if (stop_locker.TryLock(&process->GetRunLock())) {
359
if (StackFrame *frame = exe_ctx.GetFramePtr()) {
360
if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
361
ret_val = reg_ctx_sp->SetPC(new_pc);
362
}
363
}
364
}
365
}
366
367
return ret_val;
368
}
369
370
addr_t SBFrame::GetSP() const {
371
LLDB_INSTRUMENT_VA(this);
372
373
addr_t addr = LLDB_INVALID_ADDRESS;
374
std::unique_lock<std::recursive_mutex> lock;
375
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
376
377
Target *target = exe_ctx.GetTargetPtr();
378
Process *process = exe_ctx.GetProcessPtr();
379
if (target && process) {
380
Process::StopLocker stop_locker;
381
if (stop_locker.TryLock(&process->GetRunLock())) {
382
if (StackFrame *frame = exe_ctx.GetFramePtr()) {
383
if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
384
addr = reg_ctx_sp->GetSP();
385
}
386
}
387
}
388
}
389
390
return addr;
391
}
392
393
addr_t SBFrame::GetFP() const {
394
LLDB_INSTRUMENT_VA(this);
395
396
addr_t addr = LLDB_INVALID_ADDRESS;
397
std::unique_lock<std::recursive_mutex> lock;
398
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399
400
Target *target = exe_ctx.GetTargetPtr();
401
Process *process = exe_ctx.GetProcessPtr();
402
if (target && process) {
403
Process::StopLocker stop_locker;
404
if (stop_locker.TryLock(&process->GetRunLock())) {
405
if (StackFrame *frame = exe_ctx.GetFramePtr()) {
406
if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
407
addr = reg_ctx_sp->GetFP();
408
}
409
}
410
}
411
}
412
413
return addr;
414
}
415
416
SBAddress SBFrame::GetPCAddress() const {
417
LLDB_INSTRUMENT_VA(this);
418
419
SBAddress sb_addr;
420
std::unique_lock<std::recursive_mutex> lock;
421
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
422
423
StackFrame *frame = exe_ctx.GetFramePtr();
424
Target *target = exe_ctx.GetTargetPtr();
425
Process *process = exe_ctx.GetProcessPtr();
426
if (target && process) {
427
Process::StopLocker stop_locker;
428
if (stop_locker.TryLock(&process->GetRunLock())) {
429
frame = exe_ctx.GetFramePtr();
430
if (frame)
431
sb_addr.SetAddress(frame->GetFrameCodeAddress());
432
}
433
}
434
return sb_addr;
435
}
436
437
void SBFrame::Clear() {
438
LLDB_INSTRUMENT_VA(this);
439
440
m_opaque_sp->Clear();
441
}
442
443
lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
444
LLDB_INSTRUMENT_VA(this, var_path);
445
446
SBValue sb_value;
447
std::unique_lock<std::recursive_mutex> lock;
448
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
449
450
StackFrame *frame = exe_ctx.GetFramePtr();
451
Target *target = exe_ctx.GetTargetPtr();
452
if (frame && target) {
453
lldb::DynamicValueType use_dynamic =
454
frame->CalculateTarget()->GetPreferDynamicValue();
455
sb_value = GetValueForVariablePath(var_path, use_dynamic);
456
}
457
return sb_value;
458
}
459
460
lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
461
DynamicValueType use_dynamic) {
462
LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);
463
464
SBValue sb_value;
465
if (var_path == nullptr || var_path[0] == '\0') {
466
return sb_value;
467
}
468
469
std::unique_lock<std::recursive_mutex> lock;
470
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
471
472
StackFrame *frame = nullptr;
473
Target *target = exe_ctx.GetTargetPtr();
474
Process *process = exe_ctx.GetProcessPtr();
475
if (target && process) {
476
Process::StopLocker stop_locker;
477
if (stop_locker.TryLock(&process->GetRunLock())) {
478
frame = exe_ctx.GetFramePtr();
479
if (frame) {
480
VariableSP var_sp;
481
Status error;
482
ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
483
var_path, eNoDynamicValues,
484
StackFrame::eExpressionPathOptionCheckPtrVsMember |
485
StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
486
var_sp, error));
487
sb_value.SetSP(value_sp, use_dynamic);
488
}
489
}
490
}
491
return sb_value;
492
}
493
494
SBValue SBFrame::FindVariable(const char *name) {
495
LLDB_INSTRUMENT_VA(this, name);
496
497
SBValue value;
498
std::unique_lock<std::recursive_mutex> lock;
499
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
500
501
StackFrame *frame = exe_ctx.GetFramePtr();
502
Target *target = exe_ctx.GetTargetPtr();
503
if (frame && target) {
504
lldb::DynamicValueType use_dynamic =
505
frame->CalculateTarget()->GetPreferDynamicValue();
506
value = FindVariable(name, use_dynamic);
507
}
508
return value;
509
}
510
511
SBValue SBFrame::FindVariable(const char *name,
512
lldb::DynamicValueType use_dynamic) {
513
LLDB_INSTRUMENT_VA(this, name, use_dynamic);
514
515
VariableSP var_sp;
516
SBValue sb_value;
517
518
if (name == nullptr || name[0] == '\0') {
519
return sb_value;
520
}
521
522
ValueObjectSP value_sp;
523
std::unique_lock<std::recursive_mutex> lock;
524
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
525
526
StackFrame *frame = nullptr;
527
Target *target = exe_ctx.GetTargetPtr();
528
Process *process = exe_ctx.GetProcessPtr();
529
if (target && process) {
530
Process::StopLocker stop_locker;
531
if (stop_locker.TryLock(&process->GetRunLock())) {
532
frame = exe_ctx.GetFramePtr();
533
if (frame) {
534
value_sp = frame->FindVariable(ConstString(name));
535
536
if (value_sp)
537
sb_value.SetSP(value_sp, use_dynamic);
538
}
539
}
540
}
541
542
return sb_value;
543
}
544
545
SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
546
LLDB_INSTRUMENT_VA(this, name, value_type);
547
548
SBValue value;
549
std::unique_lock<std::recursive_mutex> lock;
550
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551
552
StackFrame *frame = exe_ctx.GetFramePtr();
553
Target *target = exe_ctx.GetTargetPtr();
554
if (frame && target) {
555
lldb::DynamicValueType use_dynamic =
556
frame->CalculateTarget()->GetPreferDynamicValue();
557
value = FindValue(name, value_type, use_dynamic);
558
}
559
return value;
560
}
561
562
SBValue SBFrame::FindValue(const char *name, ValueType value_type,
563
lldb::DynamicValueType use_dynamic) {
564
LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);
565
566
SBValue sb_value;
567
568
if (name == nullptr || name[0] == '\0') {
569
return sb_value;
570
}
571
572
ValueObjectSP value_sp;
573
std::unique_lock<std::recursive_mutex> lock;
574
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
575
576
StackFrame *frame = nullptr;
577
Target *target = exe_ctx.GetTargetPtr();
578
Process *process = exe_ctx.GetProcessPtr();
579
if (target && process) {
580
Process::StopLocker stop_locker;
581
if (stop_locker.TryLock(&process->GetRunLock())) {
582
frame = exe_ctx.GetFramePtr();
583
if (frame) {
584
VariableList variable_list;
585
586
switch (value_type) {
587
case eValueTypeVariableGlobal: // global variable
588
case eValueTypeVariableStatic: // static variable
589
case eValueTypeVariableArgument: // function argument variables
590
case eValueTypeVariableLocal: // function local variables
591
case eValueTypeVariableThreadLocal: // thread local variables
592
{
593
SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
594
595
const bool can_create = true;
596
const bool get_parent_variables = true;
597
const bool stop_if_block_is_inlined_function = true;
598
599
if (sc.block)
600
sc.block->AppendVariables(
601
can_create, get_parent_variables,
602
stop_if_block_is_inlined_function,
603
[frame](Variable *v) { return v->IsInScope(frame); },
604
&variable_list);
605
if (value_type == eValueTypeVariableGlobal
606
|| value_type == eValueTypeVariableStatic) {
607
const bool get_file_globals = true;
608
VariableList *frame_vars = frame->GetVariableList(get_file_globals,
609
nullptr);
610
if (frame_vars)
611
frame_vars->AppendVariablesIfUnique(variable_list);
612
}
613
ConstString const_name(name);
614
VariableSP variable_sp(
615
variable_list.FindVariable(const_name, value_type));
616
if (variable_sp) {
617
value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
618
eNoDynamicValues);
619
sb_value.SetSP(value_sp, use_dynamic);
620
}
621
} break;
622
623
case eValueTypeRegister: // stack frame register value
624
{
625
RegisterContextSP reg_ctx(frame->GetRegisterContext());
626
if (reg_ctx) {
627
if (const RegisterInfo *reg_info =
628
reg_ctx->GetRegisterInfoByName(name)) {
629
value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
630
sb_value.SetSP(value_sp);
631
}
632
}
633
} break;
634
635
case eValueTypeRegisterSet: // A collection of stack frame register
636
// values
637
{
638
RegisterContextSP reg_ctx(frame->GetRegisterContext());
639
if (reg_ctx) {
640
const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
641
for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
642
const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
643
if (reg_set &&
644
(llvm::StringRef(reg_set->name).equals_insensitive(name) ||
645
llvm::StringRef(reg_set->short_name)
646
.equals_insensitive(name))) {
647
value_sp =
648
ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
649
sb_value.SetSP(value_sp);
650
break;
651
}
652
}
653
}
654
} break;
655
656
case eValueTypeConstResult: // constant result variables
657
{
658
ConstString const_name(name);
659
ExpressionVariableSP expr_var_sp(
660
target->GetPersistentVariable(const_name));
661
if (expr_var_sp) {
662
value_sp = expr_var_sp->GetValueObject();
663
sb_value.SetSP(value_sp, use_dynamic);
664
}
665
} break;
666
667
default:
668
break;
669
}
670
}
671
}
672
}
673
674
return sb_value;
675
}
676
677
bool SBFrame::IsEqual(const SBFrame &that) const {
678
LLDB_INSTRUMENT_VA(this, that);
679
680
lldb::StackFrameSP this_sp = GetFrameSP();
681
lldb::StackFrameSP that_sp = that.GetFrameSP();
682
return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
683
}
684
685
bool SBFrame::operator==(const SBFrame &rhs) const {
686
LLDB_INSTRUMENT_VA(this, rhs);
687
688
return IsEqual(rhs);
689
}
690
691
bool SBFrame::operator!=(const SBFrame &rhs) const {
692
LLDB_INSTRUMENT_VA(this, rhs);
693
694
return !IsEqual(rhs);
695
}
696
697
SBThread SBFrame::GetThread() const {
698
LLDB_INSTRUMENT_VA(this);
699
700
std::unique_lock<std::recursive_mutex> lock;
701
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
702
703
ThreadSP thread_sp(exe_ctx.GetThreadSP());
704
SBThread sb_thread(thread_sp);
705
706
return sb_thread;
707
}
708
709
const char *SBFrame::Disassemble() const {
710
LLDB_INSTRUMENT_VA(this);
711
712
std::unique_lock<std::recursive_mutex> lock;
713
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
714
Target *target = exe_ctx.GetTargetPtr();
715
Process *process = exe_ctx.GetProcessPtr();
716
if (!target || !process)
717
return nullptr;
718
719
Process::StopLocker stop_locker;
720
if (stop_locker.TryLock(&process->GetRunLock())) {
721
if (auto *frame = exe_ctx.GetFramePtr())
722
return ConstString(frame->Disassemble()).GetCString();
723
}
724
725
return nullptr;
726
}
727
728
SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
729
bool in_scope_only) {
730
LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
731
732
SBValueList value_list;
733
std::unique_lock<std::recursive_mutex> lock;
734
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
735
736
StackFrame *frame = exe_ctx.GetFramePtr();
737
Target *target = exe_ctx.GetTargetPtr();
738
if (frame && target) {
739
lldb::DynamicValueType use_dynamic =
740
frame->CalculateTarget()->GetPreferDynamicValue();
741
const bool include_runtime_support_values =
742
target->GetDisplayRuntimeSupportValues();
743
744
SBVariablesOptions options;
745
options.SetIncludeArguments(arguments);
746
options.SetIncludeLocals(locals);
747
options.SetIncludeStatics(statics);
748
options.SetInScopeOnly(in_scope_only);
749
options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
750
options.SetUseDynamic(use_dynamic);
751
752
value_list = GetVariables(options);
753
}
754
return value_list;
755
}
756
757
lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
758
bool statics, bool in_scope_only,
759
lldb::DynamicValueType use_dynamic) {
760
LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
761
use_dynamic);
762
763
std::unique_lock<std::recursive_mutex> lock;
764
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
765
766
Target *target = exe_ctx.GetTargetPtr();
767
const bool include_runtime_support_values =
768
target ? target->GetDisplayRuntimeSupportValues() : false;
769
SBVariablesOptions options;
770
options.SetIncludeArguments(arguments);
771
options.SetIncludeLocals(locals);
772
options.SetIncludeStatics(statics);
773
options.SetInScopeOnly(in_scope_only);
774
options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
775
options.SetUseDynamic(use_dynamic);
776
return GetVariables(options);
777
}
778
779
SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
780
LLDB_INSTRUMENT_VA(this, options);
781
782
SBValueList value_list;
783
std::unique_lock<std::recursive_mutex> lock;
784
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
785
786
StackFrame *frame = nullptr;
787
Target *target = exe_ctx.GetTargetPtr();
788
789
const bool statics = options.GetIncludeStatics();
790
const bool arguments = options.GetIncludeArguments();
791
const bool recognized_arguments =
792
options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
793
const bool locals = options.GetIncludeLocals();
794
const bool in_scope_only = options.GetInScopeOnly();
795
const bool include_runtime_support_values =
796
options.GetIncludeRuntimeSupportValues();
797
const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
798
799
800
std::set<VariableSP> variable_set;
801
Process *process = exe_ctx.GetProcessPtr();
802
if (target && process) {
803
Process::StopLocker stop_locker;
804
if (stop_locker.TryLock(&process->GetRunLock())) {
805
frame = exe_ctx.GetFramePtr();
806
if (frame) {
807
Debugger &dbg = process->GetTarget().GetDebugger();
808
VariableList *variable_list = nullptr;
809
Status var_error;
810
variable_list = frame->GetVariableList(true, &var_error);
811
if (var_error.Fail())
812
value_list.SetError(var_error);
813
if (variable_list) {
814
const size_t num_variables = variable_list->GetSize();
815
if (num_variables) {
816
size_t num_produced = 0;
817
for (const VariableSP &variable_sp : *variable_list) {
818
if (INTERRUPT_REQUESTED(dbg,
819
"Interrupted getting frame variables with {0} of {1} "
820
"produced.", num_produced, num_variables))
821
return {};
822
823
if (variable_sp) {
824
bool add_variable = false;
825
switch (variable_sp->GetScope()) {
826
case eValueTypeVariableGlobal:
827
case eValueTypeVariableStatic:
828
case eValueTypeVariableThreadLocal:
829
add_variable = statics;
830
break;
831
832
case eValueTypeVariableArgument:
833
add_variable = arguments;
834
break;
835
836
case eValueTypeVariableLocal:
837
add_variable = locals;
838
break;
839
840
default:
841
break;
842
}
843
if (add_variable) {
844
// Only add variables once so we don't end up with duplicates
845
if (variable_set.find(variable_sp) == variable_set.end())
846
variable_set.insert(variable_sp);
847
else
848
continue;
849
850
if (in_scope_only && !variable_sp->IsInScope(frame))
851
continue;
852
853
ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
854
variable_sp, eNoDynamicValues));
855
856
if (!include_runtime_support_values && valobj_sp != nullptr &&
857
valobj_sp->IsRuntimeSupportValue())
858
continue;
859
860
SBValue value_sb;
861
value_sb.SetSP(valobj_sp, use_dynamic);
862
value_list.Append(value_sb);
863
}
864
}
865
}
866
num_produced++;
867
}
868
}
869
if (recognized_arguments) {
870
auto recognized_frame = frame->GetRecognizedFrame();
871
if (recognized_frame) {
872
ValueObjectListSP recognized_arg_list =
873
recognized_frame->GetRecognizedArguments();
874
if (recognized_arg_list) {
875
for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
876
SBValue value_sb;
877
value_sb.SetSP(rec_value_sp, use_dynamic);
878
value_list.Append(value_sb);
879
}
880
}
881
}
882
}
883
}
884
}
885
}
886
887
return value_list;
888
}
889
890
SBValueList SBFrame::GetRegisters() {
891
LLDB_INSTRUMENT_VA(this);
892
893
SBValueList value_list;
894
std::unique_lock<std::recursive_mutex> lock;
895
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
896
897
StackFrame *frame = nullptr;
898
Target *target = exe_ctx.GetTargetPtr();
899
Process *process = exe_ctx.GetProcessPtr();
900
if (target && process) {
901
Process::StopLocker stop_locker;
902
if (stop_locker.TryLock(&process->GetRunLock())) {
903
frame = exe_ctx.GetFramePtr();
904
if (frame) {
905
RegisterContextSP reg_ctx(frame->GetRegisterContext());
906
if (reg_ctx) {
907
const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
908
for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
909
value_list.Append(
910
ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
911
}
912
}
913
}
914
}
915
}
916
917
return value_list;
918
}
919
920
SBValue SBFrame::FindRegister(const char *name) {
921
LLDB_INSTRUMENT_VA(this, name);
922
923
SBValue result;
924
ValueObjectSP value_sp;
925
std::unique_lock<std::recursive_mutex> lock;
926
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
927
928
StackFrame *frame = nullptr;
929
Target *target = exe_ctx.GetTargetPtr();
930
Process *process = exe_ctx.GetProcessPtr();
931
if (target && process) {
932
Process::StopLocker stop_locker;
933
if (stop_locker.TryLock(&process->GetRunLock())) {
934
frame = exe_ctx.GetFramePtr();
935
if (frame) {
936
RegisterContextSP reg_ctx(frame->GetRegisterContext());
937
if (reg_ctx) {
938
if (const RegisterInfo *reg_info =
939
reg_ctx->GetRegisterInfoByName(name)) {
940
value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
941
result.SetSP(value_sp);
942
}
943
}
944
}
945
}
946
}
947
948
return result;
949
}
950
951
SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,
952
SBStream &output) {
953
Stream &strm = output.ref();
954
955
std::unique_lock<std::recursive_mutex> lock;
956
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
957
958
StackFrame *frame = nullptr;
959
Target *target = exe_ctx.GetTargetPtr();
960
Process *process = exe_ctx.GetProcessPtr();
961
SBError error;
962
963
if (!format) {
964
error.SetErrorString("The provided SBFormat object is invalid");
965
return error;
966
}
967
968
if (target && process) {
969
Process::StopLocker stop_locker;
970
if (stop_locker.TryLock(&process->GetRunLock())) {
971
frame = exe_ctx.GetFramePtr();
972
if (frame &&
973
frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {
974
return error;
975
}
976
}
977
}
978
error.SetErrorStringWithFormat(
979
"It was not possible to generate a frame "
980
"description with the given format string '%s'",
981
format.GetFormatEntrySP()->string.c_str());
982
return error;
983
}
984
985
bool SBFrame::GetDescription(SBStream &description) {
986
LLDB_INSTRUMENT_VA(this, description);
987
988
Stream &strm = description.ref();
989
990
std::unique_lock<std::recursive_mutex> lock;
991
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
992
993
StackFrame *frame;
994
Target *target = exe_ctx.GetTargetPtr();
995
Process *process = exe_ctx.GetProcessPtr();
996
if (target && process) {
997
Process::StopLocker stop_locker;
998
if (stop_locker.TryLock(&process->GetRunLock())) {
999
frame = exe_ctx.GetFramePtr();
1000
if (frame) {
1001
frame->DumpUsingSettingsFormat(&strm);
1002
}
1003
}
1004
1005
} else
1006
strm.PutCString("No value");
1007
1008
return true;
1009
}
1010
1011
SBValue SBFrame::EvaluateExpression(const char *expr) {
1012
LLDB_INSTRUMENT_VA(this, expr);
1013
1014
SBValue result;
1015
std::unique_lock<std::recursive_mutex> lock;
1016
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1017
1018
StackFrame *frame = exe_ctx.GetFramePtr();
1019
Target *target = exe_ctx.GetTargetPtr();
1020
if (frame && target) {
1021
SBExpressionOptions options;
1022
lldb::DynamicValueType fetch_dynamic_value =
1023
frame->CalculateTarget()->GetPreferDynamicValue();
1024
options.SetFetchDynamicValue(fetch_dynamic_value);
1025
options.SetUnwindOnError(true);
1026
options.SetIgnoreBreakpoints(true);
1027
SourceLanguage language = target->GetLanguage();
1028
if (!language)
1029
language = frame->GetLanguage();
1030
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
1031
return EvaluateExpression(expr, options);
1032
} else {
1033
Status error;
1034
error.SetErrorString("can't evaluate expressions when the "
1035
"process is running.");
1036
ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
1037
result.SetSP(error_val_sp, false);
1038
}
1039
return result;
1040
}
1041
1042
SBValue
1043
SBFrame::EvaluateExpression(const char *expr,
1044
lldb::DynamicValueType fetch_dynamic_value) {
1045
LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);
1046
1047
SBExpressionOptions options;
1048
options.SetFetchDynamicValue(fetch_dynamic_value);
1049
options.SetUnwindOnError(true);
1050
options.SetIgnoreBreakpoints(true);
1051
std::unique_lock<std::recursive_mutex> lock;
1052
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1053
1054
StackFrame *frame = exe_ctx.GetFramePtr();
1055
Target *target = exe_ctx.GetTargetPtr();
1056
SourceLanguage language;
1057
if (target)
1058
language = target->GetLanguage();
1059
if (!language && frame)
1060
language = frame->GetLanguage();
1061
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
1062
return EvaluateExpression(expr, options);
1063
}
1064
1065
SBValue SBFrame::EvaluateExpression(const char *expr,
1066
lldb::DynamicValueType fetch_dynamic_value,
1067
bool unwind_on_error) {
1068
LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
1069
1070
SBExpressionOptions options;
1071
std::unique_lock<std::recursive_mutex> lock;
1072
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1073
1074
options.SetFetchDynamicValue(fetch_dynamic_value);
1075
options.SetUnwindOnError(unwind_on_error);
1076
options.SetIgnoreBreakpoints(true);
1077
StackFrame *frame = exe_ctx.GetFramePtr();
1078
Target *target = exe_ctx.GetTargetPtr();
1079
SourceLanguage language;
1080
if (target)
1081
language = target->GetLanguage();
1082
if (!language && frame)
1083
language = frame->GetLanguage();
1084
options.SetLanguage((SBSourceLanguageName)language.name, language.version);
1085
return EvaluateExpression(expr, options);
1086
}
1087
1088
lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
1089
const SBExpressionOptions &options) {
1090
LLDB_INSTRUMENT_VA(this, expr, options);
1091
1092
Log *expr_log = GetLog(LLDBLog::Expressions);
1093
1094
SBValue expr_result;
1095
1096
if (expr == nullptr || expr[0] == '\0') {
1097
return expr_result;
1098
}
1099
1100
ValueObjectSP expr_value_sp;
1101
1102
std::unique_lock<std::recursive_mutex> lock;
1103
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1104
1105
StackFrame *frame = nullptr;
1106
Target *target = exe_ctx.GetTargetPtr();
1107
Process *process = exe_ctx.GetProcessPtr();
1108
1109
if (target && process) {
1110
Process::StopLocker stop_locker;
1111
if (stop_locker.TryLock(&process->GetRunLock())) {
1112
frame = exe_ctx.GetFramePtr();
1113
if (frame) {
1114
std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
1115
if (target->GetDisplayExpressionsInCrashlogs()) {
1116
StreamString frame_description;
1117
frame->DumpUsingSettingsFormat(&frame_description);
1118
stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
1119
"SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
1120
"= %u) %s",
1121
expr, options.GetFetchDynamicValue(),
1122
frame_description.GetData());
1123
}
1124
1125
target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
1126
expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
1127
}
1128
} else {
1129
Status error;
1130
error.SetErrorString("can't evaluate expressions when the "
1131
"process is running.");
1132
expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1133
expr_result.SetSP(expr_value_sp, false);
1134
}
1135
} else {
1136
Status error;
1137
error.SetErrorString("sbframe object is not valid.");
1138
expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1139
expr_result.SetSP(expr_value_sp, false);
1140
}
1141
1142
if (expr_result.GetError().Success())
1143
LLDB_LOGF(expr_log,
1144
"** [SBFrame::EvaluateExpression] Expression result is "
1145
"%s, summary %s **",
1146
expr_result.GetValue(), expr_result.GetSummary());
1147
else
1148
LLDB_LOGF(expr_log,
1149
"** [SBFrame::EvaluateExpression] Expression evaluation failed: "
1150
"%s **",
1151
expr_result.GetError().GetCString());
1152
1153
return expr_result;
1154
}
1155
1156
bool SBFrame::IsInlined() {
1157
LLDB_INSTRUMENT_VA(this);
1158
1159
return static_cast<const SBFrame *>(this)->IsInlined();
1160
}
1161
1162
bool SBFrame::IsInlined() const {
1163
LLDB_INSTRUMENT_VA(this);
1164
1165
std::unique_lock<std::recursive_mutex> lock;
1166
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1167
1168
StackFrame *frame = nullptr;
1169
Target *target = exe_ctx.GetTargetPtr();
1170
Process *process = exe_ctx.GetProcessPtr();
1171
if (target && process) {
1172
Process::StopLocker stop_locker;
1173
if (stop_locker.TryLock(&process->GetRunLock())) {
1174
frame = exe_ctx.GetFramePtr();
1175
if (frame) {
1176
1177
Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
1178
if (block)
1179
return block->GetContainingInlinedBlock() != nullptr;
1180
}
1181
}
1182
}
1183
return false;
1184
}
1185
1186
bool SBFrame::IsArtificial() {
1187
LLDB_INSTRUMENT_VA(this);
1188
1189
return static_cast<const SBFrame *>(this)->IsArtificial();
1190
}
1191
1192
bool SBFrame::IsArtificial() const {
1193
LLDB_INSTRUMENT_VA(this);
1194
1195
std::unique_lock<std::recursive_mutex> lock;
1196
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1197
1198
StackFrame *frame = exe_ctx.GetFramePtr();
1199
if (frame)
1200
return frame->IsArtificial();
1201
1202
return false;
1203
}
1204
1205
const char *SBFrame::GetFunctionName() {
1206
LLDB_INSTRUMENT_VA(this);
1207
1208
return static_cast<const SBFrame *>(this)->GetFunctionName();
1209
}
1210
1211
lldb::LanguageType SBFrame::GuessLanguage() const {
1212
LLDB_INSTRUMENT_VA(this);
1213
1214
std::unique_lock<std::recursive_mutex> lock;
1215
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1216
1217
StackFrame *frame = nullptr;
1218
Target *target = exe_ctx.GetTargetPtr();
1219
Process *process = exe_ctx.GetProcessPtr();
1220
if (target && process) {
1221
Process::StopLocker stop_locker;
1222
if (stop_locker.TryLock(&process->GetRunLock())) {
1223
frame = exe_ctx.GetFramePtr();
1224
if (frame) {
1225
return frame->GuessLanguage().AsLanguageType();
1226
}
1227
}
1228
}
1229
return eLanguageTypeUnknown;
1230
}
1231
1232
const char *SBFrame::GetFunctionName() const {
1233
LLDB_INSTRUMENT_VA(this);
1234
1235
const char *name = nullptr;
1236
std::unique_lock<std::recursive_mutex> lock;
1237
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1238
1239
StackFrame *frame = nullptr;
1240
Target *target = exe_ctx.GetTargetPtr();
1241
Process *process = exe_ctx.GetProcessPtr();
1242
if (target && process) {
1243
Process::StopLocker stop_locker;
1244
if (stop_locker.TryLock(&process->GetRunLock())) {
1245
frame = exe_ctx.GetFramePtr();
1246
if (frame) {
1247
SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1248
eSymbolContextBlock |
1249
eSymbolContextSymbol));
1250
if (sc.block) {
1251
Block *inlined_block = sc.block->GetContainingInlinedBlock();
1252
if (inlined_block) {
1253
const InlineFunctionInfo *inlined_info =
1254
inlined_block->GetInlinedFunctionInfo();
1255
name = inlined_info->GetName().AsCString();
1256
}
1257
}
1258
1259
if (name == nullptr) {
1260
if (sc.function)
1261
name = sc.function->GetName().GetCString();
1262
}
1263
1264
if (name == nullptr) {
1265
if (sc.symbol)
1266
name = sc.symbol->GetName().GetCString();
1267
}
1268
}
1269
}
1270
}
1271
return name;
1272
}
1273
1274
const char *SBFrame::GetDisplayFunctionName() {
1275
LLDB_INSTRUMENT_VA(this);
1276
1277
const char *name = nullptr;
1278
1279
std::unique_lock<std::recursive_mutex> lock;
1280
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1281
1282
StackFrame *frame = nullptr;
1283
Target *target = exe_ctx.GetTargetPtr();
1284
Process *process = exe_ctx.GetProcessPtr();
1285
if (target && process) {
1286
Process::StopLocker stop_locker;
1287
if (stop_locker.TryLock(&process->GetRunLock())) {
1288
frame = exe_ctx.GetFramePtr();
1289
if (frame) {
1290
SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1291
eSymbolContextBlock |
1292
eSymbolContextSymbol));
1293
if (sc.block) {
1294
Block *inlined_block = sc.block->GetContainingInlinedBlock();
1295
if (inlined_block) {
1296
const InlineFunctionInfo *inlined_info =
1297
inlined_block->GetInlinedFunctionInfo();
1298
name = inlined_info->GetDisplayName().AsCString();
1299
}
1300
}
1301
1302
if (name == nullptr) {
1303
if (sc.function)
1304
name = sc.function->GetDisplayName().GetCString();
1305
}
1306
1307
if (name == nullptr) {
1308
if (sc.symbol)
1309
name = sc.symbol->GetDisplayName().GetCString();
1310
}
1311
}
1312
}
1313
}
1314
return name;
1315
}
1316
1317