From 1d6d4a5377ef0c9b1b1ed261e2ba852f082b0998 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 28 Apr 2019 13:27:10 -0700 Subject: [PATCH] Debugger: Add tracing to file --- CHANGES | 1 + include/mgba/internal/debugger/cli-debugger.h | 2 ++ src/debugger/cli-debugger.c | 27 ++++++++++++++++--- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 2ef909c91..6d5c5c83a 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Features: - Debugger: Add unary operators and memory dereferencing - GB: Expose platform information to CLI debugger - Support Discord Rich Presence + - Debugger: Add tracing to file Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 60ec00fa4..0409ffe8e 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -17,6 +17,7 @@ extern const char* ERROR_OVERFLOW; extern const char* ERROR_INVALID_ARGS; struct CLIDebugger; +struct VFile; struct CLIDebugVector { struct CLIDebugVector* next; @@ -76,6 +77,7 @@ struct CLIDebugger { struct CLIDebuggerBackend* backend; int traceRemaining; + struct VFile* traceVf; }; void CLIDebuggerCreate(struct CLIDebugger*); diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index d2a93aa30..965e57f5a 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -11,6 +11,7 @@ #include #include #include +#include #if ENABLE_SCRIPTING #include @@ -100,7 +101,7 @@ static struct CLIDebuggerCommandSummary _debuggerCommands[] = { { "r/2", _readHalfword, "I", "Read a halfword from a specified offset" }, { "r/4", _readWord, "I", "Read a word from a specified offset" }, { "status", _printStatus, "", "Print the current status" }, - { "trace", _trace, "I", "Trace a fixed number of instructions" }, + { "trace", _trace, "Is", "Trace a number of instructions" }, { "w", _setReadWriteWatchpoint, "Is", "Set a watchpoint" }, { "w/1", _writeByte, "II", "Write a byte at a specified offset" }, { "w/2", _writeHalfword, "II", "Write a halfword at a specified offset" }, @@ -647,9 +648,16 @@ static void _trace(struct CLIDebugger* debugger, struct CLIDebugVector* dv) { } debugger->traceRemaining = dv->intValue; + if (debugger->traceVf) { + debugger->traceVf->close(debugger->traceVf); + debugger->traceVf = NULL; + } if (debugger->traceRemaining == 0) { return; } + if (dv->next && dv->next->charValue) { + debugger->traceVf = VFileOpen(dv->next->charValue, O_CREAT | O_WRONLY | O_APPEND); + } if (_doTrace(debugger)) { debugger->d.state = DEBUGGER_CUSTOM; } else { @@ -661,12 +669,17 @@ static bool _doTrace(struct CLIDebugger* debugger) { char trace[1024]; trace[sizeof(trace) - 1] = '\0'; debugger->d.core->step(debugger->d.core); - size_t traceSize = sizeof(trace) - 1; + size_t traceSize = sizeof(trace) - 2; debugger->d.platform->trace(debugger->d.platform, trace, &traceSize); - if (traceSize + 1 < sizeof(trace)) { + if (traceSize + 1 <= sizeof(trace)) { + trace[traceSize] = '\n'; trace[traceSize + 1] = '\0'; } - debugger->backend->printf(debugger->backend, "%s\n", trace); + if (debugger->traceVf) { + debugger->traceVf->write(debugger->traceVf, trace, traceSize + 1); + } else { + debugger->backend->printf(debugger->backend, "%s", trace); + } if (debugger->traceRemaining > 0) { --debugger->traceRemaining; } @@ -940,11 +953,17 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r static void _cliDebuggerInit(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; cliDebugger->traceRemaining = 0; + cliDebugger->traceVf = NULL; cliDebugger->backend->init(cliDebugger->backend); } static void _cliDebuggerDeinit(struct mDebugger* debugger) { struct CLIDebugger* cliDebugger = (struct CLIDebugger*) debugger; + if (cliDebugger->traceVf) { + cliDebugger->traceVf->close(cliDebugger->traceVf); + cliDebugger->traceVf = NULL; + } + if (cliDebugger->system) { if (cliDebugger->system->deinit) { cliDebugger->system->deinit(cliDebugger->system);