NationalSecurityAgency/ghidra · error · IllegalStateException
More than one state is present in
Error message
More than one state is present in
What it means
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.
Source
Thrown at Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/memory/InternalTraceMemoryOperations.java:43
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.Register;
import ghidra.program.model.lang.RegisterValue;
import ghidra.trace.model.TraceAddressSnapRange;
import ghidra.trace.model.guest.TracePlatform;
import ghidra.trace.model.memory.TraceMemoryOperations;
import ghidra.trace.model.memory.TraceMemoryState;
import ghidra.trace.util.TraceRegisterUtils;
import ghidra.util.LockHold;
@Internal
public interface InternalTraceMemoryOperations extends TraceMemoryOperations {
static TraceMemoryState requireOne(AddressRange range,
Collection<Entry<TraceAddressSnapRange, TraceMemoryState>> states, Register register) {
TraceMemoryState state =
TraceMemoryOperations.oneState(range, states);
if (state == null) {
throw new IllegalStateException("More than one state is present in " + register);
}
return state;
}
/**
* For register mapping conventions
*
* @return the address space
*/
AddressSpace getSpace();
ReadWriteLock getLock();
@Override
default void setState(TracePlatform platform, long snap, Register register,
TraceMemoryState state) {
AddressRange range = platform.getConventionalRegisterRange(getSpace(), register);
setState(snap, range, state);View on GitHub (pinned to d5f144c24d)
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).
Example fix
// before
TraceMemoryState state = memOps.requireOne(range, states, register);
// after
TraceMemoryState state = TraceMemoryOperations.oneState(range, states);
if (state == null) {
// register spans mixed states; handle per sub-range
for (var e : states) {
// inspect e.getKey().getRange() and e.getValue()
}
return;
} Defensive patterns
Strategy: validation
Validate before calling
// Call oneState yourself and handle null (non-uniform state) before requireOne
TraceMemoryState state = TraceMemoryOperations.oneState(range, states);
if (state == null) {
// register spans mixed memory states; do not call requireOne
// inspect states per sub-range instead
return;
}
// safe to use the uniform state Type guard
// Check that a register range has a uniform state before requiring one
static boolean hasUniformState(AddressRange range,
Collection<Map.Entry<TraceAddressSnapRange, TraceMemoryState>> states) {
return TraceMemoryOperations.oneState(range, states) != null;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Section path must be a successor of this module's path
- Address string should have at most one colon (:)
- Given bookmark is not present at this view's snap
- Given bookmark is not part of this trace
- Given namespace is not part of this trace
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/944e9853278a6d9e.
Report an issue: GitHub.