Debugger: look up symbols in stack traces

This commit is contained in:
Adam Higerd 2020-07-31 20:01:23 -05:00 committed by Vicki Pfau
parent 044710c3a8
commit 002e9c8802
2 changed files with 48 additions and 13 deletions

View File

@ -14,6 +14,8 @@ CXX_GUARD_START
#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 @@ enum mStackTraceMode {
};
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 mStackTraceDeinit(struct mStackTrace* stack);
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

View File

@ -4,6 +4,7 @@
* 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 @@ 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* 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 @@ struct mStackFrame* mStackTracePush(struct mStackTrace* stack, uint32_t pc, uint
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 @@ struct mStackFrame* mStackTraceGetFrame(struct mStackTrace* stack, uint32_t fram
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 @@ void mStackTraceFormatFrame(struct mStackTrace* stack, uint32_t frame, char* out
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;
}