From d295095993f5896674995d62319b11dcf2785597 Mon Sep 17 00:00:00 2001 From: FalseHonesty Date: Mon, 12 Apr 2021 01:30:57 -0400 Subject: [PATCH] LibDebug+HackStudio: Fix crashes relating to debugger variable preview For one, viewing a variable who's type contained a subprogram will no longer crash HackStudio. Additionally, the variable view will handle invalid enum values gracefully now, fixing another crash. Finally, deeply nested (nest count > 1) structures will have their memory addresses properly set, fixing the final crash I found. --- .../HackStudio/Debugger/VariablesModel.cpp | 3 ++- Userland/Libraries/LibDebug/DebugInfo.cpp | 14 +++++++------- Userland/Libraries/LibDebug/DebugInfo.h | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Userland/DevTools/HackStudio/Debugger/VariablesModel.cpp b/Userland/DevTools/HackStudio/Debugger/VariablesModel.cpp index e010fa997c..973a2e91a3 100644 --- a/Userland/DevTools/HackStudio/Debugger/VariablesModel.cpp +++ b/Userland/DevTools/HackStudio/Debugger/VariablesModel.cpp @@ -83,7 +83,8 @@ static String variable_value_as_string(const Debug::DebugInfo::VariableInfo& var auto it = variable.type->members.find_if([&enumerator_value = value.value()](const auto& enumerator) { return enumerator->constant_data.as_u32 == enumerator_value; }); - VERIFY(!it.is_end()); + if (it.is_end()) + return String::formatted("Unknown ({})", value.value()); return String::formatted("{}::{}", variable.type_name, (*it)->name); } diff --git a/Userland/Libraries/LibDebug/DebugInfo.cpp b/Userland/Libraries/LibDebug/DebugInfo.cpp index eb8ab79f14..4e6aae944a 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.cpp +++ b/Userland/Libraries/LibDebug/DebugInfo.cpp @@ -252,7 +252,7 @@ static void parse_variable_location(const Dwarf::DIE& variable_die, DebugInfo::V } } -OwnPtr DebugInfo::create_variable_info(const Dwarf::DIE& variable_die, const PtraceRegisters& regs) const +OwnPtr DebugInfo::create_variable_info(const Dwarf::DIE& variable_die, const PtraceRegisters& regs, u32 address_offset) const { VERIFY(variable_die.tag() == Dwarf::EntryTag::Variable || variable_die.tag() == Dwarf::EntryTag::Member @@ -290,6 +290,7 @@ OwnPtr DebugInfo::create_variable_info(const Dwarf::DIE } } else { parse_variable_location(variable_die, *variable_info, regs); + variable_info->location_data.address += address_offset; } if (type_die.has_value()) { @@ -301,21 +302,20 @@ OwnPtr DebugInfo::create_variable_info(const Dwarf::DIE type_die.value().for_each_child([&](const Dwarf::DIE& member) { if (member.is_null()) return; - auto member_variable = create_variable_info(member, regs); + if (member.tag() == Dwarf::EntryTag::SubProgram) + return; + + auto member_variable = create_variable_info(member, regs, variable_info->location_data.address); VERIFY(member_variable); if (type_die.value().tag() == Dwarf::EntryTag::EnumerationType) { member_variable->parent = type_info.ptr(); type_info->members.append(member_variable.release_nonnull()); } else { - if (variable_info->location_type == DebugInfo::VariableInfo::LocationType::None) { + if (variable_info->location_type == DebugInfo::VariableInfo::LocationType::None) return; - } VERIFY(variable_info->location_type == DebugInfo::VariableInfo::LocationType::Address); - if (member_variable->location_type == DebugInfo::VariableInfo::LocationType::Address) - member_variable->location_data.address += variable_info->location_data.address; - member_variable->parent = variable_info.ptr(); variable_info->members.append(member_variable.release_nonnull()); } diff --git a/Userland/Libraries/LibDebug/DebugInfo.h b/Userland/Libraries/LibDebug/DebugInfo.h index 8c73d7dee4..4c1372d9c2 100644 --- a/Userland/Libraries/LibDebug/DebugInfo.h +++ b/Userland/Libraries/LibDebug/DebugInfo.h @@ -140,7 +140,7 @@ private: void prepare_variable_scopes(); void prepare_lines(); void parse_scopes_impl(const Dwarf::DIE& die); - OwnPtr create_variable_info(const Dwarf::DIE& variable_die, const PtraceRegisters&) const; + OwnPtr create_variable_info(const Dwarf::DIE& variable_die, const PtraceRegisters&, u32 address_offset = 0) const; NonnullOwnPtr m_elf; String m_source_root;