NationalSecurityAgency/ghidra · error · IOException
GNU disassembler process died unexpectedly.
Error message
GNU disassembler process died unexpectedly.
What it means
After reading back the full disassembly result loop, GNUExternalDisassembler checks disassemblerProcess.isAlive() and throws if the gdis process has terminated during the read. Unlike [641] which catches the IOException during write/read, this fires when the read loop completed without exception but the process is no longer running — indicating it died mid-response (possibly after emitting partial data). This signals the external disassembler is in a bad state and future calls will fail.
Source
Thrown at Ghidra/Extensions/SleighDevTools/src/main/java/ghidra/app/util/disassemble/GNUExternalDisassembler.java:672
String instructionMetadataLine = buffReader.readLine();
if (!instructionMetadataLine.startsWith("Info: ")) {
// TODO, throw an "ExternalDisassemblerInterfaceException"
// or some such
error = true; // still need to consume remainder of input
continue;
}
String[] metadata = instructionMetadataLine.substring("Info: ".length()).split(",");
results.add(new GnuDisassembledInstruction(instructionLine.replace('\t', ' '),
Integer.parseInt(metadata[0]), "1".equals(metadata[1]),
Integer.parseInt(metadata[2]), Integer.parseInt(metadata[3]),
Integer.parseInt(metadata[4])));
}
}
while (instructionLine != null && !instructionLine.equals(ENDING_STRING));
if (!disassemblerProcess.isAlive()) {
throw new IOException("GNU disassembler process died unexpectedly.");
}
if (error) {
return null;
}
return results;
}
private String getBytes(ByteProvider byteProvider, int size) throws IOException {
StringBuffer byteString = new StringBuffer();
for (int i = 0; i < size; i++) {
byteString.append(formatHexString(byteProvider.readByte(i)));
}
return byteString.toString();
}
private String getBytes(MemBuffer mem, int size) {View on GitHub (pinned to d5f144c24d)
Solutions
- Check OS-level logs (dmesg, syslog) for evidence of the gdis process being killed (OOM, signal).
- Run the gdis binary manually with the same input bytes to reproduce the crash and capture its stderr/exit code.
- Restart the disassembler session or reload the configuration to spawn a fresh gdis process.
- If the crash is input-specific, skip or annotate the problematic address range and continue disassembly elsewhere.
- Update or rebuild the gdis tool if the crash indicates a binary bug.
Defensive patterns
Strategy: retry
Validate before calling
// Check process liveness before relying on results
if (!disassemblerProcess.isAlive()) {
// Process died — do not trust partial results
throw new IOException("GNU disassembler process is not alive before read.");
} Try / catch
try {
return getDisassembledInstruction();
} catch (IOException e) {
if (e.getMessage().contains("died unexpectedly")) {
restartDisassembler();
return getDisassembledInstruction(); // single retry
}
throw e;
} Prevention
- Check process liveness before AND after the read loop to detect mid-response death.
- Capture gdis stderr output to a log for post-crash diagnosis.
- Resource-limit the gdis process (ulimit) to prevent it from consuming all host memory.
- Test new gdis binaries against known-crashing instruction sequences before deployment.
When it happens
Trigger: Reaching the post-loop check in getDisassembledInstruction() where instructionLine reached ENDING_STRING or null, but disassemblerProcess.isAlive() returns false. The read loop exited normally but the process exited during or right after the read.
Common situations: The gdis process hit a fatal error on the current instruction and exited after writing a partial/terminal response; the OS killed the process (OOM killer, resource limits) between the write and the read completion; a signal was delivered to the child process; the gdis binary has a bug causing crash on certain valid instruction encodings.
Related errors
- gdis execution error
- Usage: %s target-str, arch, mach, disassembly base-addr (for
- exiting, no ASCII hex found\n
- Max ascii string size is %d you provided: %lu chars. Exiting
- need even-number of ascii chars for byte-stream: (offset: %0
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/ad9801c5ccf37d2d.
Report an issue: GitHub.