NationalSecurityAgency/ghidra · error · RuntimeError

No memory mapper

Error message

No memory mapper

What it means

Thrown by Extra.require_mm() when the memory_mapper attribute is None — meaning no architecture-specific memory mapper has been configured for the current debugging session. The debugger agent requires a memory mapper to translate between debugger offsets and Ghidra address spaces, and commands that need memory translation will fail until one is set.

Source

Thrown at Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py:105


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 the target process is connected and architecture detection has run before issuing memory commands.
  2. Call the architecture setup command that initializes both memory_mapper and register_mapper.
  3. Check that compute_ghidra_language() succeeds and a valid mapper is assigned to STATE.extra.memory_mapper.
  4. Reset and re-establish the debugging session if the mapper was lost.

Example fix

# Before: issuing memory command without mapper
# ghidra_trace_putmem(...)
#
# After: ensure mapper is initialized
# if STATE.extra.memory_mapper is None:
#     # run arch detection / connection setup first
#     establish_arch()
# ghidra_trace_putmem(...)
Defensive patterns

Strategy: validation

Validate before calling

# Before calling require_mm, check and initialize if needed:
if STATE.extra.memory_mapper is None:
    # run architecture detection to set up mapper
    arch.compute_memory_mapper(arch.compute_ghidra_language())
STATE.extra.require_mm()

Type guard

def has_memory_mapper(extra) -> bool:
    return extra.memory_mapper is not None

Try / catch

try:
    mm = STATE.extra.require_mm()
except RuntimeError as e:
    if str(e) == 'No memory mapper':
        # run setup/arch detection, then retry
        pass
    else:
        raise

Prevention

When it happens

Trigger: STATE.require_mm() (via Extra.require_mm()) is called by any command that needs to map memory addresses, but Extra.memory_mapper is still None from __init__. This happens when a memory-related command is issued before the architecture has been detected and the mapper initialized, or when arch detection fails silently.

Common situations: The user issues a memory read/write command before connecting and configuring the target architecture. The architecture detection (compute_ghidra_language) failed, so compute_memory_mapper returned the default but it was never assigned. The dbgeng session was reset without re-initializing the mapper.

Related errors


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