NationalSecurityAgency/ghidra · error · AddressOutOfBoundsException
Range [%s:%x+%x] entirely exceeds space min
Error message
Range [%s:%x+%x] entirely exceeds space min
What it means
Thrown by OpenTrace.toRange when translating a client-supplied AddrRange into an AddressRange. The method clamps a range whose start or end partially falls outside the address space, but if the range's computed end (offset+extend) is strictly below the space's minimum address offset, the whole range is entirely below the space and cannot be represented, so it throws AddressOutOfBoundsException. The %s:%x+%x placeholders report the space name, offset, and extend length of the offending range.
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/OpenTrace.java:174
*/
long minOffset = range.getOffset();
if (Long.compareUnsigned(minOffset, space.getMinAddress().getOffset()) < 0) {
Msg.warn(this, "Range [%s:%x+%x] partially exceeds space min. Clamping."
.formatted(range.getSpace(), range.getOffset(), range.getExtend()));
minOffset = space.getMinAddress().getOffset();
}
else if (Long.compareUnsigned(minOffset, space.getMaxAddress().getOffset()) > 0) {
throw new AddressOutOfBoundsException("Range [%s:%x+%x] entirely exceeds space max"
.formatted(range.getSpace(), range.getOffset(), range.getExtend()));
}
long maxOffset = range.getOffset() + range.getExtend(); // Use the requested offset, not adjusted
if (Long.compareUnsigned(maxOffset, space.getMaxAddress().getOffset()) > 0) {
Msg.warn(this, "Range [%s:%x+%x] partially exceeds space max. Clamping."
.formatted(range.getSpace(), range.getOffset(), range.getExtend()));
maxOffset = space.getMaxAddress().getOffset();
}
else if (Long.compareUnsigned(maxOffset, space.getMinAddress().getOffset()) < 0) {
throw new AddressOutOfBoundsException("Range [%s:%x+%x] entirely exceeds space min"
.formatted(range.getSpace(), range.getOffset(), range.getExtend()));
}
Address min = space.getAddress(minOffset);
Address max = space.getAddress(maxOffset);
return new AddressRangeImpl(min, max);
}
public Register getRegister(String name, boolean required) {
Register register = trace.getBaseLanguage().getRegister(name);
if (required && register == null) {
throw new InvalidRegisterError(name);
}
return register;
}
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Validate offset and extend against the space bounds before sending the range: ensure offset+extend (unsigned) >= space min and offset (unsigned) <= space max.
- Guard against extend that would make offset+extend wrap around unsigned; cap extend at the space's max address minus the offset.
- Confirm the AddressSpace name sent by the client exists in the trace's language/compiler spec and that its min/max match the backend's view.
- Check that you are not passing a zero or negative extend length when the space minimum is above zero.
Example fix
// before
long maxOffset = offset + extend; // can wrap
AddrRange range = AddrRange.newBuilder().setSpace("ram").setOffset(offset).setExtend(extend).build();
// after
long spaceMin = space.getMinAddress().getOffset();
long spaceMax = space.getMaxAddress().getOffset();
if (Long.compareUnsigned(offset, spaceMin) < 0 ||
Long.compareUnsigned(offset + extend, spaceMin) < 0 ||
Long.compareUnsigned(offset, spaceMax) > 0) {
throw new IllegalArgumentException("range outside space bounds");
} Defensive patterns
Strategy: validation
Validate before calling
long spaceMin = space.getMinAddress().getOffset();
long spaceMax = space.getMaxAddress().getOffset();
long minOffset = range.getOffset();
long maxOffset = range.getOffset() + range.getExtend();
if (Long.compareUnsigned(minOffset, spaceMax) > 0 ||
Long.compareUnsigned(maxOffset, spaceMin) < 0) {
throw new IllegalArgumentException(
"range entirely outside space " + range.getSpace());
} Try / catch
try {
AddressRange r = openTrace.toRange(range, true);
} catch (AddressOutOfBoundsException e) {
// range entirely outside the space; reject or skip the operation
} Prevention
- Always compute maxOffset as offset+extend and compare unsigned against space min/max before sending.
- Guard extend against unsigned wrap-around by capping at (spaceMax - offset).
- Confirm the client and trace agree on the address space name and its bounds.
When it happens
Trigger: A TraceRmi client sends a memory/register range (e.g. via a setValue, putBytes, or memory-state request) whose offset+extend, treated as unsigned, is less than the target AddressSpace.getMinAddress().getOffset(). This can occur when the extend causes a 64-bit unsigned wrap-around (overflow) or when the client sends a near-zero offset for a space whose minimum is high.
Common situations: Client computes extend incorrectly and wraps past zero; a debugger backend reports a range for an address space whose bounds differ from the trace's language definition; mismatched register/memory space between backend and Ghidra language; using a negative extend or zero-length range that lands below the space floor.
Related errors
- No such address space: %s
- Return address must be in {}
- Return address must be in {}
- No saved offers to launch {}
- Trace is not from this connection
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/49f59447a3efbfc6.
Report an issue: GitHub.