mirror of https://github.com/mgba-emu/mgba.git
Debugger: Clean up GDB stub network interfacing
This commit is contained in:
parent
69fb4e4c7b
commit
56d5fb579d
1
CHANGES
1
CHANGES
|
@ -75,6 +75,7 @@ Misc:
|
|||
- 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
|
||||
|
|
|
@ -53,15 +53,39 @@ static void _gdbStubEntered(struct ARMDebugger* debugger, enum DebuggerEntryReas
|
|||
|
||||
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 _writeHostInfo(struct GDBStub* stub) {
|
|||
|
||||
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 @@ void GDBStubCreate(struct GDBStub* stub) {
|
|||
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) {
|
||||
|
@ -462,9 +488,6 @@ int GDBStubListen(struct GDBStub* stub, int port, const struct Address* bindAddr
|
|||
if (err) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (!SocketSetBlocking(stub->socket, 0)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
|
@ -502,9 +525,6 @@ void GDBStubUpdate(struct GDBStub* stub) {
|
|||
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;
|
||||
|
|
|
@ -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 @@ struct GDBStub {
|
|||
|
||||
Socket socket;
|
||||
Socket connection;
|
||||
|
||||
bool shouldBlock;
|
||||
int untilPoll;
|
||||
};
|
||||
|
||||
void GDBStubCreate(struct GDBStub*);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue