Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / API / SBFrame.cpp
blobda5c6075e8f7b4b609dd3a5bd7117ffeb4755255
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 //===----------------------------------------------------------------------===//
9 #include <algorithm>
10 #include <set>
11 #include <string>
13 #include "lldb/API/SBFrame.h"
15 #include "lldb/lldb-types.h"
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"
45 #include "lldb/API/SBAddress.h"
46 #include "lldb/API/SBDebugger.h"
47 #include "lldb/API/SBExpressionOptions.h"
48 #include "lldb/API/SBStream.h"
49 #include "lldb/API/SBSymbolContext.h"
50 #include "lldb/API/SBThread.h"
51 #include "lldb/API/SBValue.h"
52 #include "lldb/API/SBVariablesOptions.h"
54 #include "llvm/Support/PrettyStackTrace.h"
56 using namespace lldb;
57 using namespace lldb_private;
59 SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {
60 LLDB_INSTRUMENT_VA(this);
63 SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)
64 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {
65 LLDB_INSTRUMENT_VA(this, lldb_object_sp);
68 SBFrame::SBFrame(const SBFrame &rhs) {
69 LLDB_INSTRUMENT_VA(this, rhs);
71 m_opaque_sp = clone(rhs.m_opaque_sp);
74 SBFrame::~SBFrame() = default;
76 const SBFrame &SBFrame::operator=(const SBFrame &rhs) {
77 LLDB_INSTRUMENT_VA(this, rhs);
79 if (this != &rhs)
80 m_opaque_sp = clone(rhs.m_opaque_sp);
81 return *this;
84 StackFrameSP SBFrame::GetFrameSP() const {
85 return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());
88 void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {
89 return m_opaque_sp->SetFrameSP(lldb_object_sp);
92 bool SBFrame::IsValid() const {
93 LLDB_INSTRUMENT_VA(this);
94 return this->operator bool();
96 SBFrame::operator bool() const {
97 LLDB_INSTRUMENT_VA(this);
99 std::unique_lock<std::recursive_mutex> lock;
100 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
102 Target *target = exe_ctx.GetTargetPtr();
103 Process *process = exe_ctx.GetProcessPtr();
104 if (target && process) {
105 Process::StopLocker stop_locker;
106 if (stop_locker.TryLock(&process->GetRunLock()))
107 return GetFrameSP().get() != nullptr;
110 // Without a target & process we can't have a valid stack frame.
111 return false;
114 SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {
115 LLDB_INSTRUMENT_VA(this, resolve_scope);
117 SBSymbolContext sb_sym_ctx;
118 std::unique_lock<std::recursive_mutex> lock;
119 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
120 SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);
121 Target *target = exe_ctx.GetTargetPtr();
122 Process *process = exe_ctx.GetProcessPtr();
123 if (target && process) {
124 Process::StopLocker stop_locker;
125 if (stop_locker.TryLock(&process->GetRunLock())) {
126 if (StackFrame *frame = exe_ctx.GetFramePtr())
127 sb_sym_ctx = frame->GetSymbolContext(scope);
131 return sb_sym_ctx;
134 SBModule SBFrame::GetModule() const {
135 LLDB_INSTRUMENT_VA(this);
137 SBModule sb_module;
138 ModuleSP module_sp;
139 std::unique_lock<std::recursive_mutex> lock;
140 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
142 StackFrame *frame = nullptr;
143 Target *target = exe_ctx.GetTargetPtr();
144 Process *process = exe_ctx.GetProcessPtr();
145 if (target && process) {
146 Process::StopLocker stop_locker;
147 if (stop_locker.TryLock(&process->GetRunLock())) {
148 frame = exe_ctx.GetFramePtr();
149 if (frame) {
150 module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;
151 sb_module.SetSP(module_sp);
156 return sb_module;
159 SBCompileUnit SBFrame::GetCompileUnit() const {
160 LLDB_INSTRUMENT_VA(this);
162 SBCompileUnit sb_comp_unit;
163 std::unique_lock<std::recursive_mutex> lock;
164 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
166 StackFrame *frame = nullptr;
167 Target *target = exe_ctx.GetTargetPtr();
168 Process *process = exe_ctx.GetProcessPtr();
169 if (target && process) {
170 Process::StopLocker stop_locker;
171 if (stop_locker.TryLock(&process->GetRunLock())) {
172 frame = exe_ctx.GetFramePtr();
173 if (frame) {
174 sb_comp_unit.reset(
175 frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);
180 return sb_comp_unit;
183 SBFunction SBFrame::GetFunction() const {
184 LLDB_INSTRUMENT_VA(this);
186 SBFunction sb_function;
187 std::unique_lock<std::recursive_mutex> lock;
188 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
190 StackFrame *frame = nullptr;
191 Target *target = exe_ctx.GetTargetPtr();
192 Process *process = exe_ctx.GetProcessPtr();
193 if (target && process) {
194 Process::StopLocker stop_locker;
195 if (stop_locker.TryLock(&process->GetRunLock())) {
196 frame = exe_ctx.GetFramePtr();
197 if (frame) {
198 sb_function.reset(
199 frame->GetSymbolContext(eSymbolContextFunction).function);
204 return sb_function;
207 SBSymbol SBFrame::GetSymbol() const {
208 LLDB_INSTRUMENT_VA(this);
210 SBSymbol sb_symbol;
211 std::unique_lock<std::recursive_mutex> lock;
212 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
214 StackFrame *frame = nullptr;
215 Target *target = exe_ctx.GetTargetPtr();
216 Process *process = exe_ctx.GetProcessPtr();
217 if (target && process) {
218 Process::StopLocker stop_locker;
219 if (stop_locker.TryLock(&process->GetRunLock())) {
220 frame = exe_ctx.GetFramePtr();
221 if (frame) {
222 sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);
227 return sb_symbol;
230 SBBlock SBFrame::GetBlock() const {
231 LLDB_INSTRUMENT_VA(this);
233 SBBlock sb_block;
234 std::unique_lock<std::recursive_mutex> lock;
235 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
237 StackFrame *frame = nullptr;
238 Target *target = exe_ctx.GetTargetPtr();
239 Process *process = exe_ctx.GetProcessPtr();
240 if (target && process) {
241 Process::StopLocker stop_locker;
242 if (stop_locker.TryLock(&process->GetRunLock())) {
243 frame = exe_ctx.GetFramePtr();
244 if (frame)
245 sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);
248 return sb_block;
251 SBBlock SBFrame::GetFrameBlock() const {
252 LLDB_INSTRUMENT_VA(this);
254 SBBlock sb_block;
255 std::unique_lock<std::recursive_mutex> lock;
256 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
258 StackFrame *frame = nullptr;
259 Target *target = exe_ctx.GetTargetPtr();
260 Process *process = exe_ctx.GetProcessPtr();
261 if (target && process) {
262 Process::StopLocker stop_locker;
263 if (stop_locker.TryLock(&process->GetRunLock())) {
264 frame = exe_ctx.GetFramePtr();
265 if (frame)
266 sb_block.SetPtr(frame->GetFrameBlock());
269 return sb_block;
272 SBLineEntry SBFrame::GetLineEntry() const {
273 LLDB_INSTRUMENT_VA(this);
275 SBLineEntry sb_line_entry;
276 std::unique_lock<std::recursive_mutex> lock;
277 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
279 StackFrame *frame = nullptr;
280 Target *target = exe_ctx.GetTargetPtr();
281 Process *process = exe_ctx.GetProcessPtr();
282 if (target && process) {
283 Process::StopLocker stop_locker;
284 if (stop_locker.TryLock(&process->GetRunLock())) {
285 frame = exe_ctx.GetFramePtr();
286 if (frame) {
287 sb_line_entry.SetLineEntry(
288 frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
292 return sb_line_entry;
295 uint32_t SBFrame::GetFrameID() const {
296 LLDB_INSTRUMENT_VA(this);
298 uint32_t frame_idx = UINT32_MAX;
300 std::unique_lock<std::recursive_mutex> lock;
301 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
303 StackFrame *frame = exe_ctx.GetFramePtr();
304 if (frame)
305 frame_idx = frame->GetFrameIndex();
307 return frame_idx;
310 lldb::addr_t SBFrame::GetCFA() const {
311 LLDB_INSTRUMENT_VA(this);
313 std::unique_lock<std::recursive_mutex> lock;
314 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
316 StackFrame *frame = exe_ctx.GetFramePtr();
317 if (frame)
318 return frame->GetStackID().GetCallFrameAddress();
319 return LLDB_INVALID_ADDRESS;
322 addr_t SBFrame::GetPC() const {
323 LLDB_INSTRUMENT_VA(this);
325 addr_t addr = LLDB_INVALID_ADDRESS;
326 std::unique_lock<std::recursive_mutex> lock;
327 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
329 StackFrame *frame = nullptr;
330 Target *target = exe_ctx.GetTargetPtr();
331 Process *process = exe_ctx.GetProcessPtr();
332 if (target && process) {
333 Process::StopLocker stop_locker;
334 if (stop_locker.TryLock(&process->GetRunLock())) {
335 frame = exe_ctx.GetFramePtr();
336 if (frame) {
337 addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
338 target, AddressClass::eCode);
343 return addr;
346 bool SBFrame::SetPC(addr_t new_pc) {
347 LLDB_INSTRUMENT_VA(this, new_pc);
349 bool ret_val = false;
350 std::unique_lock<std::recursive_mutex> lock;
351 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
353 Target *target = exe_ctx.GetTargetPtr();
354 Process *process = exe_ctx.GetProcessPtr();
355 if (target && process) {
356 Process::StopLocker stop_locker;
357 if (stop_locker.TryLock(&process->GetRunLock())) {
358 if (StackFrame *frame = exe_ctx.GetFramePtr()) {
359 if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
360 ret_val = reg_ctx_sp->SetPC(new_pc);
366 return ret_val;
369 addr_t SBFrame::GetSP() const {
370 LLDB_INSTRUMENT_VA(this);
372 addr_t addr = LLDB_INVALID_ADDRESS;
373 std::unique_lock<std::recursive_mutex> lock;
374 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
376 Target *target = exe_ctx.GetTargetPtr();
377 Process *process = exe_ctx.GetProcessPtr();
378 if (target && process) {
379 Process::StopLocker stop_locker;
380 if (stop_locker.TryLock(&process->GetRunLock())) {
381 if (StackFrame *frame = exe_ctx.GetFramePtr()) {
382 if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
383 addr = reg_ctx_sp->GetSP();
389 return addr;
392 addr_t SBFrame::GetFP() const {
393 LLDB_INSTRUMENT_VA(this);
395 addr_t addr = LLDB_INVALID_ADDRESS;
396 std::unique_lock<std::recursive_mutex> lock;
397 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
399 Target *target = exe_ctx.GetTargetPtr();
400 Process *process = exe_ctx.GetProcessPtr();
401 if (target && process) {
402 Process::StopLocker stop_locker;
403 if (stop_locker.TryLock(&process->GetRunLock())) {
404 if (StackFrame *frame = exe_ctx.GetFramePtr()) {
405 if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {
406 addr = reg_ctx_sp->GetFP();
412 return addr;
415 SBAddress SBFrame::GetPCAddress() const {
416 LLDB_INSTRUMENT_VA(this);
418 SBAddress sb_addr;
419 std::unique_lock<std::recursive_mutex> lock;
420 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
422 StackFrame *frame = exe_ctx.GetFramePtr();
423 Target *target = exe_ctx.GetTargetPtr();
424 Process *process = exe_ctx.GetProcessPtr();
425 if (target && process) {
426 Process::StopLocker stop_locker;
427 if (stop_locker.TryLock(&process->GetRunLock())) {
428 frame = exe_ctx.GetFramePtr();
429 if (frame)
430 sb_addr.SetAddress(frame->GetFrameCodeAddress());
433 return sb_addr;
436 void SBFrame::Clear() {
437 LLDB_INSTRUMENT_VA(this);
439 m_opaque_sp->Clear();
442 lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {
443 LLDB_INSTRUMENT_VA(this, var_path);
445 SBValue sb_value;
446 std::unique_lock<std::recursive_mutex> lock;
447 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
449 StackFrame *frame = exe_ctx.GetFramePtr();
450 Target *target = exe_ctx.GetTargetPtr();
451 if (frame && target) {
452 lldb::DynamicValueType use_dynamic =
453 frame->CalculateTarget()->GetPreferDynamicValue();
454 sb_value = GetValueForVariablePath(var_path, use_dynamic);
456 return sb_value;
459 lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,
460 DynamicValueType use_dynamic) {
461 LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);
463 SBValue sb_value;
464 if (var_path == nullptr || var_path[0] == '\0') {
465 return sb_value;
468 std::unique_lock<std::recursive_mutex> lock;
469 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
471 StackFrame *frame = nullptr;
472 Target *target = exe_ctx.GetTargetPtr();
473 Process *process = exe_ctx.GetProcessPtr();
474 if (target && process) {
475 Process::StopLocker stop_locker;
476 if (stop_locker.TryLock(&process->GetRunLock())) {
477 frame = exe_ctx.GetFramePtr();
478 if (frame) {
479 VariableSP var_sp;
480 Status error;
481 ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(
482 var_path, eNoDynamicValues,
483 StackFrame::eExpressionPathOptionCheckPtrVsMember |
484 StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
485 var_sp, error));
486 sb_value.SetSP(value_sp, use_dynamic);
490 return sb_value;
493 SBValue SBFrame::FindVariable(const char *name) {
494 LLDB_INSTRUMENT_VA(this, name);
496 SBValue value;
497 std::unique_lock<std::recursive_mutex> lock;
498 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
500 StackFrame *frame = exe_ctx.GetFramePtr();
501 Target *target = exe_ctx.GetTargetPtr();
502 if (frame && target) {
503 lldb::DynamicValueType use_dynamic =
504 frame->CalculateTarget()->GetPreferDynamicValue();
505 value = FindVariable(name, use_dynamic);
507 return value;
510 SBValue SBFrame::FindVariable(const char *name,
511 lldb::DynamicValueType use_dynamic) {
512 LLDB_INSTRUMENT_VA(this, name, use_dynamic);
514 VariableSP var_sp;
515 SBValue sb_value;
517 if (name == nullptr || name[0] == '\0') {
518 return sb_value;
521 ValueObjectSP value_sp;
522 std::unique_lock<std::recursive_mutex> lock;
523 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
525 StackFrame *frame = nullptr;
526 Target *target = exe_ctx.GetTargetPtr();
527 Process *process = exe_ctx.GetProcessPtr();
528 if (target && process) {
529 Process::StopLocker stop_locker;
530 if (stop_locker.TryLock(&process->GetRunLock())) {
531 frame = exe_ctx.GetFramePtr();
532 if (frame) {
533 value_sp = frame->FindVariable(ConstString(name));
535 if (value_sp)
536 sb_value.SetSP(value_sp, use_dynamic);
541 return sb_value;
544 SBValue SBFrame::FindValue(const char *name, ValueType value_type) {
545 LLDB_INSTRUMENT_VA(this, name, value_type);
547 SBValue value;
548 std::unique_lock<std::recursive_mutex> lock;
549 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551 StackFrame *frame = exe_ctx.GetFramePtr();
552 Target *target = exe_ctx.GetTargetPtr();
553 if (frame && target) {
554 lldb::DynamicValueType use_dynamic =
555 frame->CalculateTarget()->GetPreferDynamicValue();
556 value = FindValue(name, value_type, use_dynamic);
558 return value;
561 SBValue SBFrame::FindValue(const char *name, ValueType value_type,
562 lldb::DynamicValueType use_dynamic) {
563 LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);
565 SBValue sb_value;
567 if (name == nullptr || name[0] == '\0') {
568 return sb_value;
571 ValueObjectSP value_sp;
572 std::unique_lock<std::recursive_mutex> lock;
573 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
575 StackFrame *frame = nullptr;
576 Target *target = exe_ctx.GetTargetPtr();
577 Process *process = exe_ctx.GetProcessPtr();
578 if (target && process) {
579 Process::StopLocker stop_locker;
580 if (stop_locker.TryLock(&process->GetRunLock())) {
581 frame = exe_ctx.GetFramePtr();
582 if (frame) {
583 VariableList variable_list;
585 switch (value_type) {
586 case eValueTypeVariableGlobal: // global variable
587 case eValueTypeVariableStatic: // static variable
588 case eValueTypeVariableArgument: // function argument variables
589 case eValueTypeVariableLocal: // function local variables
590 case eValueTypeVariableThreadLocal: // thread local variables
592 SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));
594 const bool can_create = true;
595 const bool get_parent_variables = true;
596 const bool stop_if_block_is_inlined_function = true;
598 if (sc.block)
599 sc.block->AppendVariables(
600 can_create, get_parent_variables,
601 stop_if_block_is_inlined_function,
602 [frame](Variable *v) { return v->IsInScope(frame); },
603 &variable_list);
604 if (value_type == eValueTypeVariableGlobal
605 || value_type == eValueTypeVariableStatic) {
606 const bool get_file_globals = true;
607 VariableList *frame_vars = frame->GetVariableList(get_file_globals,
608 nullptr);
609 if (frame_vars)
610 frame_vars->AppendVariablesIfUnique(variable_list);
612 ConstString const_name(name);
613 VariableSP variable_sp(
614 variable_list.FindVariable(const_name, value_type));
615 if (variable_sp) {
616 value_sp = frame->GetValueObjectForFrameVariable(variable_sp,
617 eNoDynamicValues);
618 sb_value.SetSP(value_sp, use_dynamic);
620 } break;
622 case eValueTypeRegister: // stack frame register value
624 RegisterContextSP reg_ctx(frame->GetRegisterContext());
625 if (reg_ctx) {
626 if (const RegisterInfo *reg_info =
627 reg_ctx->GetRegisterInfoByName(name)) {
628 value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
629 sb_value.SetSP(value_sp);
632 } break;
634 case eValueTypeRegisterSet: // A collection of stack frame register
635 // values
637 RegisterContextSP reg_ctx(frame->GetRegisterContext());
638 if (reg_ctx) {
639 const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
640 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
641 const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);
642 if (reg_set &&
643 (llvm::StringRef(reg_set->name).equals_insensitive(name) ||
644 llvm::StringRef(reg_set->short_name)
645 .equals_insensitive(name))) {
646 value_sp =
647 ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);
648 sb_value.SetSP(value_sp);
649 break;
653 } break;
655 case eValueTypeConstResult: // constant result variables
657 ConstString const_name(name);
658 ExpressionVariableSP expr_var_sp(
659 target->GetPersistentVariable(const_name));
660 if (expr_var_sp) {
661 value_sp = expr_var_sp->GetValueObject();
662 sb_value.SetSP(value_sp, use_dynamic);
664 } break;
666 default:
667 break;
673 return sb_value;
676 bool SBFrame::IsEqual(const SBFrame &that) const {
677 LLDB_INSTRUMENT_VA(this, that);
679 lldb::StackFrameSP this_sp = GetFrameSP();
680 lldb::StackFrameSP that_sp = that.GetFrameSP();
681 return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());
684 bool SBFrame::operator==(const SBFrame &rhs) const {
685 LLDB_INSTRUMENT_VA(this, rhs);
687 return IsEqual(rhs);
690 bool SBFrame::operator!=(const SBFrame &rhs) const {
691 LLDB_INSTRUMENT_VA(this, rhs);
693 return !IsEqual(rhs);
696 SBThread SBFrame::GetThread() const {
697 LLDB_INSTRUMENT_VA(this);
699 std::unique_lock<std::recursive_mutex> lock;
700 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
702 ThreadSP thread_sp(exe_ctx.GetThreadSP());
703 SBThread sb_thread(thread_sp);
705 return sb_thread;
708 const char *SBFrame::Disassemble() const {
709 LLDB_INSTRUMENT_VA(this);
711 std::unique_lock<std::recursive_mutex> lock;
712 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
713 Target *target = exe_ctx.GetTargetPtr();
714 Process *process = exe_ctx.GetProcessPtr();
715 if (!target || !process)
716 return nullptr;
718 Process::StopLocker stop_locker;
719 if (stop_locker.TryLock(&process->GetRunLock())) {
720 if (auto *frame = exe_ctx.GetFramePtr())
721 return ConstString(frame->Disassemble()).GetCString();
724 return nullptr;
727 SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,
728 bool in_scope_only) {
729 LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);
731 SBValueList value_list;
732 std::unique_lock<std::recursive_mutex> lock;
733 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
735 StackFrame *frame = exe_ctx.GetFramePtr();
736 Target *target = exe_ctx.GetTargetPtr();
737 if (frame && target) {
738 lldb::DynamicValueType use_dynamic =
739 frame->CalculateTarget()->GetPreferDynamicValue();
740 const bool include_runtime_support_values =
741 target->GetDisplayRuntimeSupportValues();
743 SBVariablesOptions options;
744 options.SetIncludeArguments(arguments);
745 options.SetIncludeLocals(locals);
746 options.SetIncludeStatics(statics);
747 options.SetInScopeOnly(in_scope_only);
748 options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
749 options.SetUseDynamic(use_dynamic);
751 value_list = GetVariables(options);
753 return value_list;
756 lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,
757 bool statics, bool in_scope_only,
758 lldb::DynamicValueType use_dynamic) {
759 LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,
760 use_dynamic);
762 std::unique_lock<std::recursive_mutex> lock;
763 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
765 Target *target = exe_ctx.GetTargetPtr();
766 const bool include_runtime_support_values =
767 target ? target->GetDisplayRuntimeSupportValues() : false;
768 SBVariablesOptions options;
769 options.SetIncludeArguments(arguments);
770 options.SetIncludeLocals(locals);
771 options.SetIncludeStatics(statics);
772 options.SetInScopeOnly(in_scope_only);
773 options.SetIncludeRuntimeSupportValues(include_runtime_support_values);
774 options.SetUseDynamic(use_dynamic);
775 return GetVariables(options);
778 SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {
779 LLDB_INSTRUMENT_VA(this, options);
781 SBValueList value_list;
782 std::unique_lock<std::recursive_mutex> lock;
783 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
785 StackFrame *frame = nullptr;
786 Target *target = exe_ctx.GetTargetPtr();
788 const bool statics = options.GetIncludeStatics();
789 const bool arguments = options.GetIncludeArguments();
790 const bool recognized_arguments =
791 options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));
792 const bool locals = options.GetIncludeLocals();
793 const bool in_scope_only = options.GetInScopeOnly();
794 const bool include_runtime_support_values =
795 options.GetIncludeRuntimeSupportValues();
796 const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();
799 std::set<VariableSP> variable_set;
800 Process *process = exe_ctx.GetProcessPtr();
801 if (target && process) {
802 Process::StopLocker stop_locker;
803 if (stop_locker.TryLock(&process->GetRunLock())) {
804 frame = exe_ctx.GetFramePtr();
805 if (frame) {
806 Debugger &dbg = process->GetTarget().GetDebugger();
807 VariableList *variable_list = nullptr;
808 Status var_error;
809 variable_list = frame->GetVariableList(true, &var_error);
810 if (var_error.Fail())
811 value_list.SetError(var_error);
812 if (variable_list) {
813 const size_t num_variables = variable_list->GetSize();
814 if (num_variables) {
815 size_t num_produced = 0;
816 for (const VariableSP &variable_sp : *variable_list) {
817 if (INTERRUPT_REQUESTED(dbg,
818 "Interrupted getting frame variables with {0} of {1} "
819 "produced.", num_produced, num_variables))
820 return {};
822 if (variable_sp) {
823 bool add_variable = false;
824 switch (variable_sp->GetScope()) {
825 case eValueTypeVariableGlobal:
826 case eValueTypeVariableStatic:
827 case eValueTypeVariableThreadLocal:
828 add_variable = statics;
829 break;
831 case eValueTypeVariableArgument:
832 add_variable = arguments;
833 break;
835 case eValueTypeVariableLocal:
836 add_variable = locals;
837 break;
839 default:
840 break;
842 if (add_variable) {
843 // Only add variables once so we don't end up with duplicates
844 if (variable_set.find(variable_sp) == variable_set.end())
845 variable_set.insert(variable_sp);
846 else
847 continue;
849 if (in_scope_only && !variable_sp->IsInScope(frame))
850 continue;
852 ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(
853 variable_sp, eNoDynamicValues));
855 if (!include_runtime_support_values && valobj_sp != nullptr &&
856 valobj_sp->IsRuntimeSupportValue())
857 continue;
859 SBValue value_sb;
860 value_sb.SetSP(valobj_sp, use_dynamic);
861 value_list.Append(value_sb);
865 num_produced++;
868 if (recognized_arguments) {
869 auto recognized_frame = frame->GetRecognizedFrame();
870 if (recognized_frame) {
871 ValueObjectListSP recognized_arg_list =
872 recognized_frame->GetRecognizedArguments();
873 if (recognized_arg_list) {
874 for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {
875 SBValue value_sb;
876 value_sb.SetSP(rec_value_sp, use_dynamic);
877 value_list.Append(value_sb);
886 return value_list;
889 SBValueList SBFrame::GetRegisters() {
890 LLDB_INSTRUMENT_VA(this);
892 SBValueList value_list;
893 std::unique_lock<std::recursive_mutex> lock;
894 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
896 StackFrame *frame = nullptr;
897 Target *target = exe_ctx.GetTargetPtr();
898 Process *process = exe_ctx.GetProcessPtr();
899 if (target && process) {
900 Process::StopLocker stop_locker;
901 if (stop_locker.TryLock(&process->GetRunLock())) {
902 frame = exe_ctx.GetFramePtr();
903 if (frame) {
904 RegisterContextSP reg_ctx(frame->GetRegisterContext());
905 if (reg_ctx) {
906 const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
907 for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
908 value_list.Append(
909 ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
916 return value_list;
919 SBValue SBFrame::FindRegister(const char *name) {
920 LLDB_INSTRUMENT_VA(this, name);
922 SBValue result;
923 ValueObjectSP value_sp;
924 std::unique_lock<std::recursive_mutex> lock;
925 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
927 StackFrame *frame = nullptr;
928 Target *target = exe_ctx.GetTargetPtr();
929 Process *process = exe_ctx.GetProcessPtr();
930 if (target && process) {
931 Process::StopLocker stop_locker;
932 if (stop_locker.TryLock(&process->GetRunLock())) {
933 frame = exe_ctx.GetFramePtr();
934 if (frame) {
935 RegisterContextSP reg_ctx(frame->GetRegisterContext());
936 if (reg_ctx) {
937 if (const RegisterInfo *reg_info =
938 reg_ctx->GetRegisterInfoByName(name)) {
939 value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);
940 result.SetSP(value_sp);
947 return result;
950 bool SBFrame::GetDescription(SBStream &description) {
951 LLDB_INSTRUMENT_VA(this, description);
953 Stream &strm = description.ref();
955 std::unique_lock<std::recursive_mutex> lock;
956 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
958 StackFrame *frame;
959 Target *target = exe_ctx.GetTargetPtr();
960 Process *process = exe_ctx.GetProcessPtr();
961 if (target && process) {
962 Process::StopLocker stop_locker;
963 if (stop_locker.TryLock(&process->GetRunLock())) {
964 frame = exe_ctx.GetFramePtr();
965 if (frame) {
966 frame->DumpUsingSettingsFormat(&strm);
970 } else
971 strm.PutCString("No value");
973 return true;
976 SBValue SBFrame::EvaluateExpression(const char *expr) {
977 LLDB_INSTRUMENT_VA(this, expr);
979 SBValue result;
980 std::unique_lock<std::recursive_mutex> lock;
981 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
983 StackFrame *frame = exe_ctx.GetFramePtr();
984 Target *target = exe_ctx.GetTargetPtr();
985 if (frame && target) {
986 SBExpressionOptions options;
987 lldb::DynamicValueType fetch_dynamic_value =
988 frame->CalculateTarget()->GetPreferDynamicValue();
989 options.SetFetchDynamicValue(fetch_dynamic_value);
990 options.SetUnwindOnError(true);
991 options.SetIgnoreBreakpoints(true);
992 if (target->GetLanguage() != eLanguageTypeUnknown)
993 options.SetLanguage(target->GetLanguage());
994 else
995 options.SetLanguage(frame->GetLanguage());
996 return EvaluateExpression(expr, options);
997 } else {
998 Status error;
999 error.SetErrorString("can't evaluate expressions when the "
1000 "process is running.");
1001 ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
1002 result.SetSP(error_val_sp, false);
1004 return result;
1007 SBValue
1008 SBFrame::EvaluateExpression(const char *expr,
1009 lldb::DynamicValueType fetch_dynamic_value) {
1010 LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);
1012 SBExpressionOptions options;
1013 options.SetFetchDynamicValue(fetch_dynamic_value);
1014 options.SetUnwindOnError(true);
1015 options.SetIgnoreBreakpoints(true);
1016 std::unique_lock<std::recursive_mutex> lock;
1017 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1019 StackFrame *frame = exe_ctx.GetFramePtr();
1020 Target *target = exe_ctx.GetTargetPtr();
1021 if (target && target->GetLanguage() != eLanguageTypeUnknown)
1022 options.SetLanguage(target->GetLanguage());
1023 else if (frame)
1024 options.SetLanguage(frame->GetLanguage());
1025 return EvaluateExpression(expr, options);
1028 SBValue SBFrame::EvaluateExpression(const char *expr,
1029 lldb::DynamicValueType fetch_dynamic_value,
1030 bool unwind_on_error) {
1031 LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);
1033 SBExpressionOptions options;
1034 std::unique_lock<std::recursive_mutex> lock;
1035 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1037 options.SetFetchDynamicValue(fetch_dynamic_value);
1038 options.SetUnwindOnError(unwind_on_error);
1039 options.SetIgnoreBreakpoints(true);
1040 StackFrame *frame = exe_ctx.GetFramePtr();
1041 Target *target = exe_ctx.GetTargetPtr();
1042 if (target && target->GetLanguage() != eLanguageTypeUnknown)
1043 options.SetLanguage(target->GetLanguage());
1044 else if (frame)
1045 options.SetLanguage(frame->GetLanguage());
1046 return EvaluateExpression(expr, options);
1049 lldb::SBValue SBFrame::EvaluateExpression(const char *expr,
1050 const SBExpressionOptions &options) {
1051 LLDB_INSTRUMENT_VA(this, expr, options);
1053 Log *expr_log = GetLog(LLDBLog::Expressions);
1055 SBValue expr_result;
1057 if (expr == nullptr || expr[0] == '\0') {
1058 return expr_result;
1061 ValueObjectSP expr_value_sp;
1063 std::unique_lock<std::recursive_mutex> lock;
1064 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1066 StackFrame *frame = nullptr;
1067 Target *target = exe_ctx.GetTargetPtr();
1068 Process *process = exe_ctx.GetProcessPtr();
1070 if (target && process) {
1071 Process::StopLocker stop_locker;
1072 if (stop_locker.TryLock(&process->GetRunLock())) {
1073 frame = exe_ctx.GetFramePtr();
1074 if (frame) {
1075 std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;
1076 if (target->GetDisplayExpressionsInCrashlogs()) {
1077 StreamString frame_description;
1078 frame->DumpUsingSettingsFormat(&frame_description);
1079 stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(
1080 "SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "
1081 "= %u) %s",
1082 expr, options.GetFetchDynamicValue(),
1083 frame_description.GetData());
1086 target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
1087 expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
1089 } else {
1090 Status error;
1091 error.SetErrorString("can't evaluate expressions when the "
1092 "process is running.");
1093 expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1094 expr_result.SetSP(expr_value_sp, false);
1096 } else {
1097 Status error;
1098 error.SetErrorString("sbframe object is not valid.");
1099 expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
1100 expr_result.SetSP(expr_value_sp, false);
1103 if (expr_result.GetError().Success())
1104 LLDB_LOGF(expr_log,
1105 "** [SBFrame::EvaluateExpression] Expression result is "
1106 "%s, summary %s **",
1107 expr_result.GetValue(), expr_result.GetSummary());
1108 else
1109 LLDB_LOGF(expr_log,
1110 "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
1111 "%s **",
1112 expr_result.GetError().GetCString());
1114 return expr_result;
1117 bool SBFrame::IsInlined() {
1118 LLDB_INSTRUMENT_VA(this);
1120 return static_cast<const SBFrame *>(this)->IsInlined();
1123 bool SBFrame::IsInlined() const {
1124 LLDB_INSTRUMENT_VA(this);
1126 std::unique_lock<std::recursive_mutex> lock;
1127 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1129 StackFrame *frame = nullptr;
1130 Target *target = exe_ctx.GetTargetPtr();
1131 Process *process = exe_ctx.GetProcessPtr();
1132 if (target && process) {
1133 Process::StopLocker stop_locker;
1134 if (stop_locker.TryLock(&process->GetRunLock())) {
1135 frame = exe_ctx.GetFramePtr();
1136 if (frame) {
1138 Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;
1139 if (block)
1140 return block->GetContainingInlinedBlock() != nullptr;
1144 return false;
1147 bool SBFrame::IsArtificial() {
1148 LLDB_INSTRUMENT_VA(this);
1150 return static_cast<const SBFrame *>(this)->IsArtificial();
1153 bool SBFrame::IsArtificial() const {
1154 LLDB_INSTRUMENT_VA(this);
1156 std::unique_lock<std::recursive_mutex> lock;
1157 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1159 StackFrame *frame = exe_ctx.GetFramePtr();
1160 if (frame)
1161 return frame->IsArtificial();
1163 return false;
1166 const char *SBFrame::GetFunctionName() {
1167 LLDB_INSTRUMENT_VA(this);
1169 return static_cast<const SBFrame *>(this)->GetFunctionName();
1172 lldb::LanguageType SBFrame::GuessLanguage() const {
1173 LLDB_INSTRUMENT_VA(this);
1175 std::unique_lock<std::recursive_mutex> lock;
1176 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
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(&process->GetRunLock())) {
1184 frame = exe_ctx.GetFramePtr();
1185 if (frame) {
1186 return frame->GuessLanguage();
1190 return eLanguageTypeUnknown;
1193 const char *SBFrame::GetFunctionName() const {
1194 LLDB_INSTRUMENT_VA(this);
1196 const char *name = nullptr;
1197 std::unique_lock<std::recursive_mutex> lock;
1198 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1200 StackFrame *frame = nullptr;
1201 Target *target = exe_ctx.GetTargetPtr();
1202 Process *process = exe_ctx.GetProcessPtr();
1203 if (target && process) {
1204 Process::StopLocker stop_locker;
1205 if (stop_locker.TryLock(&process->GetRunLock())) {
1206 frame = exe_ctx.GetFramePtr();
1207 if (frame) {
1208 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1209 eSymbolContextBlock |
1210 eSymbolContextSymbol));
1211 if (sc.block) {
1212 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1213 if (inlined_block) {
1214 const InlineFunctionInfo *inlined_info =
1215 inlined_block->GetInlinedFunctionInfo();
1216 name = inlined_info->GetName().AsCString();
1220 if (name == nullptr) {
1221 if (sc.function)
1222 name = sc.function->GetName().GetCString();
1225 if (name == nullptr) {
1226 if (sc.symbol)
1227 name = sc.symbol->GetName().GetCString();
1232 return name;
1235 const char *SBFrame::GetDisplayFunctionName() {
1236 LLDB_INSTRUMENT_VA(this);
1238 const char *name = nullptr;
1240 std::unique_lock<std::recursive_mutex> lock;
1241 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1243 StackFrame *frame = nullptr;
1244 Target *target = exe_ctx.GetTargetPtr();
1245 Process *process = exe_ctx.GetProcessPtr();
1246 if (target && process) {
1247 Process::StopLocker stop_locker;
1248 if (stop_locker.TryLock(&process->GetRunLock())) {
1249 frame = exe_ctx.GetFramePtr();
1250 if (frame) {
1251 SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |
1252 eSymbolContextBlock |
1253 eSymbolContextSymbol));
1254 if (sc.block) {
1255 Block *inlined_block = sc.block->GetContainingInlinedBlock();
1256 if (inlined_block) {
1257 const InlineFunctionInfo *inlined_info =
1258 inlined_block->GetInlinedFunctionInfo();
1259 name = inlined_info->GetDisplayName().AsCString();
1263 if (name == nullptr) {
1264 if (sc.function)
1265 name = sc.function->GetDisplayName().GetCString();
1268 if (name == nullptr) {
1269 if (sc.symbol)
1270 name = sc.symbol->GetDisplayName().GetCString();
1275 return name;