Path: blob/main/contrib/llvm-project/lldb/source/API/SBFrame.cpp
39587 views
//===-- SBFrame.cpp -------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include <algorithm>9#include <set>10#include <string>1112#include "lldb/API/SBFrame.h"1314#include "lldb/lldb-types.h"1516#include "Utils.h"17#include "lldb/Core/Address.h"18#include "lldb/Core/Debugger.h"19#include "lldb/Core/ValueObjectRegister.h"20#include "lldb/Core/ValueObjectVariable.h"21#include "lldb/Core/ValueObjectConstResult.h"22#include "lldb/Expression/ExpressionVariable.h"23#include "lldb/Expression/UserExpression.h"24#include "lldb/Host/Host.h"25#include "lldb/Symbol/Block.h"26#include "lldb/Symbol/Function.h"27#include "lldb/Symbol/Symbol.h"28#include "lldb/Symbol/SymbolContext.h"29#include "lldb/Symbol/Variable.h"30#include "lldb/Symbol/VariableList.h"31#include "lldb/Target/ExecutionContext.h"32#include "lldb/Target/Process.h"33#include "lldb/Target/RegisterContext.h"34#include "lldb/Target/StackFrame.h"35#include "lldb/Target/StackFrameRecognizer.h"36#include "lldb/Target/StackID.h"37#include "lldb/Target/Target.h"38#include "lldb/Target/Thread.h"39#include "lldb/Utility/ConstString.h"40#include "lldb/Utility/Instrumentation.h"41#include "lldb/Utility/LLDBLog.h"42#include "lldb/Utility/Stream.h"4344#include "lldb/API/SBAddress.h"45#include "lldb/API/SBDebugger.h"46#include "lldb/API/SBExpressionOptions.h"47#include "lldb/API/SBFormat.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"5354#include "llvm/Support/PrettyStackTrace.h"5556using namespace lldb;57using namespace lldb_private;5859SBFrame::SBFrame() : m_opaque_sp(new ExecutionContextRef()) {60LLDB_INSTRUMENT_VA(this);61}6263SBFrame::SBFrame(const StackFrameSP &lldb_object_sp)64: m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {65LLDB_INSTRUMENT_VA(this, lldb_object_sp);66}6768SBFrame::SBFrame(const SBFrame &rhs) {69LLDB_INSTRUMENT_VA(this, rhs);7071m_opaque_sp = clone(rhs.m_opaque_sp);72}7374SBFrame::~SBFrame() = default;7576const SBFrame &SBFrame::operator=(const SBFrame &rhs) {77LLDB_INSTRUMENT_VA(this, rhs);7879if (this != &rhs)80m_opaque_sp = clone(rhs.m_opaque_sp);81return *this;82}8384StackFrameSP SBFrame::GetFrameSP() const {85return (m_opaque_sp ? m_opaque_sp->GetFrameSP() : StackFrameSP());86}8788void SBFrame::SetFrameSP(const StackFrameSP &lldb_object_sp) {89return m_opaque_sp->SetFrameSP(lldb_object_sp);90}9192bool SBFrame::IsValid() const {93LLDB_INSTRUMENT_VA(this);94return this->operator bool();95}96SBFrame::operator bool() const {97LLDB_INSTRUMENT_VA(this);9899std::unique_lock<std::recursive_mutex> lock;100ExecutionContext exe_ctx(m_opaque_sp.get(), lock);101102Target *target = exe_ctx.GetTargetPtr();103Process *process = exe_ctx.GetProcessPtr();104if (target && process) {105Process::StopLocker stop_locker;106if (stop_locker.TryLock(&process->GetRunLock()))107return GetFrameSP().get() != nullptr;108}109110// Without a target & process we can't have a valid stack frame.111return false;112}113114SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const {115LLDB_INSTRUMENT_VA(this, resolve_scope);116117SBSymbolContext sb_sym_ctx;118std::unique_lock<std::recursive_mutex> lock;119ExecutionContext exe_ctx(m_opaque_sp.get(), lock);120SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);121Target *target = exe_ctx.GetTargetPtr();122Process *process = exe_ctx.GetProcessPtr();123if (target && process) {124Process::StopLocker stop_locker;125if (stop_locker.TryLock(&process->GetRunLock())) {126if (StackFrame *frame = exe_ctx.GetFramePtr())127sb_sym_ctx = frame->GetSymbolContext(scope);128}129}130131return sb_sym_ctx;132}133134SBModule SBFrame::GetModule() const {135LLDB_INSTRUMENT_VA(this);136137SBModule sb_module;138ModuleSP module_sp;139std::unique_lock<std::recursive_mutex> lock;140ExecutionContext exe_ctx(m_opaque_sp.get(), lock);141142StackFrame *frame = nullptr;143Target *target = exe_ctx.GetTargetPtr();144Process *process = exe_ctx.GetProcessPtr();145if (target && process) {146Process::StopLocker stop_locker;147if (stop_locker.TryLock(&process->GetRunLock())) {148frame = exe_ctx.GetFramePtr();149if (frame) {150module_sp = frame->GetSymbolContext(eSymbolContextModule).module_sp;151sb_module.SetSP(module_sp);152}153}154}155156return sb_module;157}158159SBCompileUnit SBFrame::GetCompileUnit() const {160LLDB_INSTRUMENT_VA(this);161162SBCompileUnit sb_comp_unit;163std::unique_lock<std::recursive_mutex> lock;164ExecutionContext exe_ctx(m_opaque_sp.get(), lock);165166StackFrame *frame = nullptr;167Target *target = exe_ctx.GetTargetPtr();168Process *process = exe_ctx.GetProcessPtr();169if (target && process) {170Process::StopLocker stop_locker;171if (stop_locker.TryLock(&process->GetRunLock())) {172frame = exe_ctx.GetFramePtr();173if (frame) {174sb_comp_unit.reset(175frame->GetSymbolContext(eSymbolContextCompUnit).comp_unit);176}177}178}179180return sb_comp_unit;181}182183SBFunction SBFrame::GetFunction() const {184LLDB_INSTRUMENT_VA(this);185186SBFunction sb_function;187std::unique_lock<std::recursive_mutex> lock;188ExecutionContext exe_ctx(m_opaque_sp.get(), lock);189190StackFrame *frame = nullptr;191Target *target = exe_ctx.GetTargetPtr();192Process *process = exe_ctx.GetProcessPtr();193if (target && process) {194Process::StopLocker stop_locker;195if (stop_locker.TryLock(&process->GetRunLock())) {196frame = exe_ctx.GetFramePtr();197if (frame) {198sb_function.reset(199frame->GetSymbolContext(eSymbolContextFunction).function);200}201}202}203204return sb_function;205}206207SBSymbol SBFrame::GetSymbol() const {208LLDB_INSTRUMENT_VA(this);209210SBSymbol sb_symbol;211std::unique_lock<std::recursive_mutex> lock;212ExecutionContext exe_ctx(m_opaque_sp.get(), lock);213214StackFrame *frame = nullptr;215Target *target = exe_ctx.GetTargetPtr();216Process *process = exe_ctx.GetProcessPtr();217if (target && process) {218Process::StopLocker stop_locker;219if (stop_locker.TryLock(&process->GetRunLock())) {220frame = exe_ctx.GetFramePtr();221if (frame) {222sb_symbol.reset(frame->GetSymbolContext(eSymbolContextSymbol).symbol);223}224}225}226227return sb_symbol;228}229230SBBlock SBFrame::GetBlock() const {231LLDB_INSTRUMENT_VA(this);232233SBBlock sb_block;234std::unique_lock<std::recursive_mutex> lock;235ExecutionContext exe_ctx(m_opaque_sp.get(), lock);236237StackFrame *frame = nullptr;238Target *target = exe_ctx.GetTargetPtr();239Process *process = exe_ctx.GetProcessPtr();240if (target && process) {241Process::StopLocker stop_locker;242if (stop_locker.TryLock(&process->GetRunLock())) {243frame = exe_ctx.GetFramePtr();244if (frame)245sb_block.SetPtr(frame->GetSymbolContext(eSymbolContextBlock).block);246}247}248return sb_block;249}250251SBBlock SBFrame::GetFrameBlock() const {252LLDB_INSTRUMENT_VA(this);253254SBBlock sb_block;255std::unique_lock<std::recursive_mutex> lock;256ExecutionContext exe_ctx(m_opaque_sp.get(), lock);257258StackFrame *frame = nullptr;259Target *target = exe_ctx.GetTargetPtr();260Process *process = exe_ctx.GetProcessPtr();261if (target && process) {262Process::StopLocker stop_locker;263if (stop_locker.TryLock(&process->GetRunLock())) {264frame = exe_ctx.GetFramePtr();265if (frame)266sb_block.SetPtr(frame->GetFrameBlock());267}268}269return sb_block;270}271272SBLineEntry SBFrame::GetLineEntry() const {273LLDB_INSTRUMENT_VA(this);274275SBLineEntry sb_line_entry;276std::unique_lock<std::recursive_mutex> lock;277ExecutionContext exe_ctx(m_opaque_sp.get(), lock);278279StackFrame *frame = nullptr;280Target *target = exe_ctx.GetTargetPtr();281Process *process = exe_ctx.GetProcessPtr();282if (target && process) {283Process::StopLocker stop_locker;284if (stop_locker.TryLock(&process->GetRunLock())) {285frame = exe_ctx.GetFramePtr();286if (frame) {287sb_line_entry.SetLineEntry(288frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);289}290}291}292return sb_line_entry;293}294295uint32_t SBFrame::GetFrameID() const {296LLDB_INSTRUMENT_VA(this);297298uint32_t frame_idx = UINT32_MAX;299300std::unique_lock<std::recursive_mutex> lock;301ExecutionContext exe_ctx(m_opaque_sp.get(), lock);302303StackFrame *frame = exe_ctx.GetFramePtr();304if (frame)305frame_idx = frame->GetFrameIndex();306307return frame_idx;308}309310lldb::addr_t SBFrame::GetCFA() const {311LLDB_INSTRUMENT_VA(this);312313std::unique_lock<std::recursive_mutex> lock;314ExecutionContext exe_ctx(m_opaque_sp.get(), lock);315316StackFrame *frame = exe_ctx.GetFramePtr();317if (frame)318return frame->GetStackID().GetCallFrameAddress();319return LLDB_INVALID_ADDRESS;320}321322addr_t SBFrame::GetPC() const {323LLDB_INSTRUMENT_VA(this);324325addr_t addr = LLDB_INVALID_ADDRESS;326std::unique_lock<std::recursive_mutex> lock;327ExecutionContext exe_ctx(m_opaque_sp.get(), lock);328329StackFrame *frame = nullptr;330Target *target = exe_ctx.GetTargetPtr();331Process *process = exe_ctx.GetProcessPtr();332if (target && process) {333Process::StopLocker stop_locker;334if (stop_locker.TryLock(&process->GetRunLock())) {335frame = exe_ctx.GetFramePtr();336if (frame) {337addr = frame->GetFrameCodeAddress().GetOpcodeLoadAddress(338target, AddressClass::eCode);339}340}341}342343return addr;344}345346bool SBFrame::SetPC(addr_t new_pc) {347LLDB_INSTRUMENT_VA(this, new_pc);348349bool ret_val = false;350std::unique_lock<std::recursive_mutex> lock;351ExecutionContext exe_ctx(m_opaque_sp.get(), lock);352353Target *target = exe_ctx.GetTargetPtr();354Process *process = exe_ctx.GetProcessPtr();355if (target && process) {356Process::StopLocker stop_locker;357if (stop_locker.TryLock(&process->GetRunLock())) {358if (StackFrame *frame = exe_ctx.GetFramePtr()) {359if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {360ret_val = reg_ctx_sp->SetPC(new_pc);361}362}363}364}365366return ret_val;367}368369addr_t SBFrame::GetSP() const {370LLDB_INSTRUMENT_VA(this);371372addr_t addr = LLDB_INVALID_ADDRESS;373std::unique_lock<std::recursive_mutex> lock;374ExecutionContext exe_ctx(m_opaque_sp.get(), lock);375376Target *target = exe_ctx.GetTargetPtr();377Process *process = exe_ctx.GetProcessPtr();378if (target && process) {379Process::StopLocker stop_locker;380if (stop_locker.TryLock(&process->GetRunLock())) {381if (StackFrame *frame = exe_ctx.GetFramePtr()) {382if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {383addr = reg_ctx_sp->GetSP();384}385}386}387}388389return addr;390}391392addr_t SBFrame::GetFP() const {393LLDB_INSTRUMENT_VA(this);394395addr_t addr = LLDB_INVALID_ADDRESS;396std::unique_lock<std::recursive_mutex> lock;397ExecutionContext exe_ctx(m_opaque_sp.get(), lock);398399Target *target = exe_ctx.GetTargetPtr();400Process *process = exe_ctx.GetProcessPtr();401if (target && process) {402Process::StopLocker stop_locker;403if (stop_locker.TryLock(&process->GetRunLock())) {404if (StackFrame *frame = exe_ctx.GetFramePtr()) {405if (RegisterContextSP reg_ctx_sp = frame->GetRegisterContext()) {406addr = reg_ctx_sp->GetFP();407}408}409}410}411412return addr;413}414415SBAddress SBFrame::GetPCAddress() const {416LLDB_INSTRUMENT_VA(this);417418SBAddress sb_addr;419std::unique_lock<std::recursive_mutex> lock;420ExecutionContext exe_ctx(m_opaque_sp.get(), lock);421422StackFrame *frame = exe_ctx.GetFramePtr();423Target *target = exe_ctx.GetTargetPtr();424Process *process = exe_ctx.GetProcessPtr();425if (target && process) {426Process::StopLocker stop_locker;427if (stop_locker.TryLock(&process->GetRunLock())) {428frame = exe_ctx.GetFramePtr();429if (frame)430sb_addr.SetAddress(frame->GetFrameCodeAddress());431}432}433return sb_addr;434}435436void SBFrame::Clear() {437LLDB_INSTRUMENT_VA(this);438439m_opaque_sp->Clear();440}441442lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path) {443LLDB_INSTRUMENT_VA(this, var_path);444445SBValue sb_value;446std::unique_lock<std::recursive_mutex> lock;447ExecutionContext exe_ctx(m_opaque_sp.get(), lock);448449StackFrame *frame = exe_ctx.GetFramePtr();450Target *target = exe_ctx.GetTargetPtr();451if (frame && target) {452lldb::DynamicValueType use_dynamic =453frame->CalculateTarget()->GetPreferDynamicValue();454sb_value = GetValueForVariablePath(var_path, use_dynamic);455}456return sb_value;457}458459lldb::SBValue SBFrame::GetValueForVariablePath(const char *var_path,460DynamicValueType use_dynamic) {461LLDB_INSTRUMENT_VA(this, var_path, use_dynamic);462463SBValue sb_value;464if (var_path == nullptr || var_path[0] == '\0') {465return sb_value;466}467468std::unique_lock<std::recursive_mutex> lock;469ExecutionContext exe_ctx(m_opaque_sp.get(), lock);470471StackFrame *frame = nullptr;472Target *target = exe_ctx.GetTargetPtr();473Process *process = exe_ctx.GetProcessPtr();474if (target && process) {475Process::StopLocker stop_locker;476if (stop_locker.TryLock(&process->GetRunLock())) {477frame = exe_ctx.GetFramePtr();478if (frame) {479VariableSP var_sp;480Status error;481ValueObjectSP value_sp(frame->GetValueForVariableExpressionPath(482var_path, eNoDynamicValues,483StackFrame::eExpressionPathOptionCheckPtrVsMember |484StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,485var_sp, error));486sb_value.SetSP(value_sp, use_dynamic);487}488}489}490return sb_value;491}492493SBValue SBFrame::FindVariable(const char *name) {494LLDB_INSTRUMENT_VA(this, name);495496SBValue value;497std::unique_lock<std::recursive_mutex> lock;498ExecutionContext exe_ctx(m_opaque_sp.get(), lock);499500StackFrame *frame = exe_ctx.GetFramePtr();501Target *target = exe_ctx.GetTargetPtr();502if (frame && target) {503lldb::DynamicValueType use_dynamic =504frame->CalculateTarget()->GetPreferDynamicValue();505value = FindVariable(name, use_dynamic);506}507return value;508}509510SBValue SBFrame::FindVariable(const char *name,511lldb::DynamicValueType use_dynamic) {512LLDB_INSTRUMENT_VA(this, name, use_dynamic);513514VariableSP var_sp;515SBValue sb_value;516517if (name == nullptr || name[0] == '\0') {518return sb_value;519}520521ValueObjectSP value_sp;522std::unique_lock<std::recursive_mutex> lock;523ExecutionContext exe_ctx(m_opaque_sp.get(), lock);524525StackFrame *frame = nullptr;526Target *target = exe_ctx.GetTargetPtr();527Process *process = exe_ctx.GetProcessPtr();528if (target && process) {529Process::StopLocker stop_locker;530if (stop_locker.TryLock(&process->GetRunLock())) {531frame = exe_ctx.GetFramePtr();532if (frame) {533value_sp = frame->FindVariable(ConstString(name));534535if (value_sp)536sb_value.SetSP(value_sp, use_dynamic);537}538}539}540541return sb_value;542}543544SBValue SBFrame::FindValue(const char *name, ValueType value_type) {545LLDB_INSTRUMENT_VA(this, name, value_type);546547SBValue value;548std::unique_lock<std::recursive_mutex> lock;549ExecutionContext exe_ctx(m_opaque_sp.get(), lock);550551StackFrame *frame = exe_ctx.GetFramePtr();552Target *target = exe_ctx.GetTargetPtr();553if (frame && target) {554lldb::DynamicValueType use_dynamic =555frame->CalculateTarget()->GetPreferDynamicValue();556value = FindValue(name, value_type, use_dynamic);557}558return value;559}560561SBValue SBFrame::FindValue(const char *name, ValueType value_type,562lldb::DynamicValueType use_dynamic) {563LLDB_INSTRUMENT_VA(this, name, value_type, use_dynamic);564565SBValue sb_value;566567if (name == nullptr || name[0] == '\0') {568return sb_value;569}570571ValueObjectSP value_sp;572std::unique_lock<std::recursive_mutex> lock;573ExecutionContext exe_ctx(m_opaque_sp.get(), lock);574575StackFrame *frame = nullptr;576Target *target = exe_ctx.GetTargetPtr();577Process *process = exe_ctx.GetProcessPtr();578if (target && process) {579Process::StopLocker stop_locker;580if (stop_locker.TryLock(&process->GetRunLock())) {581frame = exe_ctx.GetFramePtr();582if (frame) {583VariableList variable_list;584585switch (value_type) {586case eValueTypeVariableGlobal: // global variable587case eValueTypeVariableStatic: // static variable588case eValueTypeVariableArgument: // function argument variables589case eValueTypeVariableLocal: // function local variables590case eValueTypeVariableThreadLocal: // thread local variables591{592SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock));593594const bool can_create = true;595const bool get_parent_variables = true;596const bool stop_if_block_is_inlined_function = true;597598if (sc.block)599sc.block->AppendVariables(600can_create, get_parent_variables,601stop_if_block_is_inlined_function,602[frame](Variable *v) { return v->IsInScope(frame); },603&variable_list);604if (value_type == eValueTypeVariableGlobal605|| value_type == eValueTypeVariableStatic) {606const bool get_file_globals = true;607VariableList *frame_vars = frame->GetVariableList(get_file_globals,608nullptr);609if (frame_vars)610frame_vars->AppendVariablesIfUnique(variable_list);611}612ConstString const_name(name);613VariableSP variable_sp(614variable_list.FindVariable(const_name, value_type));615if (variable_sp) {616value_sp = frame->GetValueObjectForFrameVariable(variable_sp,617eNoDynamicValues);618sb_value.SetSP(value_sp, use_dynamic);619}620} break;621622case eValueTypeRegister: // stack frame register value623{624RegisterContextSP reg_ctx(frame->GetRegisterContext());625if (reg_ctx) {626if (const RegisterInfo *reg_info =627reg_ctx->GetRegisterInfoByName(name)) {628value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);629sb_value.SetSP(value_sp);630}631}632} break;633634case eValueTypeRegisterSet: // A collection of stack frame register635// values636{637RegisterContextSP reg_ctx(frame->GetRegisterContext());638if (reg_ctx) {639const uint32_t num_sets = reg_ctx->GetRegisterSetCount();640for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {641const RegisterSet *reg_set = reg_ctx->GetRegisterSet(set_idx);642if (reg_set &&643(llvm::StringRef(reg_set->name).equals_insensitive(name) ||644llvm::StringRef(reg_set->short_name)645.equals_insensitive(name))) {646value_sp =647ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx);648sb_value.SetSP(value_sp);649break;650}651}652}653} break;654655case eValueTypeConstResult: // constant result variables656{657ConstString const_name(name);658ExpressionVariableSP expr_var_sp(659target->GetPersistentVariable(const_name));660if (expr_var_sp) {661value_sp = expr_var_sp->GetValueObject();662sb_value.SetSP(value_sp, use_dynamic);663}664} break;665666default:667break;668}669}670}671}672673return sb_value;674}675676bool SBFrame::IsEqual(const SBFrame &that) const {677LLDB_INSTRUMENT_VA(this, that);678679lldb::StackFrameSP this_sp = GetFrameSP();680lldb::StackFrameSP that_sp = that.GetFrameSP();681return (this_sp && that_sp && this_sp->GetStackID() == that_sp->GetStackID());682}683684bool SBFrame::operator==(const SBFrame &rhs) const {685LLDB_INSTRUMENT_VA(this, rhs);686687return IsEqual(rhs);688}689690bool SBFrame::operator!=(const SBFrame &rhs) const {691LLDB_INSTRUMENT_VA(this, rhs);692693return !IsEqual(rhs);694}695696SBThread SBFrame::GetThread() const {697LLDB_INSTRUMENT_VA(this);698699std::unique_lock<std::recursive_mutex> lock;700ExecutionContext exe_ctx(m_opaque_sp.get(), lock);701702ThreadSP thread_sp(exe_ctx.GetThreadSP());703SBThread sb_thread(thread_sp);704705return sb_thread;706}707708const char *SBFrame::Disassemble() const {709LLDB_INSTRUMENT_VA(this);710711std::unique_lock<std::recursive_mutex> lock;712ExecutionContext exe_ctx(m_opaque_sp.get(), lock);713Target *target = exe_ctx.GetTargetPtr();714Process *process = exe_ctx.GetProcessPtr();715if (!target || !process)716return nullptr;717718Process::StopLocker stop_locker;719if (stop_locker.TryLock(&process->GetRunLock())) {720if (auto *frame = exe_ctx.GetFramePtr())721return ConstString(frame->Disassemble()).GetCString();722}723724return nullptr;725}726727SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics,728bool in_scope_only) {729LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only);730731SBValueList value_list;732std::unique_lock<std::recursive_mutex> lock;733ExecutionContext exe_ctx(m_opaque_sp.get(), lock);734735StackFrame *frame = exe_ctx.GetFramePtr();736Target *target = exe_ctx.GetTargetPtr();737if (frame && target) {738lldb::DynamicValueType use_dynamic =739frame->CalculateTarget()->GetPreferDynamicValue();740const bool include_runtime_support_values =741target->GetDisplayRuntimeSupportValues();742743SBVariablesOptions options;744options.SetIncludeArguments(arguments);745options.SetIncludeLocals(locals);746options.SetIncludeStatics(statics);747options.SetInScopeOnly(in_scope_only);748options.SetIncludeRuntimeSupportValues(include_runtime_support_values);749options.SetUseDynamic(use_dynamic);750751value_list = GetVariables(options);752}753return value_list;754}755756lldb::SBValueList SBFrame::GetVariables(bool arguments, bool locals,757bool statics, bool in_scope_only,758lldb::DynamicValueType use_dynamic) {759LLDB_INSTRUMENT_VA(this, arguments, locals, statics, in_scope_only,760use_dynamic);761762std::unique_lock<std::recursive_mutex> lock;763ExecutionContext exe_ctx(m_opaque_sp.get(), lock);764765Target *target = exe_ctx.GetTargetPtr();766const bool include_runtime_support_values =767target ? target->GetDisplayRuntimeSupportValues() : false;768SBVariablesOptions options;769options.SetIncludeArguments(arguments);770options.SetIncludeLocals(locals);771options.SetIncludeStatics(statics);772options.SetInScopeOnly(in_scope_only);773options.SetIncludeRuntimeSupportValues(include_runtime_support_values);774options.SetUseDynamic(use_dynamic);775return GetVariables(options);776}777778SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) {779LLDB_INSTRUMENT_VA(this, options);780781SBValueList value_list;782std::unique_lock<std::recursive_mutex> lock;783ExecutionContext exe_ctx(m_opaque_sp.get(), lock);784785StackFrame *frame = nullptr;786Target *target = exe_ctx.GetTargetPtr();787788const bool statics = options.GetIncludeStatics();789const bool arguments = options.GetIncludeArguments();790const bool recognized_arguments =791options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP()));792const bool locals = options.GetIncludeLocals();793const bool in_scope_only = options.GetInScopeOnly();794const bool include_runtime_support_values =795options.GetIncludeRuntimeSupportValues();796const lldb::DynamicValueType use_dynamic = options.GetUseDynamic();797798799std::set<VariableSP> variable_set;800Process *process = exe_ctx.GetProcessPtr();801if (target && process) {802Process::StopLocker stop_locker;803if (stop_locker.TryLock(&process->GetRunLock())) {804frame = exe_ctx.GetFramePtr();805if (frame) {806Debugger &dbg = process->GetTarget().GetDebugger();807VariableList *variable_list = nullptr;808Status var_error;809variable_list = frame->GetVariableList(true, &var_error);810if (var_error.Fail())811value_list.SetError(var_error);812if (variable_list) {813const size_t num_variables = variable_list->GetSize();814if (num_variables) {815size_t num_produced = 0;816for (const VariableSP &variable_sp : *variable_list) {817if (INTERRUPT_REQUESTED(dbg,818"Interrupted getting frame variables with {0} of {1} "819"produced.", num_produced, num_variables))820return {};821822if (variable_sp) {823bool add_variable = false;824switch (variable_sp->GetScope()) {825case eValueTypeVariableGlobal:826case eValueTypeVariableStatic:827case eValueTypeVariableThreadLocal:828add_variable = statics;829break;830831case eValueTypeVariableArgument:832add_variable = arguments;833break;834835case eValueTypeVariableLocal:836add_variable = locals;837break;838839default:840break;841}842if (add_variable) {843// Only add variables once so we don't end up with duplicates844if (variable_set.find(variable_sp) == variable_set.end())845variable_set.insert(variable_sp);846else847continue;848849if (in_scope_only && !variable_sp->IsInScope(frame))850continue;851852ValueObjectSP valobj_sp(frame->GetValueObjectForFrameVariable(853variable_sp, eNoDynamicValues));854855if (!include_runtime_support_values && valobj_sp != nullptr &&856valobj_sp->IsRuntimeSupportValue())857continue;858859SBValue value_sb;860value_sb.SetSP(valobj_sp, use_dynamic);861value_list.Append(value_sb);862}863}864}865num_produced++;866}867}868if (recognized_arguments) {869auto recognized_frame = frame->GetRecognizedFrame();870if (recognized_frame) {871ValueObjectListSP recognized_arg_list =872recognized_frame->GetRecognizedArguments();873if (recognized_arg_list) {874for (auto &rec_value_sp : recognized_arg_list->GetObjects()) {875SBValue value_sb;876value_sb.SetSP(rec_value_sp, use_dynamic);877value_list.Append(value_sb);878}879}880}881}882}883}884}885886return value_list;887}888889SBValueList SBFrame::GetRegisters() {890LLDB_INSTRUMENT_VA(this);891892SBValueList value_list;893std::unique_lock<std::recursive_mutex> lock;894ExecutionContext exe_ctx(m_opaque_sp.get(), lock);895896StackFrame *frame = nullptr;897Target *target = exe_ctx.GetTargetPtr();898Process *process = exe_ctx.GetProcessPtr();899if (target && process) {900Process::StopLocker stop_locker;901if (stop_locker.TryLock(&process->GetRunLock())) {902frame = exe_ctx.GetFramePtr();903if (frame) {904RegisterContextSP reg_ctx(frame->GetRegisterContext());905if (reg_ctx) {906const uint32_t num_sets = reg_ctx->GetRegisterSetCount();907for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {908value_list.Append(909ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));910}911}912}913}914}915916return value_list;917}918919SBValue SBFrame::FindRegister(const char *name) {920LLDB_INSTRUMENT_VA(this, name);921922SBValue result;923ValueObjectSP value_sp;924std::unique_lock<std::recursive_mutex> lock;925ExecutionContext exe_ctx(m_opaque_sp.get(), lock);926927StackFrame *frame = nullptr;928Target *target = exe_ctx.GetTargetPtr();929Process *process = exe_ctx.GetProcessPtr();930if (target && process) {931Process::StopLocker stop_locker;932if (stop_locker.TryLock(&process->GetRunLock())) {933frame = exe_ctx.GetFramePtr();934if (frame) {935RegisterContextSP reg_ctx(frame->GetRegisterContext());936if (reg_ctx) {937if (const RegisterInfo *reg_info =938reg_ctx->GetRegisterInfoByName(name)) {939value_sp = ValueObjectRegister::Create(frame, reg_ctx, reg_info);940result.SetSP(value_sp);941}942}943}944}945}946947return result;948}949950SBError SBFrame::GetDescriptionWithFormat(const SBFormat &format,951SBStream &output) {952Stream &strm = output.ref();953954std::unique_lock<std::recursive_mutex> lock;955ExecutionContext exe_ctx(m_opaque_sp.get(), lock);956957StackFrame *frame = nullptr;958Target *target = exe_ctx.GetTargetPtr();959Process *process = exe_ctx.GetProcessPtr();960SBError error;961962if (!format) {963error.SetErrorString("The provided SBFormat object is invalid");964return error;965}966967if (target && process) {968Process::StopLocker stop_locker;969if (stop_locker.TryLock(&process->GetRunLock())) {970frame = exe_ctx.GetFramePtr();971if (frame &&972frame->DumpUsingFormat(strm, format.GetFormatEntrySP().get())) {973return error;974}975}976}977error.SetErrorStringWithFormat(978"It was not possible to generate a frame "979"description with the given format string '%s'",980format.GetFormatEntrySP()->string.c_str());981return error;982}983984bool SBFrame::GetDescription(SBStream &description) {985LLDB_INSTRUMENT_VA(this, description);986987Stream &strm = description.ref();988989std::unique_lock<std::recursive_mutex> lock;990ExecutionContext exe_ctx(m_opaque_sp.get(), lock);991992StackFrame *frame;993Target *target = exe_ctx.GetTargetPtr();994Process *process = exe_ctx.GetProcessPtr();995if (target && process) {996Process::StopLocker stop_locker;997if (stop_locker.TryLock(&process->GetRunLock())) {998frame = exe_ctx.GetFramePtr();999if (frame) {1000frame->DumpUsingSettingsFormat(&strm);1001}1002}10031004} else1005strm.PutCString("No value");10061007return true;1008}10091010SBValue SBFrame::EvaluateExpression(const char *expr) {1011LLDB_INSTRUMENT_VA(this, expr);10121013SBValue result;1014std::unique_lock<std::recursive_mutex> lock;1015ExecutionContext exe_ctx(m_opaque_sp.get(), lock);10161017StackFrame *frame = exe_ctx.GetFramePtr();1018Target *target = exe_ctx.GetTargetPtr();1019if (frame && target) {1020SBExpressionOptions options;1021lldb::DynamicValueType fetch_dynamic_value =1022frame->CalculateTarget()->GetPreferDynamicValue();1023options.SetFetchDynamicValue(fetch_dynamic_value);1024options.SetUnwindOnError(true);1025options.SetIgnoreBreakpoints(true);1026SourceLanguage language = target->GetLanguage();1027if (!language)1028language = frame->GetLanguage();1029options.SetLanguage((SBSourceLanguageName)language.name, language.version);1030return EvaluateExpression(expr, options);1031} else {1032Status error;1033error.SetErrorString("can't evaluate expressions when the "1034"process is running.");1035ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);1036result.SetSP(error_val_sp, false);1037}1038return result;1039}10401041SBValue1042SBFrame::EvaluateExpression(const char *expr,1043lldb::DynamicValueType fetch_dynamic_value) {1044LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value);10451046SBExpressionOptions options;1047options.SetFetchDynamicValue(fetch_dynamic_value);1048options.SetUnwindOnError(true);1049options.SetIgnoreBreakpoints(true);1050std::unique_lock<std::recursive_mutex> lock;1051ExecutionContext exe_ctx(m_opaque_sp.get(), lock);10521053StackFrame *frame = exe_ctx.GetFramePtr();1054Target *target = exe_ctx.GetTargetPtr();1055SourceLanguage language;1056if (target)1057language = target->GetLanguage();1058if (!language && frame)1059language = frame->GetLanguage();1060options.SetLanguage((SBSourceLanguageName)language.name, language.version);1061return EvaluateExpression(expr, options);1062}10631064SBValue SBFrame::EvaluateExpression(const char *expr,1065lldb::DynamicValueType fetch_dynamic_value,1066bool unwind_on_error) {1067LLDB_INSTRUMENT_VA(this, expr, fetch_dynamic_value, unwind_on_error);10681069SBExpressionOptions options;1070std::unique_lock<std::recursive_mutex> lock;1071ExecutionContext exe_ctx(m_opaque_sp.get(), lock);10721073options.SetFetchDynamicValue(fetch_dynamic_value);1074options.SetUnwindOnError(unwind_on_error);1075options.SetIgnoreBreakpoints(true);1076StackFrame *frame = exe_ctx.GetFramePtr();1077Target *target = exe_ctx.GetTargetPtr();1078SourceLanguage language;1079if (target)1080language = target->GetLanguage();1081if (!language && frame)1082language = frame->GetLanguage();1083options.SetLanguage((SBSourceLanguageName)language.name, language.version);1084return EvaluateExpression(expr, options);1085}10861087lldb::SBValue SBFrame::EvaluateExpression(const char *expr,1088const SBExpressionOptions &options) {1089LLDB_INSTRUMENT_VA(this, expr, options);10901091Log *expr_log = GetLog(LLDBLog::Expressions);10921093SBValue expr_result;10941095if (expr == nullptr || expr[0] == '\0') {1096return expr_result;1097}10981099ValueObjectSP expr_value_sp;11001101std::unique_lock<std::recursive_mutex> lock;1102ExecutionContext exe_ctx(m_opaque_sp.get(), lock);11031104StackFrame *frame = nullptr;1105Target *target = exe_ctx.GetTargetPtr();1106Process *process = exe_ctx.GetProcessPtr();11071108if (target && process) {1109Process::StopLocker stop_locker;1110if (stop_locker.TryLock(&process->GetRunLock())) {1111frame = exe_ctx.GetFramePtr();1112if (frame) {1113std::unique_ptr<llvm::PrettyStackTraceFormat> stack_trace;1114if (target->GetDisplayExpressionsInCrashlogs()) {1115StreamString frame_description;1116frame->DumpUsingSettingsFormat(&frame_description);1117stack_trace = std::make_unique<llvm::PrettyStackTraceFormat>(1118"SBFrame::EvaluateExpression (expr = \"%s\", fetch_dynamic_value "1119"= %u) %s",1120expr, options.GetFetchDynamicValue(),1121frame_description.GetData());1122}11231124target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());1125expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());1126}1127} else {1128Status error;1129error.SetErrorString("can't evaluate expressions when the "1130"process is running.");1131expr_value_sp = ValueObjectConstResult::Create(nullptr, error);1132expr_result.SetSP(expr_value_sp, false);1133}1134} else {1135Status error;1136error.SetErrorString("sbframe object is not valid.");1137expr_value_sp = ValueObjectConstResult::Create(nullptr, error);1138expr_result.SetSP(expr_value_sp, false);1139}11401141if (expr_result.GetError().Success())1142LLDB_LOGF(expr_log,1143"** [SBFrame::EvaluateExpression] Expression result is "1144"%s, summary %s **",1145expr_result.GetValue(), expr_result.GetSummary());1146else1147LLDB_LOGF(expr_log,1148"** [SBFrame::EvaluateExpression] Expression evaluation failed: "1149"%s **",1150expr_result.GetError().GetCString());11511152return expr_result;1153}11541155bool SBFrame::IsInlined() {1156LLDB_INSTRUMENT_VA(this);11571158return static_cast<const SBFrame *>(this)->IsInlined();1159}11601161bool SBFrame::IsInlined() const {1162LLDB_INSTRUMENT_VA(this);11631164std::unique_lock<std::recursive_mutex> lock;1165ExecutionContext exe_ctx(m_opaque_sp.get(), lock);11661167StackFrame *frame = nullptr;1168Target *target = exe_ctx.GetTargetPtr();1169Process *process = exe_ctx.GetProcessPtr();1170if (target && process) {1171Process::StopLocker stop_locker;1172if (stop_locker.TryLock(&process->GetRunLock())) {1173frame = exe_ctx.GetFramePtr();1174if (frame) {11751176Block *block = frame->GetSymbolContext(eSymbolContextBlock).block;1177if (block)1178return block->GetContainingInlinedBlock() != nullptr;1179}1180}1181}1182return false;1183}11841185bool SBFrame::IsArtificial() {1186LLDB_INSTRUMENT_VA(this);11871188return static_cast<const SBFrame *>(this)->IsArtificial();1189}11901191bool SBFrame::IsArtificial() const {1192LLDB_INSTRUMENT_VA(this);11931194std::unique_lock<std::recursive_mutex> lock;1195ExecutionContext exe_ctx(m_opaque_sp.get(), lock);11961197StackFrame *frame = exe_ctx.GetFramePtr();1198if (frame)1199return frame->IsArtificial();12001201return false;1202}12031204const char *SBFrame::GetFunctionName() {1205LLDB_INSTRUMENT_VA(this);12061207return static_cast<const SBFrame *>(this)->GetFunctionName();1208}12091210lldb::LanguageType SBFrame::GuessLanguage() const {1211LLDB_INSTRUMENT_VA(this);12121213std::unique_lock<std::recursive_mutex> lock;1214ExecutionContext exe_ctx(m_opaque_sp.get(), lock);12151216StackFrame *frame = nullptr;1217Target *target = exe_ctx.GetTargetPtr();1218Process *process = exe_ctx.GetProcessPtr();1219if (target && process) {1220Process::StopLocker stop_locker;1221if (stop_locker.TryLock(&process->GetRunLock())) {1222frame = exe_ctx.GetFramePtr();1223if (frame) {1224return frame->GuessLanguage().AsLanguageType();1225}1226}1227}1228return eLanguageTypeUnknown;1229}12301231const char *SBFrame::GetFunctionName() const {1232LLDB_INSTRUMENT_VA(this);12331234const char *name = nullptr;1235std::unique_lock<std::recursive_mutex> lock;1236ExecutionContext exe_ctx(m_opaque_sp.get(), lock);12371238StackFrame *frame = nullptr;1239Target *target = exe_ctx.GetTargetPtr();1240Process *process = exe_ctx.GetProcessPtr();1241if (target && process) {1242Process::StopLocker stop_locker;1243if (stop_locker.TryLock(&process->GetRunLock())) {1244frame = exe_ctx.GetFramePtr();1245if (frame) {1246SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |1247eSymbolContextBlock |1248eSymbolContextSymbol));1249if (sc.block) {1250Block *inlined_block = sc.block->GetContainingInlinedBlock();1251if (inlined_block) {1252const InlineFunctionInfo *inlined_info =1253inlined_block->GetInlinedFunctionInfo();1254name = inlined_info->GetName().AsCString();1255}1256}12571258if (name == nullptr) {1259if (sc.function)1260name = sc.function->GetName().GetCString();1261}12621263if (name == nullptr) {1264if (sc.symbol)1265name = sc.symbol->GetName().GetCString();1266}1267}1268}1269}1270return name;1271}12721273const char *SBFrame::GetDisplayFunctionName() {1274LLDB_INSTRUMENT_VA(this);12751276const char *name = nullptr;12771278std::unique_lock<std::recursive_mutex> lock;1279ExecutionContext exe_ctx(m_opaque_sp.get(), lock);12801281StackFrame *frame = nullptr;1282Target *target = exe_ctx.GetTargetPtr();1283Process *process = exe_ctx.GetProcessPtr();1284if (target && process) {1285Process::StopLocker stop_locker;1286if (stop_locker.TryLock(&process->GetRunLock())) {1287frame = exe_ctx.GetFramePtr();1288if (frame) {1289SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction |1290eSymbolContextBlock |1291eSymbolContextSymbol));1292if (sc.block) {1293Block *inlined_block = sc.block->GetContainingInlinedBlock();1294if (inlined_block) {1295const InlineFunctionInfo *inlined_info =1296inlined_block->GetInlinedFunctionInfo();1297name = inlined_info->GetDisplayName().AsCString();1298}1299}13001301if (name == nullptr) {1302if (sc.function)1303name = sc.function->GetDisplayName().GetCString();1304}13051306if (name == nullptr) {1307if (sc.symbol)1308name = sc.symbol->GetDisplayName().GetCString();1309}1310}1311}1312}1313return name;1314}131513161317