Add debugging logging interface

This commit is contained in:
Jeffrey Pfau 2014-02-01 16:13:00 -08:00
parent d97976d0df
commit b9f8955890
4 changed files with 66 additions and 12 deletions

View File

@ -31,6 +31,13 @@ enum DebuggerEntryReason {
DEBUGGER_ENTER_ILLEGAL_OP DEBUGGER_ENTER_ILLEGAL_OP
}; };
enum DebuggerLogLevel {
DEBUGGER_LOG_DEBUG = 0x01,
DEBUGGER_LOG_INFO = 0x02,
DEBUGGER_LOG_WARN = 0x04,
DEBUGGER_LOG_ERROR = 0x08
};
struct ARMDebugger { struct ARMDebugger {
enum DebuggerState state; enum DebuggerState state;
struct ARMCore* cpu; struct ARMCore* cpu;
@ -42,6 +49,9 @@ struct ARMDebugger {
void (*deinit)(struct ARMDebugger*); void (*deinit)(struct ARMDebugger*);
void (*paused)(struct ARMDebugger*); void (*paused)(struct ARMDebugger*);
void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason); void (*entered)(struct ARMDebugger*, enum DebuggerEntryReason);
__attribute__((format (printf, 3, 4)))
void (*log)(struct ARMDebugger*, enum DebuggerLogLevel, const char* format, ...);
}; };
void ARMDebuggerInit(struct ARMDebugger*, struct ARMCore*); void ARMDebuggerInit(struct ARMDebugger*, struct ARMCore*);

View File

@ -71,7 +71,9 @@ static void _ack(struct GDBStub* stub) {
static void _nak(struct GDBStub* stub) { static void _nak(struct GDBStub* stub) {
char nak = '-'; char nak = '-';
printf("Packet error\n"); if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Packet error");
}
send(stub->connection, &nak, 1, 0); send(stub->connection, &nak, 1, 0);
} }
@ -150,6 +152,9 @@ static void _sendMessage(struct GDBStub* stub) {
stub->outgoing[i] = '#'; stub->outgoing[i] = '#';
_int2hex8(checksum, &stub->outgoing[i + 1]); _int2hex8(checksum, &stub->outgoing[i + 1]);
stub->outgoing[i + 3] = 0; stub->outgoing[i + 3] = 0;
if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "> %s", stub->outgoing);
}
send(stub->connection, stub->outgoing, i + 3, 0); send(stub->connection, stub->outgoing, i + 3, 0);
} }
@ -366,7 +371,9 @@ size_t _parseGDBMessage(struct GDBStub* stub, const char* message) {
parsed += 2; parsed += 2;
int networkChecksum = _hex2int(&message[i], 2); int networkChecksum = _hex2int(&message[i], 2);
if (networkChecksum != checksum) { if (networkChecksum != checksum) {
printf("Checksum error: expected %02x, got %02x\n", checksum, networkChecksum); if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_WARN, "Checksum error: expected %02x, got %02x", checksum, networkChecksum);
}
_nak(stub); _nak(stub);
return parsed; return parsed;
} }
@ -430,6 +437,7 @@ void GDBStubCreate(struct GDBStub* stub) {
stub->d.deinit = _gdbStubDeinit; stub->d.deinit = _gdbStubDeinit;
stub->d.paused = _gdbStubPoll; stub->d.paused = _gdbStubPoll;
stub->d.entered = _gdbStubEntered; stub->d.entered = _gdbStubEntered;
stub->d.log = 0;
} }
int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) { int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) {
@ -439,7 +447,9 @@ int GDBStubListen(struct GDBStub* stub, int port, uint32_t bindAddress) {
// TODO: support IPv6 // TODO: support IPv6
stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); stub->socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (stub->socket < 0) { if (stub->socket < 0) {
printf("Couldn't open socket\n"); if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_ERROR, "Couldn't open socket");
}
return 0; return 0;
} }
@ -518,6 +528,9 @@ void GDBStubUpdate(struct GDBStub* stub) {
goto connectionLost; goto connectionLost;
} }
stub->line[messageLen] = '\0'; stub->line[messageLen] = '\0';
if (stub->d.log) {
stub->d.log(&stub->d, DEBUGGER_LOG_DEBUG, "< %s", stub->line);
}
ssize_t position = 0; ssize_t position = 0;
while (position < messageLen) { while (position < messageLen) {
position += _parseGDBMessage(stub, &stub->line[position]); position += _parseGDBMessage(stub, &stub->line[position]);
@ -525,7 +538,8 @@ void GDBStubUpdate(struct GDBStub* stub) {
} }
connectionLost: connectionLost:
// TODO: add logging support to the debugging interface if (stub->d.log) {
printf("Connection lost\n"); stub->d.log(&stub->d, DEBUGGER_LOG_INFO, "Connection lost");
}
GDBStubHangup(stub); GDBStubHangup(stub);
} }

View File

@ -503,7 +503,7 @@ int GBAHalt(struct GBA* gba) {
return GBAWaitForIRQ(gba); return GBAWaitForIRQ(gba);
} }
void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) { static void _GBAVLog(struct GBA* gba, enum GBALogLevel level, const char* format, va_list args) {
if (!gba) { if (!gba) {
struct GBAThread* threadContext = GBAThreadGetContext(); struct GBAThread* threadContext = GBAThreadGetContext();
if (threadContext) { if (threadContext) {
@ -512,10 +512,7 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
} }
if (gba && gba->logHandler) { if (gba && gba->logHandler) {
va_list args;
va_start(args, format);
gba->logHandler(gba, level, format, args); gba->logHandler(gba, level, format, args);
va_end(args);
return; return;
} }
@ -523,10 +520,7 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
return; return;
} }
va_list args;
va_start(args, format);
vprintf(format, args); vprintf(format, args);
va_end(args);
printf("\n"); printf("\n");
if (level == GBA_LOG_FATAL) { if (level == GBA_LOG_FATAL) {
@ -534,6 +528,38 @@ void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
} }
} }
void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...) {
va_list args;
va_start(args, format);
_GBAVLog(gba, level, format, args);
va_end(args);
}
void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...) {
struct GBABoard* gbaBoard = (struct GBABoard*) debugger->cpu->board;
enum GBALogLevel gbaLevel;
switch (level) {
case DEBUGGER_LOG_DEBUG:
gbaLevel = GBA_LOG_DEBUG;
break;
case DEBUGGER_LOG_INFO:
gbaLevel = GBA_LOG_INFO;
break;
case DEBUGGER_LOG_WARN:
gbaLevel = GBA_LOG_WARN;
break;
case DEBUGGER_LOG_ERROR:
gbaLevel = GBA_LOG_ERROR;
break;
}
va_list args;
va_start(args, format);
_GBAVLog(gbaBoard->p, gbaLevel, format, args);
va_end(args);
}
void GBAHitStub(struct ARMBoard* board, uint32_t opcode) { void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
struct GBABoard* gbaBoard = (struct GBABoard*) board; struct GBABoard* gbaBoard = (struct GBABoard*) board;
enum GBALogLevel level = GBA_LOG_FATAL; enum GBALogLevel level = GBA_LOG_FATAL;

View File

@ -2,6 +2,7 @@
#define GBA_H #define GBA_H
#include "arm.h" #include "arm.h"
#include "debugger.h"
#include "gba-memory.h" #include "gba-memory.h"
#include "gba-video.h" #include "gba-video.h"
@ -146,4 +147,7 @@ void GBALoadBIOS(struct GBA* gba, int fd);
__attribute__((format (printf, 3, 4))) __attribute__((format (printf, 3, 4)))
void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...); void GBALog(struct GBA* gba, enum GBALogLevel level, const char* format, ...);
__attribute__((format (printf, 3, 4)))
void GBADebuggerLogShim(struct ARMDebugger* debugger, enum DebuggerLogLevel level, const char* format, ...);
#endif #endif