NationalSecurityAgency/ghidra · error · RuntimeError

No memory mapper

Error message

No memory mapper

What it means

Raised as RuntimeError by Extra.require_mm() when STATE.trace.extra.memory_mapper is still None. The mapper is only populated during start_trace(); calling a memory operation before the trace is started (or on an extra object that was never wired) triggers it.

Source

Thrown at Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py:89


class ErrorWithCode(Exception):

    def __init__(self, code: int) -> None:
        self.code = code

    def __str__(self) -> str:
        return repr(self.code)


class Extra(object):
    def __init__(self) -> None:
        self.memory_mapper: Optional[arch.DefaultMemoryMapper] = None
        self.register_mapper: Optional[arch.DefaultRegisterMapper] = None

    def require_mm(self) -> arch.DefaultMemoryMapper:
        if self.memory_mapper is None:
            raise RuntimeError("No memory mapper")
        return self.memory_mapper

    def require_rm(self) -> arch.DefaultRegisterMapper:
        if self.register_mapper is None:
            raise RuntimeError("No register mapper")
        return self.register_mapper


class State(object):

    def __init__(self) -> None:
        self.reset_client()

    def require_client(self) -> Client:
        if self.client is None:
            raise RuntimeError("Not connected")
        return self.client

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Ensure ghidra_trace_start() completed successfully before any memory operation.
  2. Guard with: if trace.extra.memory_mapper is None: start the trace / report 'start trace first'.
  3. Verify start_trace() actually set extra.memory_mapper (arch.compute_memory_mapper returned a mapper).

Example fix

// before
mm = trace.extra.require_mm()  # RuntimeError if not started
// after
if trace.extra.memory_mapper is None:
    raise RuntimeError("call ghidra_trace_start before memory ops")
mm = trace.extra.require_mm()
Defensive patterns

Strategy: validation

Validate before calling

trace = STATE.require_trace()
if trace.extra.memory_mapper is None:
    raise RuntimeError('call ghidra_trace_start before memory operations')
mm = trace.extra.require_mm()

Type guard

def has_memory_mapper(trace) -> bool:
    return getattr(getattr(trace, 'extra', None), 'memory_mapper', None) is not None

Try / catch

try:
    mm = trace.extra.require_mm()
except RuntimeError as e:
    if 'No memory mapper' in str(e):
        ghidra_trace_start(); mm = trace.extra.require_mm()
    else:
        raise

Prevention

When it happens

Trigger: Invoking a memory read/write/refresh method before ghidra_trace_start() has run; accessing a Trace[Extra] whose extra was not initialized with a memory_mapper.

Common situations: Memory operation dispatched out of the connect→start_trace ordering; trace started on a path that failed before setting extra.memory_mapper; using a Trace created outside start_trace().

Related errors


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