NationalSecurityAgency/ghidra · warning · DecompileException

interrupted:

Error message

interrupted: 

What it means

Thrown by ParallelDecompileTask.decompile when the decompile worker thread is interrupted (InterruptedException). It wraps the interruption as a DecompileException with source 'interrupted' and the interrupt's message. This typically indicates an external cancellation or shutdown of the parallel decompile pool rather than a logic error.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ParallelDecompileTask.java:58

	// save for shutting down abnormally
	private DecompilerConcurrentQ<Function, Function> queue;

	public ParallelDecompileTask(Program prog, TaskMonitor mon, DecompileFunctionTask ftask) {
		program = prog;
		if (mon != null)
			taskMonitor = mon;
		ftask_template = ftask;

		ftask_template.initializeGlobal(program);
	}

	public void decompile(Iterator<Function> iter, int functionCount) throws DecompileException {
		try {
			doDecompile(iter, functionCount);
		}
		catch (InterruptedException e) {
			Msg.error(this, "Problem with decompiler worker thread", e);
			throw new DecompileException("interrupted", e.getMessage());
		}
		catch (Exception t) {
			Msg.error(this, "Problem with decompiler worker thread", t);
			DecompileException decompileException =
				new DecompileException("execution", t.getMessage());
			decompileException.initCause(t);
			throw decompileException;
		}
	}

	private void doDecompile(Iterator<Function> iter, int functionCount)
			throws InterruptedException, Exception {
		taskMonitor.setMessage("Analyzing functions...");
		taskMonitor.initialize(functionCount);

		CachingPool<DecompileFunctionTask> decompilerPool =
			new CachingPool<DecompileFunctionTask>(new DecompilerTaskFactory(ftask_template));
		QCallback<Function, Function> callback = new ParallelDecompilerCallback(decompilerPool);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Treat this as a cancellation, not a defect: check whether the operation was intentionally cancelled (monitor.isCancelled()).
  2. If unexpected, ensure nothing is prematurely interrupting the decompiler worker threads (e.g. an overly aggressive timeout).
  3. Restore the interrupt status in your handler if you swallow it: Thread.currentThread().interrupt().
  4. Clean up partial decompiler resources and report the cancellation to the user.

Example fix

// before
catch (InterruptedException e) {
    throw new DecompileException("interrupted", e.getMessage());
}
// after
catch (InterruptedException e) {
    Thread.currentThread().interrupt(); // restore interrupt status
    throw new DecompileException("interrupted", "decompile cancelled");
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    parallelTask.decompile(iter, functionCount);
} catch (DecompileException e) {
    if ("interrupted".equals(e.getSource())) {
        log.info("Decompile was interrupted/cancelled");
        Thread.currentThread().interrupt(); // restore flag
        // handle cancellation gracefully (cleanup + report)
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: doDecompile throws InterruptedException because a worker thread was interrupted: the user cancelled the operation, the TaskMonitor was cancelled, a timeout fired, or the JVM/application is shutting down the decompiler threads.

Common situations: User cancels a long-running BSim signature generation job. A TaskMonitor cancellation propagates as an interrupt. Thread pool shutdown during application exit. An explicit timeout/cancel from a higher-level orchestration layer.

Related errors


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