NationalSecurityAgency/ghidra · error · IllegalArgumentException

Cannot create register container

Error message

Cannot create register container

What it means

ProgramEmulationUtils.initializeRegisters() asks the trace object schema for a register container via searchForRegisterContainer(...) relative to the thread's canonical path. If the schema returns no pattern (regsFilter.isNone()), there is no defined place to store registers for that thread, so initialization aborts with IllegalArgumentException("Cannot create register container").

Source

Thrown at Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/service/emulation/ProgramEmulationUtils.java:351

	 * Initialize a thread's registers using program context and an optional stack
	 * 
	 * @param trace the trace containing the thread
	 * @param snap the destination snap for the register state
	 * @param thread the thread whose registers to initialize
	 * @param program the program whose context to use
	 * @param tracePc the program counter in the trace's memory map
	 * @param programPc the program counter in the program's memory map
	 * @param stack optionally, the range for the thread's stack allocation
	 */
	public static void initializeRegisters(Trace trace, long snap, TraceThread thread,
			Program program, Address tracePc, Address programPc, AddressRange stack) {
		TraceMemoryManager memory = trace.getMemoryManager();
		TraceObject object = thread.getObject();
		PathFilter regsFilter = object.getRoot()
				.getSchema()
				.searchForRegisterContainer(0, object.getCanonicalPath());
		if (regsFilter.isNone()) {
			throw new IllegalArgumentException("Cannot create register container");
		}
		for (PathPattern regsPattern : regsFilter.getPatterns()) {
			trace.getObjectManager().createObject(regsPattern.getSingletonPath());
			break;
		}
		TraceMemorySpace regSpace = memory.getMemoryRegisterSpace(thread, true);
		if (program != null) {
			ProgramContext ctx = program.getProgramContext();
			for (Register reg : Stream.of(ctx.getRegistersWithValues())
					.map(Register::getBaseRegister)
					.collect(Collectors.toSet())) {
				RegisterValue rv = ctx.getRegisterValue(reg, programPc);
				if (rv == null || !rv.hasAnyValue()) {
					continue;
				}
				TraceMemoryOperations space =
					reg.getAddressSpace().isRegisterSpace() ? regSpace : memory;
				// Set all the mask bits

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure the correct platform (language + compiler spec) is associated with the trace before emulation so the schema exposes a register container.
  2. Verify the trace object schema defines a register container for the thread's canonical path (searchForRegisterContainer must yield at least one pattern).
  3. Recreate/re-import the trace under the proper schema if it was built incorrectly.
  4. For custom schemas, add a register-container element to the schema for the relevant thread path.

Example fix

// before
ProgramEmulationUtils.initializeRegisters(trace, snap, thread, program, tracePc, programPc, stack);
// throws: schema has no register container for thread path

// after
// confirm the platform/schema yields a register container
PathFilter regs = thread.getObject().getRoot().getSchema()
    .searchForRegisterContainer(0, thread.getObject().getCanonicalPath());
if (regs.isNone()) {
    throw new IllegalStateException("Trace schema lacks register container; fix platform/schema");
}
ProgramEmulationUtils.initializeRegisters(trace, snap, thread, program, tracePc, programPc, stack);
Defensive patterns

Strategy: validation

Validate before calling

// Verify the schema exposes a register container before initializing registers
TraceObject obj = thread.getObject();
PathFilter regs = obj.getRoot().getSchema()
    .searchForRegisterContainer(0, obj.getCanonicalPath());
if (regs.isNone()) {
    throw new IllegalStateException(
        "No register container in schema; fix platform/language for trace");
}

Type guard

public static boolean schemaHasRegisterContainer(TraceThread thread) {
    TraceObject obj = thread.getObject();
    PathFilter regs = obj.getRoot().getSchema()
        .searchForRegisterContainer(0, obj.getCanonicalPath());
    return regs != null && !regs.isNone();
}

Try / catch

try {
    ProgramEmulationUtils.initializeRegisters(trace, snap, thread, program, tracePc, programPc, stack);
} catch (IllegalArgumentException e) {
    if (e.getMessage().equals("Cannot create register container")) {
        // set correct platform/language/schema, then retry
    } else throw e;
}

Prevention

When it happens

Trigger: Initializing registers for a thread whose object path does not match any register-container schema element. Emulating a trace built with a schema/compiler spec that lacks a register container, or where the thread object lives at an unexpected path. Wrong or missing platform/language for the trace.

Common situations: Emulating traces created with an older or custom schema that has no Registers object. Loading a trace with the wrong language/compiler spec so the schema does not match. Guest/overlay traces where the thread's canonical path is not where the schema expects registers.

Related errors


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