{"record":{"id":"df497f5bbaba52d2","repo":"NationalSecurityAgency/ghidra","slug":"no-memory-mapper-df497f","errorCode":null,"errorMessage":"No memory mapper","messagePattern":"No memory mapper","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py","lineNumber":89,"sourceCode":"\n\nclass ErrorWithCode(Exception):\n\n    def __init__(self, code: int) -> None:\n        self.code = code\n\n    def __str__(self) -> str:\n        return repr(self.code)\n\n\nclass Extra(object):\n    def __init__(self) -> None:\n        self.memory_mapper: Optional[arch.DefaultMemoryMapper] = None\n        self.register_mapper: Optional[arch.DefaultRegisterMapper] = None\n\n    def require_mm(self) -> arch.DefaultMemoryMapper:\n        if self.memory_mapper is None:\n            raise RuntimeError(\"No memory mapper\")\n        return self.memory_mapper\n\n    def require_rm(self) -> arch.DefaultRegisterMapper:\n        if self.register_mapper is None:\n            raise RuntimeError(\"No register mapper\")\n        return self.register_mapper\n\n\nclass State(object):\n\n    def __init__(self) -> None:\n        self.reset_client()\n\n    def require_client(self) -> Client:\n        if self.client is None:\n            raise RuntimeError(\"Not connected\")\n        return self.client\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-drgn/src/main/py/src/ghidradrgn/commands.py#L71-L107","documentation":"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.","triggerScenarios":"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.","commonSituations":"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().","solutions":["Ensure ghidra_trace_start() completed successfully before any memory operation.","Guard with: if trace.extra.memory_mapper is None: start the trace / report 'start trace first'.","Verify start_trace() actually set extra.memory_mapper (arch.compute_memory_mapper returned a mapper)."],"exampleFix":"// before\nmm = trace.extra.require_mm()  # RuntimeError if not started\n// after\nif trace.extra.memory_mapper is None:\n    raise RuntimeError(\"call ghidra_trace_start before memory ops\")\nmm = trace.extra.require_mm()","handlingStrategy":"validation","validationCode":"trace = STATE.require_trace()\nif trace.extra.memory_mapper is None:\n    raise RuntimeError('call ghidra_trace_start before memory operations')\nmm = trace.extra.require_mm()","typeGuard":"def has_memory_mapper(trace) -> bool:\n    return getattr(getattr(trace, 'extra', None), 'memory_mapper', None) is not None","tryCatchPattern":"try:\n    mm = trace.extra.require_mm()\nexcept RuntimeError as e:\n    if 'No memory mapper' in str(e):\n        ghidra_trace_start(); mm = trace.extra.require_mm()\n    else:\n        raise","preventionTips":["Always run ghidra_trace_start() before any memory operation.","Confirm start_trace() set extra.memory_mapper for the detected language.","Centralize memory-op entry points behind a helper that checks the mapper first."],"tags":["drgn","memory-mapper","state-machine","precondition"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}