Debugger: Clean up GDB stub network interfacing
Jeffrey Pfau jeffrey@endrift.com
Fri, 16 Jan 2015 00:50:15 -0800
4 files changed,
41 insertions(+),
16 deletions(-)
M
CHANGES
→
CHANGES
@@ -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.c
→
src/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.h
→
src/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.h
→
src/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;