HackStudio: Improve backtrace accuracy

We now decrement the return address of the previous frame by one to get
the address of the call instruction and use this address in the
backtrace.

This results in more accurate source position information than what we
previously had when using the return address.
This commit is contained in:
Itamar 2021-11-19 16:13:07 +02:00 committed by Linus Groh
parent d6d48ce936
commit ce726fe027
Notes: sideshowbarker 2024-07-18 00:57:07 +09:00
2 changed files with 16 additions and 6 deletions

View File

@ -36,21 +36,30 @@ Vector<BacktraceModel::FrameInfo> BacktraceModel::create_backtrace(Debug::Proces
FlatPtr current_ebp = regs.bp(); FlatPtr current_ebp = regs.bp();
FlatPtr current_instruction = regs.ip(); FlatPtr current_instruction = regs.ip();
Vector<BacktraceModel::FrameInfo> frames; Vector<BacktraceModel::FrameInfo> frames;
size_t frame_index = 0;
do { do {
auto lib = inspector.library_at(regs.ip()); auto lib = inspector.library_at(current_instruction);
if (!lib) if (!lib)
continue; continue;
String name = lib->debug_info->name_of_containing_function(current_instruction - lib->base_address);
// After the first frame, current_instruction holds the return address from the function call.
// We need to go back to the 'call' instruction to get accurate source position information.
if (frame_index > 0)
--current_instruction;
String name = lib->debug_info->elf().symbolicate(current_instruction - lib->base_address);
if (name.is_null()) { if (name.is_null()) {
dbgln("BacktraceModel: couldn't find containing function for address: {:p}", current_instruction); dbgln("BacktraceModel: couldn't find containing function for address: {:p} (library={})", current_instruction, lib->name);
name = "<missing>"; name = "<missing>";
} }
frames.append({ name, current_instruction, current_ebp }); auto source_position = lib->debug_info->get_source_position(current_instruction - lib->base_address);
frames.append({ name, current_instruction, current_ebp, source_position });
auto frame_info = Debug::StackFrameUtils::get_info(inspector, current_ebp); auto frame_info = Debug::StackFrameUtils::get_info(inspector, current_ebp);
VERIFY(frame_info.has_value()); VERIFY(frame_info.has_value());
current_instruction = frame_info.value().return_address; current_instruction = frame_info.value().return_address;
current_ebp = frame_info.value().next_ebp; current_ebp = frame_info.value().next_ebp;
++frame_index;
} while (current_ebp && current_instruction); } while (current_ebp && current_instruction);
return frames; return frames;
} }

View File

@ -38,8 +38,9 @@ public:
struct FrameInfo { struct FrameInfo {
String function_name; String function_name;
FlatPtr instruction_address; FlatPtr instruction_address { 0 };
FlatPtr frame_base; FlatPtr frame_base { 0 };
Optional<Debug::DebugInfo::SourcePosition> m_source_position;
}; };
const Vector<FrameInfo>& frames() const { return m_frames; } const Vector<FrameInfo>& frames() const { return m_frames; }