NationalSecurityAgency/ghidra · error · MemoryAccessException
Failed to read {len} bytes at {addr}
Error message
Failed to read {len} bytes at {addr} What it means
Thrown by DBTraceInstruction.getParsedBytes() when the instruction has a length override (isLengthOverridden() is true) and the trace memory cannot supply the prototype's expected number of bytes at the instruction's address. The method reads len bytes (from getPrototype().getLength()) via getMemory().getBytes(addr, b) and if the returned count differs from len, a MemoryAccessException is raised. This is a checked exception, signalling that the backing memory for this instruction is missing, partially initialized, or has been truncated in the trace database.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceInstruction.java:654
public int getParsedLength() {
if (lengthOverride == 0) {
return super.getLength();
}
return getPrototype().getLength();
}
@Override
public byte[] getParsedBytes() throws MemoryAccessException {
if (!isLengthOverridden()) {
return getBytes();
}
try (LockHold hold = LockHold.lock(space.lock.readLock())) {
refreshIfNeeded();
int len = getPrototype().getLength();
byte[] b = new byte[len];
Address addr = getAddress();
if (len != getMemory().getBytes(addr, b)) {
throw new MemoryAccessException("Failed to read " + len + " bytes at " + addr);
}
return b;
}
}
@Override
public void setFallThrough(Address fallThrough) {
try (LockHold hold = space.trace.lockWrite()) {
checkDeleted();
Address defaultFallThrough = prototype.getFallThrough(this);
if (Objects.equals(fallThrough, defaultFallThrough)) {
clearFallThroughOverride();
return;
}
if (fallThrough == null) {
clearFallThroughRefs(null);
setFallThroughOverridden(true);
}View on GitHub (pinned to d5f144c24d)
Solutions
- Ensure the trace memory at the instruction's address and snap is fully recorded before calling getParsedBytes() — write bytes via TraceMemorySpace.putBytes() first.
- Check the instruction's memory state with getState(snap) == TraceMemoryState.KNOWN before requesting parsed bytes.
- If length override is unnecessary, avoid setting it so getParsedBytes() delegates to getBytes() which may handle partial reads differently.
- Wrap the call in try-catch for MemoryAccessException and fall back to getBytes() or skip the instruction if memory is unavailable.
Example fix
// before
byte[] parsed = instruction.getParsedBytes();
// after
if (instruction.isLengthOverridden() &&
memory.getState(instruction.getStartSnap(), instruction.getAddress()) != TraceMemoryState.KNOWN) {
// populate or skip
} else {
byte[] parsed = instruction.getParsedBytes();
} Defensive patterns
Strategy: validation
Validate before calling
// Before calling getParsedBytes(), check memory state and length
TraceMemorySpace mem = instruction.getMemory();
long snap = instruction.getStartSnap();
Address addr = instruction.getAddress();
if (mem.getState(snap, addr) != TraceMemoryState.KNOWN) {
// memory not available; handle gracefully
return;
}
int expectedLen = instruction.getPrototype().getLength();
// optionally verify bytes are readable
byte[] test = new byte[expectedLen];
if (mem.getBytes(addr, test) != expectedLen) {
// insufficient bytes
return;
} Try / catch
try {
byte[] parsed = instruction.getParsedBytes();
} catch (MemoryAccessException e) {
// memory unavailable for this instruction's snap
// fall back to getBytes() or skip
logger.warning("No parsed bytes at " + instruction.getAddress() + ": " + e.getMessage());
} Prevention
- Always record memory for instruction addresses before accessing parsed bytes.
- Check TraceMemoryState.KNOWN before calling getParsedBytes().
- Avoid unnecessary length overrides that may exceed available memory.
When it happens
Trigger: Calling getParsedBytes() on a DBTraceInstruction whose isLengthOverridden() returns true, when the underlying trace memory space does not contain enough bytes at the instruction's address. This occurs when memory state at the relevant snap is UNKNOWN or only partially written, or when the instruction was created with a forced length override that exceeds available memory.
Common situations: During debugger/emulator trace replay when memory was never recorded for the instruction's snap. After importing a partial trace where code units reference memory regions that were not captured. When an instruction's length was overridden to a value larger than the recorded memory block.
Related errors
- Trace does not contain referenced instruction: ({getStartSna
- Instruction has incompatible prototype at: ({getStartSnap},{
- Code units cannot overlap
- Code unit would extend beyond address space
- Platform and prototype disagree in language
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/c317ee412003476a.
Report an issue: GitHub.