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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of lldb/source/API/SBFrame.cpp