bool GDBStubListen(struct GDBStub* stub, int port, const struct Address* bindAddress) { if (!SOCKET_FAILED(stub->socket)) { GDBStubShutdown(stub); } stub->socket = SocketOpenTCP(port, bindAddress); if (SOCKET_FAILED(stub->socket)) { mLOG(DEBUGGER, ERROR, "Couldn't open socket"); return false; } if (!SocketSetBlocking(stub->socket, false)) { goto cleanup; } int err = SocketListen(stub->socket, 1); if (err) { goto cleanup; } return true; cleanup: mLOG(DEBUGGER, ERROR, "Couldn't listen on port"); SocketClose(stub->socket); stub->socket = INVALID_SOCKET; return false; }
static bool _mPerfRunServer(const char* listen, const struct mArguments* args, const struct PerfOpts* perfOpts) { SocketSubsystemInit(); Socket server = SocketOpenTCP(7216, NULL); if (SOCKET_FAILED(server)) { SocketSubsystemDeinit(); return false; } if (SOCKET_FAILED(SocketListen(server, 0))) { SocketClose(server); SocketSubsystemDeinit(); return false; } _socket = SocketAccept(server, NULL); if (perfOpts->csv) { const char* header = "game_code,frames,duration,renderer\n"; SocketSend(_socket, header, strlen(header)); } char path[PATH_MAX]; while (SocketRecv(_socket, path, sizeof(path)) > 0) { char* nl = strchr(path, '\n'); if (nl == path) { break; } if (nl) { nl[0] = '\0'; } if (!_mPerfRunCore(path, args, perfOpts)) { break; } } SocketClose(_socket); SocketClose(server); SocketSubsystemDeinit(); return true; }
void GDBStubShutdown(struct GDBStub* stub) { GDBStubHangup(stub); if (!SOCKET_FAILED(stub->socket)) { SocketClose(stub->socket); stub->socket = INVALID_SOCKET; } }
void GDBStubHangup(struct GDBStub* stub) { if (!SOCKET_FAILED(stub->connection)) { SocketClose(stub->connection); stub->connection = INVALID_SOCKET; } if (stub->d.state == DEBUGGER_PAUSED) { stub->d.state = DEBUGGER_RUNNING; } }
void GDBStubUpdate(struct GDBStub* stub) { if (stub->socket == INVALID_SOCKET) { if (stub->d.state == DEBUGGER_PAUSED) { stub->d.state = DEBUGGER_RUNNING; } return; } if (stub->connection == INVALID_SOCKET) { if (stub->shouldBlock) { Socket reads = stub->socket; SocketPoll(1, &reads, 0, 0, SOCKET_TIMEOUT); } stub->connection = SocketAccept(stub->socket, 0); if (!SOCKET_FAILED(stub->connection)) { if (!SocketSetBlocking(stub->connection, false)) { goto connectionLost; } mDebuggerEnter(&stub->d, DEBUGGER_ENTER_ATTACHED, 0); } else if (SocketWouldBlock()) { return; } else { goto connectionLost; } } while (true) { if (stub->shouldBlock) { Socket reads = stub->connection; SocketPoll(1, &reads, 0, 0, SOCKET_TIMEOUT); } ssize_t messageLen = SocketRecv(stub->connection, stub->line, GDB_STUB_MAX_LINE - 1); if (messageLen == 0) { goto connectionLost; } if (messageLen == -1) { if (SocketWouldBlock()) { return; } goto connectionLost; } stub->line[messageLen] = '\0'; mLOG(DEBUGGER, DEBUG, "< %s", stub->line); ssize_t position = 0; while (position < messageLen) { position += _parseGDBMessage(stub, &stub->line[position]); } } connectionLost: mLOG(DEBUGGER, WARN, "Connection lost"); GDBStubHangup(stub); }
static void _gdbStubDeinit(struct mDebugger* debugger) { struct GDBStub* stub = (struct GDBStub*) debugger; if (!SOCKET_FAILED(stub->socket)) { GDBStubShutdown(stub); } }