all repos — mgba @ 56d5fb579d4881b4d4d01df8029489cfa16fd1ab

mGBA Game Boy Advance Emulator

Debugger: Clean up GDB stub network interfacing
Jeffrey Pfau jeffrey@endrift.com
Fri, 16 Jan 2015 00:50:15 -0800
commit

56d5fb579d4881b4d4d01df8029489cfa16fd1ab

parent

69fb4e4c7bea99d1f0390bb28adf2ab071a7a508

4 files changed, 41 insertions(+), 16 deletions(-)

jump to
M CHANGESCHANGES

@@ -75,6 +75,7 @@ - GBA Memory: Simplify memory API and use fixed bus width

- GBA Video: Start video at the last scanline instead of the first - Debugger: Watchpoints now work on STM/LDM instructions - GBA: Improve accuracy of event timing + - Debugger: Clean up GDB stub network interfacing 0.1.0: (2014-12-13) - Initial release
M src/debugger/gdb-stub.csrc/debugger/gdb-stub.c

@@ -53,15 +53,39 @@ }

static void _gdbStubPoll(struct ARMDebugger* debugger) { struct GDBStub* stub = (struct GDBStub*) debugger; - do { - if (!SOCKET_FAILED(stub->connection)) { - if (!SocketSetBlocking(stub->connection, 1)) { - GDBStubHangup(stub); - return; - } + --stub->untilPoll; + if (stub->untilPoll > 0) { + return; + } + stub->untilPoll = GDB_STUB_INTERVAL; + if (stub->shouldBlock) { + stub->shouldBlock = false; + if (!SocketSetBlocking(stub->socket, false)) { + GDBStubHangup(stub); + return; } - GDBStubUpdate(stub); - } while (stub->d.state == DEBUGGER_PAUSED); + if (!SOCKET_FAILED(stub->connection) && !SocketSetBlocking(stub->connection, false)) { + GDBStubHangup(stub); + return; + } + } + GDBStubUpdate(stub); +} + +static void _gdbStubWait(struct ARMDebugger* debugger) { + struct GDBStub* stub = (struct GDBStub*) debugger; + if (!stub->shouldBlock) { + stub->shouldBlock = true; + if (!SocketSetBlocking(stub->socket, true)) { + GDBStubHangup(stub); + return; + } + if (!SOCKET_FAILED(stub->connection) && !SocketSetBlocking(stub->connection, true)) { + GDBStubHangup(stub); + return; + } + } + GDBStubUpdate(stub); } static void _ack(struct GDBStub* stub) {

@@ -170,6 +194,7 @@ }

static void _continue(struct GDBStub* stub, const char* message) { stub->d.state = DEBUGGER_CUSTOM; + stub->untilPoll = GDB_STUB_INTERVAL; if (!SOCKET_FAILED(stub->connection)) { if (!SocketSetBlocking(stub->connection, 0)) { GDBStubHangup(stub);

@@ -441,10 +466,11 @@ stub->socket = INVALID_SOCKET;

stub->connection = INVALID_SOCKET; stub->d.init = 0; stub->d.deinit = _gdbStubDeinit; - stub->d.paused = _gdbStubPoll; + stub->d.paused = _gdbStubWait; stub->d.entered = _gdbStubEntered; stub->d.custom = _gdbStubPoll; stub->d.log = 0; + stub->untilPoll = GDB_STUB_INTERVAL; } int GDBStubListen(struct GDBStub* stub, int port, const struct Address* bindAddress) {

@@ -460,9 +486,6 @@ return 0;

} int err = SocketListen(stub->socket, 1); if (err) { - goto cleanup; - } - if (!SocketSetBlocking(stub->socket, 0)) { goto cleanup; }

@@ -502,9 +525,6 @@ }

if (stub->connection == INVALID_SOCKET) { stub->connection = SocketAccept(stub->socket, 0); if (!SOCKET_FAILED(stub->connection)) { - if (!SocketSetBlocking(stub->connection, 0)) { - goto connectionLost; - } ARMDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED); } else if (errno == EWOULDBLOCK || errno == EAGAIN) { return;
M src/debugger/gdb-stub.hsrc/debugger/gdb-stub.h

@@ -13,6 +13,7 @@

#include "util/socket.h" #define GDB_STUB_MAX_LINE 1200 +#define GDB_STUB_INTERVAL 32 enum GDBStubAckState { GDB_ACK_PENDING = 0,

@@ -30,6 +31,9 @@ enum GDBStubAckState lineAck;

Socket socket; Socket connection; + + bool shouldBlock; + int untilPoll; }; void GDBStubCreate(struct GDBStub*);
M src/util/socket.hsrc/util/socket.h

@@ -157,7 +157,7 @@ static inline int SocketClose(Socket socket) {

return close(socket) >= 0; } -static inline int SocketSetBlocking(Socket socket, int blocking) { +static inline int SocketSetBlocking(Socket socket, bool blocking) { #ifdef _WIN32 u_long unblocking = !blocking; return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR;