NationalSecurityAgency/ghidra · error · RuntimeException
Failed to read memory
Error message
Failed to read memory
What it means
Ghidra DebuggerReadsMemoryTrait wraps the result of target.readMemoryAsync(sel, monitor).get(). If the future completes exceptionally (ExecutionException) or the waiting thread is interrupted (InterruptedException), the task throws RuntimeException("Failed to read memory", e). This typically reflects a backend/target communication failure during a memory-read action.
Source
Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/gui/action/DebuggerReadsMemoryTrait.java:89
if (!current.isAliveAndReadsPresent()) {
return;
}
AddressSetView selection = getSelection();
if (selection == null || selection.isEmpty()) {
selection = visible;
}
final AddressSetView sel = selection;
Target target = current.getTarget();
TargetActionTask.executeTask(tool, new Task(NAME, true, true, false) {
@Override
public void run(TaskMonitor monitor) throws CancelledException {
target.invalidateMemoryCaches();
try {
target.readMemoryAsync(sel, monitor).get();
}
catch (InterruptedException | ExecutionException e) {
throw new RuntimeException("Failed to read memory", e);
}
memoryWasRead(sel);
}
});
}
@Override
public boolean isEnabledForContext(ActionContext context) {
return current.isAliveAndReadsPresent();
}
public void updateEnabled(ActionContext context) {
setEnabled(isEnabledForContext(context));
}
}
protected class ForReadsTraceListener extends TraceDomainObjectListener {
public ForReadsTraceListener() {View on GitHub (pinned to d5f144c24d)
Solutions
- Confirm the target is still alive and connected before issuing the read (current.isAliveAndReadsPresent()).
- Narrow the selection to known-mapped, accessible memory regions.
- Reattach/reconnect to the target if the transport dropped, then retry.
- Catch RuntimeException around the action and inspect getCause() to distinguish cancellation from a transport error.
Example fix
// before
target.readMemoryAsync(sel, monitor).get(); // propagates as RuntimeException("Failed to read memory")
// after
try {
target.readMemoryAsync(sel, monitor).get();
} catch (ExecutionException ee) {
Msg.error(this, "Target read failed: " + ee.getCause());
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!current.isAliveAndReadsPresent()) {
// target not usable for reads; abort the action
return;
} Try / catch
try {
target.readMemoryAsync(sel, monitor).get();
} catch (ExecutionException ee) {
Msg.error(this, "read failed", ee.getCause());
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
} Prevention
- Check current.isAliveAndReadsPresent() before issuing reads.
- Narrow selections to mapped, accessible ranges.
- Inspect getCause() of the wrapped RuntimeException to diagnose transport vs cancellation.
When it happens
Trigger: Invoking the read-memory action on a selection when the debug target's readMemoryAsync fails — e.g., the target process died, the connection dropped, the address range is unreadable, or the task was cancelled/interrupted.
Common situations: Target process terminated mid-read; debugger backend connection lost; reading an address range not mapped/accessible; user cancellation racing with the read.
Related errors
- Unsupported value: {}
- Invalid value for {}
- No such address space: %s
- Current trace does not use Sleigh
- Cannot convert '{address}' to address
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/6de0480c4ae034db.
Report an issue: GitHub.