all repos — mgba @ 002e9c8802e93766f4cd544432779e57f706a929

mGBA Game Boy Advance Emulator

Debugger: look up symbols in stack traces
Adam Higerd chighland@gmail.com
Fri, 31 Jul 2020 20:01:23 -0500
commit

002e9c8802e93766f4cd544432779e57f706a929

parent

044710c3a809f48f95dfd1be160bc219461e3aea

2 files changed, 48 insertions(+), 13 deletions(-)

jump to
M include/mgba/internal/debugger/stack-trace.hinclude/mgba/internal/debugger/stack-trace.h

@@ -14,6 +14,8 @@ #include <mgba/core/cpu.h>

#include <mgba/core/log.h> #include <mgba-util/vector.h> +struct mDebuggerSymbols; + enum mStackTraceMode { STACK_TRACE_DISABLED = 0, STACK_TRACE_ENABLED = 1,

@@ -23,8 +25,11 @@ STACK_TRACE_BREAK_ON_BOTH = STACK_TRACE_BREAK_ON_RETURN | STACK_TRACE_BREAK_ON_CALL

}; struct mStackFrame { + int callSegment; uint32_t callAddress; + int entrySegment; uint32_t entryAddress; + int frameBaseSegment; uint32_t frameBaseAddress; void* regs; bool finished;

@@ -47,8 +52,9 @@

void mStackTraceClear(struct mStackTrace* stack); size_t mStackTraceGetDepth(struct mStackTrace* stack); struct mStackFrame* mStackTracePush(struct mStackTrace* stack, uint32_t pc, uint32_t destAddress, uint32_t sp, void* regs); +struct mStackFrame* mStackTracePushSegmented(struct mStackTrace* stack, int pcSegment, uint32_t pc, int destSegment, uint32_t destAddress, int spSegment, uint32_t sp, void* regs); struct mStackFrame* mStackTraceGetFrame(struct mStackTrace* stack, uint32_t frame); -void mStackTraceFormatFrame(struct mStackTrace* stack, uint32_t frame, char* out, size_t* length); +void mStackTraceFormatFrame(struct mStackTrace* stack, struct mDebuggerSymbols* st, uint32_t frame, char* out, size_t* length); void mStackTracePop(struct mStackTrace* stack); CXX_GUARD_END
M src/debugger/stack-trace.csrc/debugger/stack-trace.c

@@ -4,6 +4,7 @@ * This Source Code Form is subject to the terms of the Mozilla Public

* License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include <mgba/internal/debugger/stack-trace.h> +#include <mgba/internal/debugger/symbols.h> #include <mgba/core/core.h>

@@ -40,8 +41,11 @@ }

struct mStackFrame* mStackTracePush(struct mStackTrace* stack, uint32_t pc, uint32_t destAddress, uint32_t sp, void* regs) { struct mStackFrame* frame = mStackFramesAppend(&stack->stack); + frame->callSegment = -1; frame->callAddress = pc; + frame->entrySegment = -1; frame->entryAddress = destAddress; + frame->frameBaseSegment = -1; frame->frameBaseAddress = sp; frame->regs = malloc(stack->registersSize); frame->finished = false;

@@ -51,6 +55,14 @@ memcpy(frame->regs, regs, stack->registersSize);

return frame; } +struct mStackFrame* mStackTracePushSegmented(struct mStackTrace* stack, int pcSegment, uint32_t pc, int destSegment, uint32_t destAddress, int spSegment, uint32_t sp, void* regs) { + struct mStackFrame* frame = mStackTracePush(stack, pc, destAddress, sp, regs); + frame->callSegment = pcSegment; + frame->entrySegment = destSegment; + frame->frameBaseSegment = spSegment; + return frame; +} + struct mStackFrame* mStackTraceGetFrame(struct mStackTrace* stack, uint32_t frame) { size_t depth = mStackTraceGetDepth(stack); if (frame >= depth) {

@@ -59,20 +71,26 @@ }

return mStackFramesGetPointer(&stack->stack, depth - frame - 1); } -void mStackTraceFormatFrame(struct mStackTrace* stack, uint32_t frame, char* out, size_t* length) { +void mStackTraceFormatFrame(struct mStackTrace* stack, struct mDebuggerSymbols* st, uint32_t frame, char* out, size_t* length) { struct mStackFrame* stackFrame = mStackTraceGetFrame(stack, frame); struct mStackFrame* prevFrame = mStackTraceGetFrame(stack, frame + 1); size_t written = snprintf(out, *length, "#%d ", frame); CHECK_LENGTH(); - if (prevFrame) { - written += snprintf(out + written, *length - written, "0x%08X ", prevFrame->entryAddress); - CHECK_LENGTH(); - } if (!stackFrame) { - written += snprintf(out + written, *length - written, "no stack frame available)\n"); + written += snprintf(out + written, *length - written, "(no stack frame available)\n"); *length = written; return; - } else if (stack->formatRegisters) { + } + const char* functionName = mDebuggerSymbolReverseLookup(st, stackFrame->entryAddress, stackFrame->entrySegment); + if (functionName) { + written += snprintf(out + written, *length - written, "%s ", functionName); + } else if (prevFrame->entrySegment >= 0) { + written += snprintf(out + written, *length - written, "0x%02X:%08X ", stackFrame->entrySegment, stackFrame->entryAddress); + } else { + written += snprintf(out + written, *length - written, "0x%08X ", stackFrame->entryAddress); + } + CHECK_LENGTH(); + if (stack->formatRegisters) { written += snprintf(out + written, *length - written, "("); CHECK_LENGTH(); char buffer[1024];

@@ -81,16 +99,27 @@ stack->formatRegisters(stackFrame, buffer, &formattedSize);

written += snprintf(out + written, *length - written, "%s)\n ", buffer); CHECK_LENGTH(); } + if (stackFrame->callSegment >= 0) { + written += snprintf(out + written, *length - written, "at 0x%02X:%08X", stackFrame->callSegment, stackFrame->callAddress); + } else { + written += snprintf(out + written, *length - written, "at 0x%08X", stackFrame->callAddress); + } + CHECK_LENGTH(); if (prevFrame) { int32_t offset = stackFrame->callAddress - prevFrame->entryAddress; if (offset >= 0) { - written += snprintf(out + written, *length - written, "at 0x%08X [0x%08X+%d]\n", stackFrame->callAddress, prevFrame->entryAddress, offset); - } else { - written += snprintf(out + written, *length - written, "at 0x%08X\n", stackFrame->callAddress); + functionName = mDebuggerSymbolReverseLookup(st, prevFrame->entryAddress, prevFrame->entrySegment); + if (functionName) { + written += snprintf(out + written, *length - written, " [%s+%d]", functionName, offset); + } else if (stackFrame->entrySegment >= 0) { + written += snprintf(out + written, *length - written, " [0x%02X:%08X+%d]", prevFrame->entrySegment, prevFrame->entryAddress, offset); + } else { + written += snprintf(out + written, *length - written, " [0x%08X+%d]", prevFrame->entryAddress, offset); + } } - } else { - written += snprintf(out + written, *length - written, "at 0x%08X\n", stackFrame->callAddress); } + CHECK_LENGTH(); + written += snprintf(out + written, *length - written, "\n"); *length = written; }