47#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextLastItem) << 1)
48#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_CODE_ADDR << 1)
49#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1)
50#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1)
51#define RESOLVED_GLOBAL_VARIABLES (RESOLVED_VARIABLES << 1)
56 bool behaves_like_zeroth_frame,
58 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
59 m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(),
60 m_id(
pc, cfa, nullptr), m_frame_code_addr(
pc), m_sc(), m_flags(),
61 m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid),
62 m_stack_frame_kind(kind),
63 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
64 m_variable_list_sp(), m_variable_list_value_objects(),
65 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
73 if (sc_ptr !=
nullptr) {
82 addr_t pc,
bool behaves_like_zeroth_frame,
84 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
85 m_concrete_frame_index(unwind_frame_index),
86 m_reg_context_sp(reg_context_sp), m_id(
pc, cfa, nullptr),
87 m_frame_code_addr(
pc), m_sc(), m_flags(), m_frame_base(),
88 m_frame_base_error(), m_cfa_is_valid(true),
90 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
91 m_variable_list_sp(), m_variable_list_value_objects(),
92 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
93 if (sc_ptr !=
nullptr) {
108 const Address &pc_addr,
bool behaves_like_zeroth_frame,
110 : m_thread_wp(thread_sp), m_frame_index(frame_idx),
111 m_concrete_frame_index(unwind_frame_index),
112 m_reg_context_sp(reg_context_sp),
113 m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa,
115 m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(),
116 m_frame_base_error(), m_cfa_is_valid(true),
118 m_behaves_like_zeroth_frame(behaves_like_zeroth_frame),
119 m_variable_list_sp(), m_variable_list_value_objects(),
120 m_recognized_frame_sp(), m_disassembly(), m_mutex() {
121 if (sc_ptr !=
nullptr) {
146 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
159 if (scope ==
nullptr) {
178 return thread_sp->GetStackFrameList()->GetVisibleStackFrameIndex(
185 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
191 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
200 TargetSP target_sp(thread_sp->CalculateTarget());
202 const bool allow_section_end =
true;
248 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
257 thread_sp->ClearStackFrames();
262 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
301 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
303 if ((
m_flags.
Get() & resolve_scope) != resolve_scope) {
304 uint32_t resolved = 0;
310 resolved |= eSymbolContextTarget;
329 SymbolContextItem actual_resolve_scope = SymbolContextItem(0);
331 if (resolve_scope & eSymbolContextCompUnit) {
334 resolved |= eSymbolContextCompUnit;
336 actual_resolve_scope |= eSymbolContextCompUnit;
340 if (resolve_scope & eSymbolContextFunction) {
343 resolved |= eSymbolContextFunction;
345 actual_resolve_scope |= eSymbolContextFunction;
349 if (resolve_scope & eSymbolContextBlock) {
352 resolved |= eSymbolContextBlock;
354 actual_resolve_scope |= eSymbolContextBlock;
358 if (resolve_scope & eSymbolContextSymbol) {
361 resolved |= eSymbolContextSymbol;
363 actual_resolve_scope |= eSymbolContextSymbol;
367 if (resolve_scope & eSymbolContextLineEntry) {
370 resolved |= eSymbolContextLineEntry;
372 actual_resolve_scope |= eSymbolContextLineEntry;
376 if (actual_resolve_scope) {
383 lookup_addr, actual_resolve_scope, sc);
387 if ((resolved & eSymbolContextCompUnit) &&
m_sc.
comp_unit ==
nullptr)
389 if ((resolved & eSymbolContextFunction) &&
m_sc.
function ==
nullptr)
391 if ((resolved & eSymbolContextBlock) &&
m_sc.
block ==
nullptr)
393 if ((resolved & eSymbolContextSymbol) &&
m_sc.
symbol ==
nullptr)
395 if ((resolved & eSymbolContextLineEntry) &&
406 resolved |=
m_sc.
target_sp->GetImages().ResolveSymbolContextForAddress(
407 lookup_addr, resolve_scope,
m_sc);
426 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
434 const bool get_child_variables =
true;
435 const bool can_create =
true;
436 const bool stop_if_child_block_is_inlined_function =
true;
438 stop_if_child_block_is_inlined_function,
476 bool must_have_valid_location) {
477 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
486 const bool can_create =
true;
487 const bool get_parent_variables =
true;
488 const bool stop_if_block_is_inlined_function =
true;
490 can_create, get_parent_variables, stop_if_block_is_inlined_function,
491 [
this, must_have_valid_location](
Variable *v) {
492 return v->
IsInScope(
this) && (!must_have_valid_location ||
501 if (global_variable_list_sp)
502 var_list_sp->AddVariables(global_variable_list_sp.get());
511 llvm::StringRef original_var_expr = var_expr;
516 if (var_expr.empty()) {
517 error.SetErrorStringWithFormat(
"invalid variable path '%s'",
518 var_expr.str().c_str());
522 const bool check_ptr_vs_member =
524 const bool no_fragile_ivar =
526 const bool no_synth_child =
532 bool address_of =
false;
534 const bool get_file_globals =
true;
544 std::string var_expr_storage;
545 if (var_expr[0] ==
'*') {
547 var_expr = var_expr.drop_front();
548 }
else if (var_expr[0] ==
'&') {
550 var_expr = var_expr.drop_front();
553 size_t separator_idx = var_expr.find_first_of(
".-[=+~|&^%#@!/?,<>{}");
556 ConstString name_const_string(var_expr.substr(0, separator_idx));
558 var_sp = variable_list->
FindVariable(name_const_string,
false);
560 bool synthetically_added_instance_object =
false;
563 var_expr = var_expr.drop_front(name_const_string.
GetLength());
571 if (!instance_var_name.empty()) {
575 if (
Type *var_type = var_sp->GetType())
576 if (
auto compiler_type = var_type->GetForwardCompilerType())
577 if (!compiler_type.IsPointerType())
578 var_expr_storage =
".";
580 if (var_expr_storage.empty())
581 var_expr_storage =
"->";
582 var_expr_storage += var_expr;
583 var_expr = var_expr_storage;
584 synthetically_added_instance_object =
true;
592 for (
const VariableSP &variable_sp : *variable_list) {
595 if (!variable_sp->GetName().IsEmpty())
598 Type *var_type = variable_sp->GetType();
607 valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string);
613 if (var_sp && !valobj_sp) {
619 error.SetErrorStringWithFormat(
"no variable named '%s' found in this frame",
625 while (!var_expr.empty()) {
628 const char separator_type = var_expr[0];
629 bool expr_is_ptr =
false;
630 switch (separator_type) {
633 if (var_expr.size() >= 2 && var_expr[1] !=
'>')
636 if (no_fragile_ivar) {
639 const uint32_t pointer_type_flags =
640 valobj_sp->GetCompilerType().GetTypeInfo(
nullptr);
641 if ((pointer_type_flags & eTypeIsObjC) &&
642 (pointer_type_flags & eTypeIsPointer)) {
651 if (!valobj_sp->IsPointerType() && valobj_sp->HasSyntheticValue()) {
653 if (valobj_sp->GetCompilerType().IsReferenceType()) {
654 valobj_sp = valobj_sp->GetSyntheticValue()->Dereference(deref_error);
655 if (!valobj_sp || deref_error.
Fail()) {
656 error.SetErrorStringWithFormatv(
657 "Failed to dereference reference type: %s", deref_error);
662 valobj_sp = valobj_sp->Dereference(deref_error);
663 if (!valobj_sp || deref_error.
Fail()) {
664 error.SetErrorStringWithFormatv(
665 "Failed to dereference sythetic value: {0}", deref_error);
670 error.SetErrorString(
"Failed to dereference sythetic value");
676 var_expr = var_expr.drop_front();
679 var_expr = var_expr.drop_front();
680 separator_idx = var_expr.find_first_of(
".-[");
681 ConstString child_name(var_expr.substr(0, var_expr.find_first_of(
".-[")));
683 if (check_ptr_vs_member) {
687 const bool actual_is_ptr = valobj_sp->IsPointerType();
689 if (actual_is_ptr != expr_is_ptr) {
692 valobj_sp->GetExpressionPath(var_expr_path_strm);
694 error.SetErrorStringWithFormat(
695 "\"%s\" is a pointer and . was used to attempt to access "
696 "\"%s\". Did you mean \"%s->%s\"?",
698 var_expr_path_strm.
GetData(), var_expr.str().c_str());
700 error.SetErrorStringWithFormat(
701 "\"%s\" is not a pointer and -> was used to attempt to "
702 "access \"%s\". Did you mean \"%s.%s\"?",
704 var_expr_path_strm.
GetData(), var_expr.str().c_str());
708 child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name);
709 if (!child_valobj_sp) {
710 if (!no_synth_child) {
711 child_valobj_sp = valobj_sp->GetSyntheticValue();
714 child_valobj_sp->GetChildMemberWithName(child_name);
717 if (no_synth_child || !child_valobj_sp) {
719 if (synthetically_added_instance_object) {
723 error.SetErrorStringWithFormat(
724 "no variable or instance variable named '%s' found in "
728 valobj_sp->GetExpressionPath(var_expr_path_strm);
730 error.SetErrorStringWithFormat(
731 "\"%s\" is not a member of \"(%s) %s\"",
733 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
736 error.SetErrorStringWithFormat(
737 "incomplete expression path after \"%s\" in \"%s\"",
739 original_var_expr.str().c_str());
745 synthetically_added_instance_object =
false;
747 var_expr = var_expr.drop_front(child_name.
GetLength());
750 child_valobj_sp->GetDynamicValue(use_dynamic));
751 if (dynamic_value_sp)
752 child_valobj_sp = dynamic_value_sp;
759 if (var_expr.size() <= 2) {
760 error.SetErrorStringWithFormat(
761 "invalid square bracket encountered after \"%s\" in \"%s\"",
762 var_expr_path_strm.
GetData(), var_expr.str().c_str());
767 var_expr = var_expr.drop_front();
768 long child_index = 0;
771 size_t end_pos = var_expr.find_first_of(
']');
772 if (end_pos == llvm::StringRef::npos) {
773 error.SetErrorStringWithFormat(
774 "missing closing square bracket in expression \"%s\"",
778 llvm::StringRef index_expr = var_expr.take_front(end_pos);
779 llvm::StringRef original_index_expr = index_expr;
781 var_expr = var_expr.drop_front(end_pos + 1);
783 if (index_expr.consumeInteger(0, child_index)) {
786 error.SetErrorStringWithFormat(
"invalid index expression \"%s\"",
787 index_expr.str().c_str());
791 if (index_expr.empty()) {
794 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
800 if (!temp || deref_error.
Fail()) {
801 valobj_sp->GetExpressionPath(var_expr_path_strm);
802 error.SetErrorStringWithFormat(
803 "could not dereference \"(%s) %s\"",
804 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
810 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() &&
818 valobj_sp->GetExpressionPath(var_expr_path_strm);
819 error.SetErrorStringWithFormat(
820 "could not get item 0 for \"(%s) %s\"",
821 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
829 bool is_incomplete_array =
false;
830 if (valobj_sp->IsPointerType()) {
831 bool is_objc_pointer =
true;
833 if (valobj_sp->GetCompilerType().GetMinimumLanguage() !=
835 is_objc_pointer =
false;
836 else if (!valobj_sp->GetCompilerType().IsPointerType())
837 is_objc_pointer =
false;
839 if (no_synth_child && is_objc_pointer) {
840 error.SetErrorStringWithFormat(
841 "\"(%s) %s\" is an Objective-C pointer, and cannot be "
843 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
847 }
else if (is_objc_pointer) {
852 || synthetic == valobj_sp)
855 valobj_sp->GetExpressionPath(var_expr_path_strm);
856 error.SetErrorStringWithFormat(
857 "\"(%s) %s\" is not an array type",
858 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
860 }
else if (
static_cast<uint32_t
>(child_index) >=
862 ->GetNumChildrenIgnoringErrors()
865 valobj_sp->GetExpressionPath(var_expr_path_strm);
866 error.SetErrorStringWithFormat(
867 "array index %ld is not valid for \"(%s) %s\"", child_index,
868 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
871 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
872 if (!child_valobj_sp) {
873 valobj_sp->GetExpressionPath(var_expr_path_strm);
874 error.SetErrorStringWithFormat(
875 "array index %ld is not valid for \"(%s) %s\"", child_index,
876 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
882 valobj_sp->GetSyntheticArrayMember(child_index,
true);
883 if (!child_valobj_sp) {
884 valobj_sp->GetExpressionPath(var_expr_path_strm);
885 error.SetErrorStringWithFormat(
886 "failed to use pointer as array for index %ld for "
889 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
893 }
else if (valobj_sp->GetCompilerType().IsArrayType(
894 nullptr,
nullptr, &is_incomplete_array)) {
897 child_valobj_sp = valobj_sp->GetChildAtIndex(child_index);
898 if (!child_valobj_sp && (is_incomplete_array || !no_synth_child))
900 valobj_sp->GetSyntheticArrayMember(child_index,
true);
902 if (!child_valobj_sp) {
903 valobj_sp->GetExpressionPath(var_expr_path_strm);
904 error.SetErrorStringWithFormat(
905 "array index %ld is not valid for \"(%s) %s\"", child_index,
906 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
909 }
else if (valobj_sp->GetCompilerType().IsScalarType()) {
911 child_valobj_sp = valobj_sp->GetSyntheticBitFieldChild(
912 child_index, child_index,
true);
913 if (!child_valobj_sp) {
914 valobj_sp->GetExpressionPath(var_expr_path_strm);
915 error.SetErrorStringWithFormat(
916 "bitfield range %ld-%ld is not valid for \"(%s) %s\"",
917 child_index, child_index,
918 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
923 if (no_synth_child ||
925 || synthetic == valobj_sp)
928 valobj_sp->GetExpressionPath(var_expr_path_strm);
929 error.SetErrorStringWithFormat(
930 "\"(%s) %s\" is not an array type",
931 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
933 }
else if (
static_cast<uint32_t
>(child_index) >=
934 synthetic->GetNumChildrenIgnoringErrors()
936 valobj_sp->GetExpressionPath(var_expr_path_strm);
937 error.SetErrorStringWithFormat(
938 "array index %ld is not valid for \"(%s) %s\"", child_index,
939 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
942 child_valobj_sp = synthetic->GetChildAtIndex(child_index);
943 if (!child_valobj_sp) {
944 valobj_sp->GetExpressionPath(var_expr_path_strm);
945 error.SetErrorStringWithFormat(
946 "array index %ld is not valid for \"(%s) %s\"", child_index,
947 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
953 if (!child_valobj_sp) {
960 child_valobj_sp->GetDynamicValue(use_dynamic));
961 if (dynamic_value_sp)
962 child_valobj_sp = dynamic_value_sp;
970 if (index_expr.front() !=
'-') {
971 error.SetErrorStringWithFormat(
"invalid range expression \"'%s'\"",
972 original_index_expr.str().c_str());
976 index_expr = index_expr.drop_front();
977 long final_index = 0;
978 if (index_expr.getAsInteger(0, final_index)) {
979 error.SetErrorStringWithFormat(
"invalid range expression \"'%s'\"",
980 original_index_expr.str().c_str());
985 if (child_index > final_index) {
986 long temp = child_index;
987 child_index = final_index;
991 if (valobj_sp->GetCompilerType().IsPointerToScalarType() && deref) {
998 if (!temp || deref_error.
Fail()) {
999 valobj_sp->GetExpressionPath(var_expr_path_strm);
1000 error.SetErrorStringWithFormat(
1001 "could not dereference \"(%s) %s\"",
1002 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1003 var_expr_path_strm.
GetData());
1008 }
else if (valobj_sp->GetCompilerType().IsArrayOfScalarType() && deref) {
1015 valobj_sp->GetExpressionPath(var_expr_path_strm);
1016 error.SetErrorStringWithFormat(
1017 "could not get item 0 for \"(%s) %s\"",
1018 valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1019 var_expr_path_strm.
GetData());
1027 valobj_sp->GetSyntheticBitFieldChild(child_index, final_index,
true);
1028 if (!child_valobj_sp) {
1029 valobj_sp->GetExpressionPath(var_expr_path_strm);
1030 error.SetErrorStringWithFormat(
1031 "bitfield range %ld-%ld is not valid for \"(%s) %s\"", child_index,
1032 final_index, valobj_sp->GetTypeName().AsCString(
"<invalid type>"),
1033 var_expr_path_strm.
GetData());
1036 if (!child_valobj_sp) {
1043 child_valobj_sp->GetDynamicValue(use_dynamic));
1044 if (dynamic_value_sp)
1045 child_valobj_sp = dynamic_value_sp;
1054 valobj_sp->GetExpressionPath(var_expr_path_strm);
1055 error.SetErrorStringWithFormat(
1056 "unexpected char '%c' encountered after \"%s\" in \"%s\"",
1057 separator_type, var_expr_path_strm.
GetData(),
1058 var_expr.str().c_str());
1064 if (child_valobj_sp)
1065 valobj_sp = child_valobj_sp;
1070 valobj_sp = deref_valobj_sp;
1071 }
else if (address_of) {
1073 valobj_sp = address_of_valobj_sp;
1080 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1083 "No frame base available for this historical stack frame.");
1100 llvm::Expected<Value> expr_value =
1102 &exe_ctx,
nullptr, loclist_base_addr,
nullptr,
nullptr);
1132 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1156 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1164 const uint32_t num_variables = var_list->
GetSize();
1165 if (var_idx < num_variables) {
1178 ValueObjectSP dynamic_sp = valobj_sp->GetDynamicValue(use_dynamic);
1203 return recognized_frame_sp->ShouldHide();
1230std::pair<const Instruction::Operand *, int64_t>
1233 switch (operand.
m_type) {
1239 return std::make_pair(
nullptr, 0);
1251 if (!immediate_child) {
1252 return std::make_pair(
nullptr, 0);
1260 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1261 GetBaseExplainingValue(*variable_child, register_context,
1263 if (!base_and_offset.first) {
1264 return std::make_pair(
nullptr, 0);
1267 base_and_offset.second -= immediate_child->
m_immediate;
1269 base_and_offset.second += immediate_child->
m_immediate;
1271 return base_and_offset;
1277 return std::make_pair(
nullptr, 0);
1281 return std::make_pair(
nullptr, 0);
1284 return std::make_pair(&operand, 0);
1286 return std::make_pair(
nullptr, 0);
1290 return std::make_pair(
nullptr, 0);
1293std::pair<const Instruction::Operand *, int64_t>
1298 return GetBaseExplainingValue(operand.
m_children[0], register_context,
1301 return std::make_pair(
nullptr, 0);
1308 const ArchSpec &target_arch = target_sp->GetArchitecture();
1314 const char *plugin_name =
nullptr;
1315 const char *flavor =
nullptr;
1316 const bool force_live_memory =
true;
1320 *target_sp, pc_range, force_live_memory);
1322 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1327 disassembler_sp->GetInstructionList().GetInstructionAtIndex(0);
1329 llvm::SmallVector<Instruction::Operand, 3> operands;
1331 if (!instruction_sp->ParseOperands(operands)) {
1337 if (!register_context_sp) {
1342 std::pair<const Instruction::Operand *, int64_t> base_and_offset =
1343 GetBaseExplainingDereference(operand, *register_context_sp, addr);
1345 if (!base_and_offset.first) {
1349 switch (base_and_offset.first->m_type) {
1352 if (target_sp->ResolveLoadAddress(base_and_offset.first->m_immediate +
1353 base_and_offset.second,
1355 auto c_type_system_or_err =
1357 if (
auto err = c_type_system_or_err.takeError()) {
1359 "Unable to guess value for given address: {0}");
1362 auto ts = *c_type_system_or_err;
1377 base_and_offset.second);
1390 if (offset < 0 || uint64_t(offset) >= parent->GetByteSize()) {
1394 if (parent->IsPointerOrReferenceType()) {
1398 for (
int ci = 0, ce = parent->GetNumChildrenIgnoringErrors(); ci != ce;
1406 int64_t child_offset = child_sp->GetByteOffset();
1407 int64_t child_size = child_sp->GetByteSize().value_or(0);
1409 if (offset >= child_offset && offset < (child_offset + child_size)) {
1410 return GetValueForOffset(frame, child_sp, offset - child_offset);
1428 if (!base->IsPointerOrReferenceType()) {
1439 if (offset >= 0 && uint64_t(offset) >= pointee->GetByteSize()) {
1440 int64_t index = offset / pointee->GetByteSize().value_or(1);
1441 offset = offset % pointee->GetByteSize().value_or(1);
1442 const bool can_create =
true;
1443 pointee = base->GetSyntheticArrayMember(index, can_create);
1446 if (!pointee ||
error.Fail()) {
1450 return GetValueForOffset(frame, pointee, offset);
1505 using namespace OperandMatchers;
1522 if (var_sp->LocationExpressionList().MatchesOperand(frame, op))
1526 const uint32_t current_inst =
1532 for (uint32_t ii = current_inst - 1; ii != (uint32_t)-1; --ii) {
1540 if (instruction_sp->IsCall()) {
1546 const char *return_register_name;
1547 if (!abi_sp->GetPointerReturnRegister(return_register_name)) {
1553 return_register_name);
1554 if (!return_register_info) {
1570 llvm::SmallVector<Instruction::Operand, 1> operands;
1571 if (!instruction_sp->ParseOperands(operands) || operands.size() != 1) {
1575 switch (operands[0].m_type) {
1582 operands[0].m_immediate, load_address)) {
1586 load_address, eSymbolContextFunction, sc);
1600 std::string name_str(
1602 name_str.append(
"()");
1605 &frame, name_str, return_value_address, return_type);
1606 return GetValueForDereferincingOffset(frame, return_value_sp, offset);
1613 llvm::SmallVector<Instruction::Operand, 2> operands;
1614 if (!instruction_sp->ParseOperands(operands) || operands.size() != 2) {
1623 if (clobbered_reg_matcher(operands[0])) {
1624 origin_operand = &operands[1];
1626 else if (clobbered_reg_matcher(operands[1])) {
1627 origin_operand = &operands[0];
1636 int64_t origin_offset = 0;
1638 if (
FetchRegOp(origin_register)(*origin_operand)) {
1639 source_path = DoGuessValueAt(frame, origin_register, 0, disassembler,
1640 variables, instruction_sp->GetAddress());
1643 FetchRegOp(origin_register))(*origin_operand) ||
1648 FetchImmOp(origin_offset)))(*origin_operand)) {
1650 DoGuessValueAt(frame, origin_register, origin_offset, disassembler,
1651 variables, instruction_sp->GetAddress());
1656 GetValueForDereferincingOffset(frame, source_path, offset);
1672 const ArchSpec &target_arch = target_sp->GetArchitecture();
1695 const char *plugin_name =
nullptr;
1696 const char *flavor =
nullptr;
1697 const bool force_live_memory =
true;
1700 *target_sp, pc_range, force_live_memory);
1702 if (!disassembler_sp || !disassembler_sp->GetInstructionList().GetSize()) {
1706 const bool get_file_globals =
false;
1713 return DoGuessValueAt(*
this, reg, offset, *disassembler_sp, *variables,
1726 if (!target_sp && !process_sp)
1734 const bool can_create =
true;
1735 const bool get_parent_variables =
true;
1736 const bool stop_if_block_is_inlined_function =
true;
1739 can_create, get_parent_variables, stop_if_block_is_inlined_function,
1740 [
this](
Variable *v) { return v->IsInScope(this); },
1756 ProcessSP process_sp(thread_sp->CalculateProcess());
1758 target_sp = process_sp->CalculateTarget();
1767 process_sp = thread_sp->CalculateProcess();
1781 llvm::StringRef frame_marker) {
1788 nullptr,
false,
false)) {
1796 const char *frame_marker) {
1797 if (strm ==
nullptr)
1812 Dump(strm,
true,
false);
1818 bool show_fullpaths) {
1819 if (strm ==
nullptr)
1822 if (show_frame_index)
1826 strm->
Printf(
"0x%0*" PRIx64
" ",
1831 const bool show_module =
true;
1832 const bool show_inline =
true;
1833 const bool show_function_arguments =
true;
1834 const bool show_function_name =
true;
1837 show_inline, show_function_arguments,
1838 show_function_name);
1842 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1854 std::lock_guard<std::recursive_mutex> guard(
m_mutex);
1890 bool show_unique,
const char *frame_marker) {
1891 if (show_frame_info) {
1898 bool have_source =
false, have_debuginfo =
false;
1904 const uint32_t source_lines_before =
1906 const uint32_t source_lines_after =
1912 have_debuginfo =
true;
1913 if (source_lines_before > 0 || source_lines_after > 0) {
1923 source_lines_before, source_lines_after,
"->", &strm);
1932 "Note: this address is compiler-generated code in function "
1933 "%s that has no source code associated with it.",
1936 strm.
Printf(
"Note: this address is compiler-generated code that "
1937 "has no source code associated with it.");
1942 switch (disasm_display) {
1959 if (disasm_lines > 0) {
1961 const char *plugin_name =
nullptr;
1962 const char *flavor =
nullptr;
1963 const bool mixed_source_and_assembly =
false;
1965 target->
GetDebugger(), target_arch, plugin_name, flavor,
1968 mixed_source_and_assembly, 0,
1980 auto process =
GetThread()->GetProcess();
1984 auto &manager = process->GetTarget().GetFrameRecognizerManager();
1985 auto new_generation = manager.GetGeneration();
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
#define RESOLVED_GLOBAL_VARIABLES
#define RESOLVED_FRAME_ID_SYMBOL_SCOPE
#define RESOLVED_FRAME_CODE_ADDR
#define RESOLVED_VARIABLES
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
void SetByteSize(lldb::addr_t byte_size)
Set accessor for the byte size of this range.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
lldb::addr_t GetOpcodeLoadAddress(Target *target, AddressClass addr_class=AddressClass::eInvalid) const
Get the load address as an opcode load address.
bool SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, AddressClass addr_class=AddressClass::eInvalid, bool allow_section_end=false)
void SetRawAddress(lldb::addr_t addr)
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
lldb::addr_t GetFileAddress() const
Get the file address.
lldb::addr_t GetOffset() const
Get the section relative offset value.
bool IsValid() const
Check if the object state is valid.
bool IsSectionOffset() const
Check if an address is section offset.
bool SetOffset(lldb::addr_t offset)
Set accessor for the offset.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
uint32_t GetMaximumOpcodeByteSize() const
A class that describes a single lexical block.
Block * GetContainingInlinedBlock()
Get the inlined block that contains this block.
Function * CalculateSymbolContextFunction() override
uint32_t AppendVariables(bool can_create, bool get_parent_variables, bool stop_if_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Appends the variables from this block, and optionally from all parent blocks, to variable_list.
uint32_t AppendBlockVariables(bool can_create, bool get_child_block_variables, bool stop_if_child_block_is_inlined_function, const std::function< bool(Variable *)> &filter, VariableList *variable_list)
Get the variable list for this block and optionally all child blocks if get_child_variables is true.
A class that describes a compilation unit.
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
lldb::LanguageType GetLanguage()
Generic representation of a type in a programming language.
CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) const
Create related types using the current type's AST.
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
bool IsAnonymousType() const
bool IsFunctionType() const
CompilerType GetFunctionReturnType() const
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
bool IsEmpty() const
Test for empty string.
size_t GetLength() const
Get the length in bytes of string value.
const char * GetCString() const
Get the string value as a C string.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
bool IsAlwaysValidSingleExpr() const
llvm::Expected< Value > Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx, lldb::addr_t func_load_addr, const Value *initial_value_ptr, const Value *object_address_ptr) const
A class to manage flag bits.
uint64_t GetDisassemblyLineCount() const
StopDisassemblyType GetStopDisassemblyDisplay() const
@ eStopDisassemblyTypeNever
@ eStopDisassemblyTypeNoDebugInfo
@ eStopDisassemblyTypeNoSource
@ eStopDisassemblyTypeAlways
uint64_t GetStopSourceLineCount(bool before) const
const FormatEntity::Entry * GetFrameFormat() const
const FormatEntity::Entry * GetFrameFormatUnique() const
InstructionList & GetInstructionList()
static lldb::DisassemblerSP DisassembleRange(const ArchSpec &arch, const char *plugin_name, const char *flavor, Target &target, const AddressRange &disasm_range, bool force_live_memory=false)
static bool Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, const Address &start, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm)
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
ExecutionContextScope * GetBestExecutionContextScope() const
void SetContext(const lldb::TargetSP &target_sp, bool get_process)
Target * GetTargetPtr() const
Returns a pointer to the target object.
bool IsClear(ValueType bit) const
Test a single flag bit to see if it is clear (zero).
ValueType Get() const
Get accessor for all flags.
ValueType Clear(ValueType mask=~static_cast< ValueType >(0))
Clear one or more flags.
void Reset(ValueType flags)
Set accessor for all flags.
ValueType Set(ValueType mask)
Set one or more flags by logical OR'ing mask with the current flags.
A class that describes a function.
const AddressRange & GetAddressRange()
CompilerType GetCompilerType()
DWARFExpressionList & GetFrameBaseExpression()
Get accessor for the frame base location.
ConstString GetName() const
const Mangled & GetMangled() const
void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no)
Find the file and line number of the source location of the start of the function.
Block & GetBlock(bool can_create)
Get accessor for the block list.
uint32_t GetIndexOfInstructionAtAddress(const Address &addr)
lldb::InstructionSP GetInstructionAtIndex(size_t idx) const
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
size_t DisplaySourceLinesWithLineNumbers(const FileSpec &file, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
This base class provides an interface to stack frames.
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
uint16_t m_frame_recognizer_generation
lldb::VariableListSP m_variable_list_sp
void UpdatePreviousFrameFromCurrentFrame(StackFrame &curr_frame)
lldb::ThreadSP GetThread() const
Address m_frame_code_addr
The frame code address (might not be the same as the actual PC for inlined frames) as a section/offse...
@ eExpressionPathOptionsNoFragileObjcIvar
@ eExpressionPathOptionCheckPtrVsMember
@ eExpressionPathOptionsInspectAnonymousUnions
@ eExpressionPathOptionsAllowDirectIVarAccess
@ eExpressionPathOptionsNoSyntheticChildren
bool IsHidden()
Query whether this frame should be hidden from backtraces.
VariableList * GetVariableList(bool get_file_globals, Status *error_ptr)
Retrieve the list of variables that are in scope at this StackFrame's pc.
DWARFExpressionList * GetFrameBaseExpression(Status *error_ptr)
Get the DWARFExpressionList corresponding to the Canonical Frame Address.
void UpdateCurrentFrameFromPreviousFrame(StackFrame &prev_frame)
ValueObjectList m_variable_list_value_objects
Value objects for each variable in m_variable_list_sp.
bool m_cfa_is_valid
Does this frame have a CFA? Different from CFA == LLDB_INVALID_ADDRESS.
std::optional< lldb::RecognizedStackFrameSP > m_recognized_frame_sp
void DumpUsingSettingsFormat(Stream *strm, bool show_unique=false, const char *frame_marker=nullptr)
Print a description for this frame using the frame-format formatter settings.
bool IsInlined()
Query whether this frame is a concrete frame on the call stack, or if it is an inlined frame derived ...
lldb::ValueObjectSP GetValueForVariableExpressionPath(llvm::StringRef var_expr, lldb::DynamicValueType use_dynamic, uint32_t options, lldb::VariableSP &var_sp, Status &error)
Create a ValueObject for a variable name / pathname, possibly including simple dereference/child sele...
SourceLanguage GuessLanguage()
Similar to GetLanguage(), but is allowed to take a potentially incorrect guess if exact information i...
lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
lldb::RegisterContextSP m_reg_context_sp
lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset)
Attempt to reconstruct the ValueObject for the address contained in a given register plus an offset.
lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
Address GetFrameCodeAddressForSymbolication()
Get the current code Address suitable for symbolication, may not be the same as GetFrameCodeAddress()...
@ History
A historical stack frame – possibly without CFA or registers or local variables.
@ Artificial
An artificial stack frame (e.g.
uint32_t m_concrete_frame_index
bool m_behaves_like_zeroth_frame
Whether this frame behaves like the zeroth frame, in the sense that its pc value might not immediatel...
lldb::ValueObjectSP GuessValueForAddress(lldb::addr_t addr)
Attempt to econstruct the ValueObject for a given raw address touched by the current instruction.
bool ChangePC(lldb::addr_t pc)
Change the pc value for a given thread.
lldb::ThreadSP CalculateThread() override
SourceLanguage GetLanguage()
Query this frame to determine what the default language should be when parsing expressions given the ...
lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
bool HasCachedData() const
StreamString m_disassembly
lldb::StackFrameSP CalculateStackFrame() override
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Status m_frame_base_error
bool IsHistorical() const
Query whether this frame is part of a historical backtrace.
const char * Disassemble()
Return the disassembly for the instructions of this StackFrame's function as a single C string.
bool IsArtificial() const
Query whether this frame is artificial (e.g a synthesized result of inferring missing tail call frame...
void CalculateExecutionContext(ExecutionContext &exe_ctx) override
Reconstruct the object's execution context into sc.
void Dump(Stream *strm, bool show_frame_index, bool show_fullpaths)
Print a description for this frame using a default format.
uint32_t GetFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList.
bool HasDebugInformation()
Determine whether this StackFrame has debug information available or not.
bool GetStatus(Stream &strm, bool show_frame_info, bool show_source, bool show_unique=false, const char *frame_marker=nullptr)
Print a description of this stack frame and/or the source context/assembly for this stack frame.
Block * GetFrameBlock()
Get the current lexical scope block for this StackFrame, if possible.
bool GetFrameBaseValue(Scalar &value, Status *error_ptr)
Return the Canonical Frame Address (DWARF term) for this frame.
bool DumpUsingFormat(Stream &strm, const lldb_private::FormatEntity::Entry *format, llvm::StringRef frame_marker={})
Print a description of this frame using the provided frame format.
lldb::ProcessSP CalculateProcess() override
lldb::RecognizedStackFrameSP GetRecognizedFrame()
std::recursive_mutex m_mutex
StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, bool behaves_like_zeroth_frame, const SymbolContext *sc_ptr)
Construct a StackFrame object without supplying a RegisterContextSP.
lldb::ValueObjectSP FindVariable(ConstString name)
Attempt to reconstruct the ValueObject for a variable with a given name from within the current Stack...
const Address & GetFrameCodeAddress()
Get an Address for the current pc value in this StackFrame.
lldb::TargetSP CalculateTarget() override
void SetPC(lldb::addr_t pc)
SymbolContextScope * GetSymbolContextScope() const
lldb::addr_t GetPC() const
void SetSymbolContextScope(SymbolContextScope *symbol_scope)
void SetCFA(lldb::addr_t cfa)
void Clear()
Clear the object state.
bool Fail() const
Test for error condition.
void SetErrorString(llvm::StringRef err_str)
Set the current error string to err_str.
bool Success() const
Test for success condition.
const char * GetData() const
llvm::StringRef GetString() const
A stream class that can stream formatted output to a file.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
"lldb/Symbol/SymbolContextScope.h" Inherit from this if your object is part of a symbol context and c...
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
llvm::StringRef GetInstanceVariableName()
Determines the name of the instance variable for the this decl context.
ConstString GetFunctionName(Mangled::NamePreference preference=Mangled::ePreferDemangled) const
Find a name of the innermost function for the symbol context.
Block * block
The Block for a given query.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
bool DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const Address &so_addr, bool show_fullpaths, bool show_module, bool show_inlined_frames, bool show_function_arguments, bool show_function_name, bool show_function_display_name=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump the stop context in this object to a Stream.
uint32_t GetResolvedMask() const
void Clear(bool clear_target)
Clear the object's state.
Symbol * symbol
The Symbol for a given query.
lldb::TargetSP target_sp
The Target for a given query.
LineEntry line_entry
The LineEntry for a given query.
Provides public interface for all SymbolFiles.
Status GetFrameVariableError(StackFrame &frame)
Get an error that describes why variables might be missing for a given symbol context.
SourceManager & GetSourceManager()
const ArchSpec & GetArchitecture() const
CompilerType GetForwardCompilerType()
void SetValueObjectAtIndex(size_t idx, const lldb::ValueObjectSP &valobj_sp)
lldb::ValueObjectSP GetValueObjectAtIndex(size_t idx)
void Swap(ValueObjectList &value_object_list)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
lldb::VariableSP FindVariable(ConstString name, bool include_static_members=true)
uint32_t FindIndexForVariable(Variable *variable)
bool IsInScope(StackFrame *frame)
bool LocationIsValidForFrame(StackFrame *frame)
#define LLDB_INVALID_ADDRESS
std::function< bool(const Instruction::Operand &)> MatchRegOp(const RegisterInfo &info)
std::function< bool(const Instruction::Operand &)> FetchRegOp(ConstString ®)
std::function< bool(const Instruction::Operand &)> FetchImmOp(int64_t &imm)
std::function< bool(const Instruction::Operand &)> MatchOpType(Instruction::Operand::Type type)
std::function< bool(const Instruction::Operand &)> MatchBinaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> left, std::function< bool(const Instruction::Operand &)> right)
std::function< bool(const Instruction::Operand &)> MatchUnaryOp(std::function< bool(const Instruction::Operand &)> base, std::function< bool(const Instruction::Operand &)> child)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::ABI > ABISP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::RecognizedStackFrame > RecognizedStackFrameSP
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
@ eLanguageTypeC
Non-standardized C, such as K&R.
@ eLanguageTypeObjC
Objective-C.
std::shared_ptr< lldb_private::Instruction > InstructionSP
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Disassembler > DisassemblerSP
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
enum lldb_private::Instruction::Operand::Type m_type
static Operand BuildImmediate(lldb::addr_t imm, bool neg)
static Operand BuildDereference(const Operand &ref)
std::vector< Operand > m_children
static Operand BuildSum(const Operand &lhs, const Operand &rhs)
static Operand BuildRegister(ConstString &r)
uint16_t column
The column number of the source line, or zero if there is no column information.
bool IsValid() const
Check if a line entry object is valid.
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
const FileSpec & GetFile() const
Helper to access the file.
void ApplyFileMappings(lldb::TargetSP target_sp)
Apply file mappings from target.source-map to the LineEntry's file.
Every register is described in detail including its name, alternate name (optional),...
A type-erased pair of llvm::dwarf::SourceLanguageName and version.