{"record":{"id":"73d0b7b187795bce","repo":"NationalSecurityAgency/ghidra","slug":"code-units-cannot-overlap-73d0b7","errorCode":null,"errorMessage":"Code units cannot overlap","messagePattern":"Code units cannot overlap","errorType":"exception","errorClass":"CodeUnitInsertionException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceInstructionsView.java","lineNumber":382,"sourceCode":"\t\tif (platform.getLanguage() != prototype.getLanguage()) {\n\t\t\tthrow new IllegalArgumentException(\"Platform and prototype disagree in language\");\n\t\t}\n\n\t\tint forcedLengthOverride = InstructionDB.checkLengthOverride(length, prototype);\n\t\tif (length == 0) {\n\t\t\tlength = prototype.getLength();\n\t\t}\n\t\tAddress endAddress = address.addNoWrap(length - 1);\n\t\tAddressRangeImpl createdRange = new AddressRangeImpl(address, endAddress);\n\n\t\t// Truncate, then check that against existing code units.\n\t\tlong endSnap = computeTruncatedMax(lifespan, null, createdRange);\n\t\tTraceAddressSnapRange tasr =\n\t\t\tnew ImmutableTraceAddressSnapRange(createdRange, lifespan.withMax(endSnap));\n\n\t\tif (!space.undefinedData.coversRange(tasr)) {\n\t\t\t// TODO: Figure out the conflicting unit or snap boundary?\n\t\t\tthrow new CodeUnitInsertionException(\"Code units cannot overlap\");\n\t\t}\n\n\t\tdoSetContext(tasr, prototype.getLanguage(), context);\n\n\t\tDBTraceInstruction created = space.instructionMapSpace.put(tasr, null);\n\t\tcreated.set(platform, prototype, context, forcedLengthOverride);\n\n\t\tcacheForContaining.notifyNewEntry(tasr.getLifespan(), createdRange, created);\n\t\tcacheForSequence.notifyNewEntry(tasr.getLifespan(), createdRange, created);\n\t\tspace.undefinedData.invalidateCache();\n\n\t\t// TODO: Save the context register into the context manager? Flow it?\n\t\t// TODO: Ensure cached undefineds don't extend into defined stuff\n\t\t// TODO: Explicitly remove undefined from cache, or let weak refs take care of it?\n\t\treturn created;\n\t}\n\n\t@Override","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceInstructionsView.java#L364-L400","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Before creating the instruction, check for existing code units at the target address via space.definedUnits.getContaining(snap, address) and clear them if appropriate.","Use a Lifespan that does not overlap with existing code units — create the instruction at a different snap range.","Call trace.getCodeManager().instructionAt(snap, addr) to check for conflicts first.","Catch CodeUnitInsertionException and handle the conflict by clearing the existing unit or adjusting the address."],"exampleFix":"// before\nDBTraceInstruction instr = view.create(lifespan, addr, platform, proto, ctx, 0);\n\n// after\nCodeUnit existing = space.definedUnits.getContaining(lifespan.lmin(), addr);\nif (existing != null) {\n    existing.delete(); // or choose a different address\n}\nDBTraceInstruction instr = view.create(lifespan, addr, platform, proto, ctx, 0);","handlingStrategy":"try-catch","validationCode":"// Check for existing code units before creating\nCodeUnit existing = space.definedUnits\n    .getContaining(lifespan.lmin(), address);\nif (existing != null) {\n    // conflict; clear existing or choose different address\n}","typeGuard":null,"tryCatchPattern":"try {\n    DBTraceInstruction instr = view.create(lifespan, address, platform, proto, ctx, len);\n} catch (CodeUnitInsertionException e) {\n    // overlap detected; clear the conflicting unit or adjust the range\n    CodeUnit conflict = space.definedUnits.getContaining(lifespan.lmin(), address);\n    if (conflict != null) conflict.delete();\n    // retry creation\n}","preventionTips":["Check getContaining() for existing code units before creating instructions.","Use non-overlapping lifespans when adding instructions at the same address across time.","Clear conflicting code units before re-disassembling an address range."],"tags":["instruction","trace-database","code-unit-conflict","overlap","checked-exception"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}