{"record":{"id":"944e9853278a6d9e","repo":"NationalSecurityAgency/ghidra","slug":"more-than-one-state-is-present-in","errorCode":null,"errorMessage":"More than one state is present in ","messagePattern":"More than one state is present in ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/InternalTraceMemoryOperations.java","lineNumber":43,"sourceCode":"import ghidra.program.model.address.AddressSpace;\nimport ghidra.program.model.lang.Register;\nimport ghidra.program.model.lang.RegisterValue;\nimport ghidra.trace.model.TraceAddressSnapRange;\nimport ghidra.trace.model.guest.TracePlatform;\nimport ghidra.trace.model.memory.TraceMemoryOperations;\nimport ghidra.trace.model.memory.TraceMemoryState;\nimport ghidra.trace.util.TraceRegisterUtils;\nimport ghidra.util.LockHold;\n\n@Internal\npublic interface InternalTraceMemoryOperations extends TraceMemoryOperations {\n\n\tstatic TraceMemoryState requireOne(AddressRange range,\n\t\t\tCollection<Entry<TraceAddressSnapRange, TraceMemoryState>> states, Register register) {\n\t\tTraceMemoryState state =\n\t\t\tTraceMemoryOperations.oneState(range, states);\n\t\tif (state == null) {\n\t\t\tthrow new IllegalStateException(\"More than one state is present in \" + register);\n\t\t}\n\t\treturn state;\n\t}\n\n\t/**\n\t * For register mapping conventions\n\t * \n\t * @return the address space\n\t */\n\tAddressSpace getSpace();\n\n\tReadWriteLock getLock();\n\n\t@Override\n\tdefault void setState(TracePlatform platform, long snap, Register register,\n\t\t\tTraceMemoryState state) {\n\t\tAddressRange range = platform.getConventionalRegisterRange(getSpace(), register);\n\t\tsetState(snap, range, state);","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/InternalTraceMemoryOperations.java#L25-L61","documentation":"Thrown by InternalTraceMemoryOperations.requireOne when TraceMemoryOperations.oneState returns null for a register's address range. oneState returns null when the register's conventional address range is covered by memory-state entries that are not all the same state, or when the entries do not completely cover the range. This indicates the register spans bytes with heterogeneous memory states (e.g. part KNOWN, part UNKNOWN), so no single uniform state can be reported for the whole register.","triggerScenarios":"Calling a register-level state operation (e.g. getState on a Register) whose conventional range overlaps multiple memory-state boundaries with differing TraceMemoryState values. This happens when a sub-register or parent register's byte range crosses a region boundary, or when only part of the register has been written/known at the given snap.","commonSituations":"Inspecting or requiring a uniform memory state for a multi-byte register (e.g. a 64-bit register where only the lower 32 bits were set) in a debugger/emulator trace. Partial register writes in emulator traces that mark sub-registers known but leave the rest unknown. Querying state of a register that overlaps two memory regions.","solutions":["Use TraceMemoryOperations.oneState yourself before calling requireOne and handle a null (non-uniform) result gracefully instead of requiring a single state.","Query state on the smallest sub-register that is fully covered, or query each byte/sub-range separately to find where the state boundary falls.","Ensure the entire register range is written/known before requiring a uniform state (write all bytes or set state for the full conventional range)."],"exampleFix":"// before\nTraceMemoryState state = memOps.requireOne(range, states, register);\n\n// after\nTraceMemoryState state = TraceMemoryOperations.oneState(range, states);\nif (state == null) {\n    // register spans mixed states; handle per sub-range\n    for (var e : states) {\n        // inspect e.getKey().getRange() and e.getValue()\n    }\n    return;\n}","handlingStrategy":"validation","validationCode":"// Call oneState yourself and handle null (non-uniform state) before requireOne\nTraceMemoryState state = TraceMemoryOperations.oneState(range, states);\nif (state == null) {\n    // register spans mixed memory states; do not call requireOne\n    // inspect states per sub-range instead\n    return;\n}\n// safe to use the uniform state","typeGuard":"// Check that a register range has a uniform state before requiring one\nstatic boolean hasUniformState(AddressRange range,\n        Collection<Map.Entry<TraceAddressSnapRange, TraceMemoryState>> states) {\n    return TraceMemoryOperations.oneState(range, states) != null;\n}","tryCatchPattern":null,"preventionTips":["Never call requireOne without first checking oneState returns non-null.","Query sub-register ranges when a parent register may span state boundaries.","Ensure the full register range is written/known before requiring uniform state."],"tags":["trace-modeling","memory-state","register","ghidra","validation"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}