{"record":{"id":"01d3c9736a030d75","repo":"NationalSecurityAgency/ghidra","slug":"no-memory-mapper-01d3c9","errorCode":null,"errorMessage":"No memory mapper","messagePattern":"No memory mapper","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py","lineNumber":82,"sourceCode":"MEMORY_PATTERN = PROCESS_PATTERN + '.Memory'\nREGION_KEY_PATTERN = '[{start:08x}]'\nREGION_PATTERN = MEMORY_PATTERN + REGION_KEY_PATTERN\nMODULES_PATTERN = PROCESS_PATTERN + '.Modules'\nMODULE_KEY_PATTERN = '[{modpath}]'\nMODULE_PATTERN = MODULES_PATTERN + MODULE_KEY_PATTERN\nSECTIONS_ADD_PATTERN = '.Sections'\nSECTION_KEY_PATTERN = '[{secname}]'\nSECTION_ADD_PATTERN = SECTIONS_ADD_PATTERN + SECTION_KEY_PATTERN\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":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py#L64-L100","documentation":"Raised by Extra.require_mm in the Ghidra LLDB agent when memory_mapper has not been set on the trace's Extra object. The memory mapper translates between Ghidra addresses and target offsets; without it, memory-related trace operations cannot proceed. RuntimeError signals a missing precondition — the mapper must be computed (compute_memory_mapper) and assigned before any memory operation is invoked.","triggerScenarios":"Calling trace.extra.require_mm() before the agent initialized memory_mapper — e.g. a memory command/method ran during trace startup before compute_memory_mapper completed, or the mapper was never assigned for the target language. Reached by ~15 commands/methods (putmem, getmem, mem region emission, etc.).","commonSituations":"Trace started but the environment/activate step that sets memory_mapper did not run (e.g. target not yet launched, or arch detection failed silently); language with no registered mapper where the init code path was skipped; ordering bug where a memory method fires before 'activate'.","solutions":["Ensure the trace-activate/environment step (which sets trace.extra.memory_mapper = compute_memory_mapper(lang)) runs to completion before any memory method.","Lazily initialize the mapper inside require_mm: if None, assign compute_memory_mapper(current_lang) before returning.","Order commands so memory operations occur only after target launch and arch detection.","Add a startup self-check that asserts memory_mapper is set after activate."],"exampleFix":"// before\noffset = trace.extra.require_mm().map_back(proc, address)\n// after\nextra = trace.extra\nif extra.memory_mapper is None:\n    extra.memory_mapper = arch.compute_memory_mapper(current_lang)\noffset = extra.require_mm().map_back(proc, address)","handlingStrategy":"validation","validationCode":"extra = trace.extra\nif extra.memory_mapper is None:\n    extra.memory_mapper = arch.compute_memory_mapper(current_lang)\noffset = extra.require_mm().map_back(proc, address)","typeGuard":"def memory_mapper_ready(extra) -> bool:\n    return extra.memory_mapper is not None","tryCatchPattern":"try:\n    mm = trace.extra.require_mm()\nexcept RuntimeError:\n    # mapper not initialized; initialize then retry\n    trace.extra.memory_mapper = arch.compute_memory_mapper(current_lang)\n    mm = trace.extra.require_mm()","preventionTips":["ensure activate/environment step sets memory_mapper before any memory command","lazily initialize the mapper in require_mm","self-check that memory_mapper is set after activate"],"tags":["ghidra","lldb","runtime-error","state-machine","memory-mapper"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}