{"record":{"id":"9cdaf5f13f5fe63e","repo":"NationalSecurityAgency/ghidra","slug":"socket-closed","errorCode":null,"errorMessage":"Socket closed","messagePattern":"Socket closed","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py","lineNumber":53,"sourceCode":"    send_length(s, size)\n    s.sendall(data)\n\n\ndef recv_all(s, size: int) -> bytes:\n    buf = b''\n    while len(buf) < size:\n        part = s.recv(size - len(buf))\n        if len(part) == 0:\n            return buf\n        buf += part\n    return buf\n    # return s.recv(size, socket.MSG_WAITALL)\n\n\ndef recv_length(s: socket.socket) -> int:\n    buf = recv_all(s, 4)\n    if len(buf) < 4:\n        raise Exception(\"Socket closed\")\n    return int.from_bytes(buf, 'big')\n\n\ndef recv_delimited(s: socket.socket, msg: M, dbg_seq: int) -> M:\n    size = recv_length(s)\n    if size > MAX_MSG_LENGTH:\n        raise TraceRmiError(\"Cannot receive TraceRmi message with excessive message length\")\n    buf = recv_all(s, size)\n    if len(buf) < size:\n        raise Exception(\"Socket closed\")\n    msg.ParseFromString(buf)\n    return msg\n","sourceCodeStart":35,"sourceCodeEnd":66,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/py/src/ghidratrace/util.py#L35-L66","documentation":"Raised as a generic Exception by recv_length() when recv_all() returns fewer than 4 bytes for the length-prefix, i.e. the peer closed the socket (recv returned 0) before sending a full 4-byte length word. It signals connection termination, not malformed data.","triggerScenarios":"The Ghidra TraceRmi server crashed or was killed mid-session; the remote debugger process exited; network reset; orderly shutdown by the peer.","commonSituations":"Remote trace target terminated; Ghidra closed; VPN/SSH tunnel dropped; server hit an exception and tore down the socket.","solutions":["Check that the Ghidra TraceRmi server/target is still running and reachable.","Catch the exception, log the disconnect, and re-establish the connection / re-open the trace.","Inspect server-side logs for the cause of the close."],"exampleFix":"# before\nclient = Client.connect(s)\n... use without guarding ...\n# after\ntry:\n    client = Client.connect(s)\nexcept Exception as e:\n    if str(e) == 'Socket closed':\n        log.warning('TraceRmi peer disconnected')\n        reconnect()\n    raise","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    size = recv_length(s)\nexcept Exception as e:\n    if str(e) == 'Socket closed':\n        handle_disconnect()\n    raise","preventionTips":["Monitor the TraceRmi server process.","Reconnect logic for long sessions."],"tags":["network","trace-rmi","connection","disconnect"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}