NationalSecurityAgency/ghidra · error · AccessPcodeExecutionException

Timed out reading or writing target

Error message

Timed out reading or writing target

What it means

DebuggerEmulationIntegration.waitTimeout() wraps an asynchronous target memory read/write in future.get(1, TimeUnit.SECONDS). If the target does not respond within that hard-coded one second, the TimeoutException is rethrown as AccessPcodeExecutionException("Timed out reading or writing target"). This fires during p-code emulation when a memory piece is configured to redirect reads/writes to the live target (e.g. bytesImmediateWriteTarget / bytesWriteMode with Mode.RW).

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/DebuggerEmulationIntegration.java:132

	 * directly with a {@link PcodeExecutorState} vice a {@link PcodeEmulator}.
	 * 
	 * @see TraceEmulationIntegration#bytesImmediateWrite(PcodeTraceAccess, TraceThread, int)
	 * @param access the access shim for loads and stores
	 * @param thread the trace thread for register accesses
	 * @param frame the frame for register accesses, usually 0
	 * @return the callbacks
	 */
	public static PcodeStateCallbacks bytesImmediateWriteTarget(PcodeDebuggerAccess access,
			TraceThread thread, int frame) {
		return bytesWriteMode(access, thread, frame, Mode.RW).wrapFor(null);
	}

	protected static <T> T waitTimeout(CompletableFuture<T> future) {
		try {
			return future.get(1, TimeUnit.SECONDS);
		}
		catch (TimeoutException e) {
			throw new AccessPcodeExecutionException("Timed out reading or writing target", e);
		}
		catch (InterruptedException | ExecutionException e) {
			throw new AccessPcodeExecutionException("Error reading or writing target", e);
		}
	}

	/**
	 * An extension/replacement of the {@link BytesPieceHandler} that may redirect reads and writes
	 * to/from the target.
	 * 
	 * @implNote Because piece handlers are keyed by (address-domain, value-domain), adding this to
	 *           a writer will replace the default handler.
	 */
	public static class TargetBytesPieceHandler extends BytesPieceHandler {
		protected final Mode mode;

		public TargetBytesPieceHandler(Mode mode) {
			this.mode = mode;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Keep the target responsive and not stopped on a synchronous operation while emulating (resume/continue the target so it services memory requests).
  2. Reduce target-touching during emulation by caching/warming the emulator memory so p-code execution does not need to round-trip to the target.
  3. Use an emulation mode that does not redirect to the target (read from trace/emulator state) instead of RW-to-target.
  4. Investigate the underlying target/debug-connector latency and increase throughput or move the target closer.

Example fix

// before: emulation redirects every byte access to a slow target
PcodeStateCallbacks cb = DebuggerEmulationIntegration.bytesImmediateWriteTarget(access, thread, frame);

// after: warm the emulator from the trace and avoid target round-trips,
// or ensure the target is running/responsive before emulating
access.getPcodeExecutor().getMemory().setState(...); // pre-load bytes
Defensive patterns

Strategy: try-catch

Validate before calling

// No pre-call validation; the timeout is internal. Mitigate by ensuring target responsiveness
// before emulating: confirm the target is running and not blocked.
if (!targetService.isTargetAlive(target)) {
    throw new IllegalStateException("Target unavailable; cannot emulate with target access");
}

Try / catch

try {
    executor.execute(injection);
} catch (AccessPcodeExecutionException e) {
    if (e.getMessage().contains("Timed out")) {
        // target too slow: warm emulator cache or avoid target-touching p-code
    } else throw e;
}

Prevention

When it happens

Trigger: Emulating a trace whose bytes piece handler is in RW mode (redirecting to target) while the target is slow, paused, or unresponsive. Calling p-code execution that touches a memory address not present in the emulator cache, forcing a synchronous target fetch through waitTimeout. A halted/disconnected target during emulation.

Common situations: Slow remote debug targets (GDB over network, traced targets under heavy load). Emulating large memory regions that trigger many target round-trips. Target stepping/breaking while an emulation step is in flight. Latency spikes on the debug connector exceeding the fixed 1s budget.

Understand the failure class

Related errors


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