NationalSecurityAgency/ghidra · error · IOException

gdis execution error

Error message

gdis execution error

What it means

Thrown when the GNU external disassembler (gdis) process encounters an IOException while writing the disassembly request to the process's stdin or while reading back the result. The error wraps the underlying IOException. The code logs the last request that failed and then re-throws, forcing the caller to handle the broken pipe / I/O failure. A TODO comment notes the process is intentionally not destroyed to avoid repeated failures, so subsequent calls may also fail until the process recovers or the config is reloaded.

Source

Thrown at Ghidra/Extensions/SleighDevTools/src/main/java/ghidra/app/util/disassemble/GNUExternalDisassembler.java:639

			disassemblyRequest += '\n';
		}
		else {
			disassemblyRequest += OPTIONS_SEPARATOR + disassemblerOptions + SEPARATOR_CHARACTER;
		}

		try {
			outputWriter.write(disassemblyRequest);
			outputWriter.flush();
			return getDisassembledInstruction();
		}
		catch (IOException e) {
			// force a restart of the disassembler on next call to this function
			// TODO: Should we not do this to avoid repeated failure and severe slowdown?
			// User must exit or switch configs/programs to retry after failure
			//disassemblerProcess.destroy();
			//disassemblerProcess = null; // assumes process exit
			Msg.error(this, "Last gdis request failed: " + disassemblyRequest);
			throw new IOException("gdis execution error", e);
		}
	}

	private List<GnuDisassembledInstruction> getDisassembledInstruction() throws IOException {

		List<GnuDisassembledInstruction> results = new ArrayList<>();
		String instructionLine;

		boolean error = false;
		do {
			instructionLine = buffReader.readLine();
			if (!error && instructionLine != null && !instructionLine.equals(ENDING_STRING) &&
				(instructionLine.indexOf(ADDRESS_OUT_OF_BOUNDS) < 0) &&
				!instructionLine.startsWith("Usage:") && !instructionLine.startsWith("Debug:")) {

				String instructionMetadataLine = buffReader.readLine();
				if (!instructionMetadataLine.startsWith("Info: ")) {
					// TODO, throw an "ExternalDisassemblerInterfaceException"

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Check the application log for the preceding 'Last gdis request failed' message — it shows the exact request that broke the pipe.
  2. Verify the gdis executable path and version configured for this language match a working binary (run it manually with the same input).
  3. Restart the Ghidra session or switch/reload the disassembler configuration to force a fresh gdis process spawn.
  4. If the crash is reproducible, isolate the specific instruction bytes in the request and test them against gdis directly to find the offending input.
  5. Check system resources (memory, file descriptors) — native child processes may be killed by the OS under pressure.
Defensive patterns

Strategy: retry

Validate before calling

// Before sending a request, verify the process is alive
if (disassemblerProcess == null || !disassemblerProcess.isAlive()) {
    // restart the gdis process
    startDisassembler();
}

Try / catch

try {
    return disassemble(...);
} catch (IOException e) {
    if ("gdis execution error".equals(e.getMessage())) {
        // reset process state and retry once
        resetDisassemblerProcess();
        return disassemble(...);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling the disassembly method that writes disassemblyRequest to outputWriter and calls getDisassembledInstruction(); any IOException during outputWriter.write/flush or during the subsequent read triggers this. Commonly a broken pipe because the gdis process crashed between requests.

Common situations: The gdis binary crashed or was killed (OOM, segfault); the pipe between JVM and the native gdis process broke; the gdis executable is mismatched with the expected protocol version; the host system is under memory pressure causing the child process to die; a corrupt or unexpectedly long instruction stream causes gdis to error out and close its stdout.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/c71087941b8c01d6. Report an issue: GitHub.