NationalSecurityAgency/ghidra · error · CodeUnitInsertionException

Code units cannot overlap

Error message

Code units cannot overlap

What it means

Thrown by DBTraceInstructionsView.doCreate() when the address range for the new instruction (after lifespan truncation via computeTruncatedMax) overlaps with an existing defined code unit in the trace. The check is space.undefinedData.coversRange(tasr) returning false, meaning some portion of the range is already occupied by a defined code unit. This is a CodeUnitInsertionException (checked), the standard Ghidra exception for code unit conflicts.

Source

Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceInstructionsView.java:382

		if (platform.getLanguage() != prototype.getLanguage()) {
			throw new IllegalArgumentException("Platform and prototype disagree in language");
		}

		int forcedLengthOverride = InstructionDB.checkLengthOverride(length, prototype);
		if (length == 0) {
			length = prototype.getLength();
		}
		Address endAddress = address.addNoWrap(length - 1);
		AddressRangeImpl createdRange = new AddressRangeImpl(address, endAddress);

		// Truncate, then check that against existing code units.
		long endSnap = computeTruncatedMax(lifespan, null, createdRange);
		TraceAddressSnapRange tasr =
			new ImmutableTraceAddressSnapRange(createdRange, lifespan.withMax(endSnap));

		if (!space.undefinedData.coversRange(tasr)) {
			// TODO: Figure out the conflicting unit or snap boundary?
			throw new CodeUnitInsertionException("Code units cannot overlap");
		}

		doSetContext(tasr, prototype.getLanguage(), context);

		DBTraceInstruction created = space.instructionMapSpace.put(tasr, null);
		created.set(platform, prototype, context, forcedLengthOverride);

		cacheForContaining.notifyNewEntry(tasr.getLifespan(), createdRange, created);
		cacheForSequence.notifyNewEntry(tasr.getLifespan(), createdRange, created);
		space.undefinedData.invalidateCache();

		// TODO: Save the context register into the context manager? Flow it?
		// TODO: Ensure cached undefineds don't extend into defined stuff
		// TODO: Explicitly remove undefined from cache, or let weak refs take care of it?
		return created;
	}

	@Override

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Before creating the instruction, check for existing code units at the target address via space.definedUnits.getContaining(snap, address) and clear them if appropriate.
  2. Use a Lifespan that does not overlap with existing code units — create the instruction at a different snap range.
  3. Call trace.getCodeManager().instructionAt(snap, addr) to check for conflicts first.
  4. Catch CodeUnitInsertionException and handle the conflict by clearing the existing unit or adjusting the address.

Example fix

// before
DBTraceInstruction instr = view.create(lifespan, addr, platform, proto, ctx, 0);

// after
CodeUnit existing = space.definedUnits.getContaining(lifespan.lmin(), addr);
if (existing != null) {
    existing.delete(); // or choose a different address
}
DBTraceInstruction instr = view.create(lifespan, addr, platform, proto, ctx, 0);
Defensive patterns

Strategy: try-catch

Validate before calling

// Check for existing code units before creating
CodeUnit existing = space.definedUnits
    .getContaining(lifespan.lmin(), address);
if (existing != null) {
    // conflict; clear existing or choose different address
}

Try / catch

try {
    DBTraceInstruction instr = view.create(lifespan, address, platform, proto, ctx, len);
} catch (CodeUnitInsertionException e) {
    // overlap detected; clear the conflicting unit or adjust the range
    CodeUnit conflict = space.definedUnits.getContaining(lifespan.lmin(), address);
    if (conflict != null) conflict.delete();
    // retry creation
}

Prevention

When it happens

Trigger: Calling create() to place an instruction at an address range [address, address+length-1] that intersects an already-defined instruction or data unit in the same address space and lifespan. For example, disassembling an address that already has a data type or instruction defined at that snap range.

Common situations: Running disassembly twice on overlapping ranges. Creating a data unit and then trying to create an instruction in the same address range. Importing code blocks that overlap existing definitions in the trace.

Related errors


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