NationalSecurityAgency/ghidra · error · IllegalArgumentException

Length would cause address overflow in trace

Error message

Length would cause address overflow in trace

What it means

addMapping() validates that fromAddress + (length-1) does not exceed the maximum address of the source trace's address space (unsigned comparison). If length would run the source range past the trace space's max address, it throws IllegalArgumentException("Length would cause address overflow in trace"). The length is interpreted as an unsigned byte count.

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/modules/DebuggerStaticMappingUtils.java:128

			boolean truncateExisting) throws TraceConflictedMappingException {
		Program tp = to.getProgram();
		if (tp instanceof TraceProgramView) {
			throw new IllegalArgumentException(
				"Mapping destination cannot be a " + TraceProgramView.class.getSimpleName());
		}
		TraceStaticMappingManager manager = from.getTrace().getStaticMappingManager();
		URL toURL = ProgramURLUtils.getUrlFromProgram(tp);
		if (toURL == null) {
			noProject(DebuggerStaticMappingUtils.class);
		}
		Address fromAddress = from.getAddress();
		Address toAddress = to.getByteAddress();
		long maxFromLengthMinus1 =
			fromAddress.getAddressSpace().getMaxAddress().subtract(fromAddress);
		long maxToLengthMinus1 =
			toAddress.getAddressSpace().getMaxAddress().subtract(toAddress);
		if (Long.compareUnsigned(length - 1, maxFromLengthMinus1) > 0) {
			throw new IllegalArgumentException("Length would cause address overflow in trace");
		}
		if (Long.compareUnsigned(length - 1, maxToLengthMinus1) > 0) {
			throw new IllegalArgumentException("Length would cause address overflow in program");
		}
		Address end = fromAddress.addWrap(length - 1);
		// Also check end in the destination
		AddressRangeImpl range = new AddressRangeImpl(fromAddress, end);
		Lifespan fromLifespan = from.getLifespan();
		if (truncateExisting) {
			long truncEnd = fromLifespan.lmin() - 1;
			for (TraceStaticMapping existing : List
					.copyOf(manager.findAllOverlapping(range, fromLifespan))) {
				existing.delete();
				if (fromLifespan.minIsFinite() &&
					Lifespan.DOMAIN.compare(existing.getStartSnap(), truncEnd) <= 0) {
					manager.add(existing.getTraceAddressRange(),
						Lifespan.span(existing.getStartSnap(), truncEnd),
						existing.getStaticProgramURL(), existing.getStaticAddress());

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Clamp length so fromAddress + (length-1) stays within fromAddress.getAddressSpace().getMaxAddress().
  2. Recompute length as a correct unsigned byte count (toAddress/end - fromAddress/start + 1) and verify against the space maximum.
  3. If you intended a partial range, intersect the desired range with the trace address space before calling addMapping.

Example fix

// before
long length = moduleEnd - moduleStart; // possibly off / huge
DebuggerStaticMappingUtils.addMapping(from, to, length, false);

// after
Address maxFrom = from.getAddress().getAddressSpace().getMaxAddress();
long maxLen = maxFrom.subtract(from.getAddress()) + 1;
long length = Math.min(desiredLength, maxLen);
DebuggerStaticMappingUtils.addMapping(from, to, length, false);
Defensive patterns

Strategy: validation

Validate before calling

// Clamp length to the source trace address space before addMapping
Address fromAddr = from.getAddress();
long maxLenFrom = fromAddr.getAddressSpace().getMaxAddress().subtract(fromAddr) + 1;
long safeLength = Math.min(length, maxLenFrom);
if (Long.compareUnsigned(length - 1, maxLenFrom - 1) > 0) {
    length = safeLength; // or throw with a clear message
}

Type guard

public static boolean lengthFitsTrace(Address fromAddr, long length) {
    long maxLen = fromAddr.getAddressSpace().getMaxAddress().subtract(fromAddr) + 1;
    return Long.compareUnsigned(length, maxLen) <= 0;
}

Try / catch

try {
    DebuggerStaticMappingUtils.addMapping(from, to, length, false);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("overflow in trace")) {
        long maxLen = from.getAddress().getAddressSpace().getMaxAddress()
            .subtract(from.getAddress()) + 1;
        DebuggerStaticMappingUtils.addMapping(from, to, Math.min(length, maxLen), false);
    } else throw e;
}

Prevention

When it happens

Trigger: Passing a very large length (or a length computed from a wrong unit, e.g. an address offset instead of a byte count). Mapping near the top of a small address space with a length that wraps past max. Negative length interpreted as a huge unsigned value.

Common situations: Computing length as end.subtract(start) without subtracting/adding correctly, yielding an off-by-one overflow. Mapping whole segments whose declared length exceeds the trace space. Using a module length that includes padding beyond the space.

Related errors


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