{"record":{"id":"2c3da48a0da22f21","repo":"NationalSecurityAgency/ghidra","slug":"no-register-mapper-2c3da4","errorCode":null,"errorMessage":"No register mapper","messagePattern":"No register mapper","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py","lineNumber":107,"sourceCode":"        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\n    def require_no_client(self) -> None:\n        if self.client != None:\n            raise RuntimeError(\"Already connected\")\n\n    def reset_client(self) -> None:","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-x64dbg/src/main/py/src/ghidraxdbg/commands.py#L89-L125","documentation":"Raised by Extra.require_rm when the trace's register_mapper has not been set. The register mapper translates between Ghidra register values and x64dbg register formats; it is initialized during start_trace via compute_register_mapper. Any register operation calling require_rm before start_trace completes will trigger this.","triggerScenarios":"A trace method calls STATE.trace.extra.require_rm() (directly or via a register read/write operation) before start_trace has set register_mapper.","commonSituations":"Register read/write commands issued before 'ghidra trace start'. start_trace failed before setting the register mapper. The language detected by compute_ghidra_lcsp did not have a registered mapper and compute_register_mapper was bypassed.","solutions":["Ensure 'ghidra trace start' completes successfully before issuing register commands.","Verify start_trace executed the register_mapper assignment line without error.","Manually set STATE.trace.extra.register_mapper = arch.compute_register_mapper(language) if needed."],"exampleFix":"# before: register op before trace start\nrm = STATE.trace.extra.require_rm()  # register_mapper is None\n\n# after: start trace first\nstart_trace(compute_name())\nrm = STATE.trace.extra.require_rm()","handlingStrategy":"validation","validationCode":"extra = STATE.trace.extra if STATE.trace else None\nif extra is None or extra.register_mapper is None:\n    raise RuntimeError(\"Register mapper not initialized; run 'ghidra trace start' first\")","typeGuard":"def has_register_mapper(extra: 'Extra') -> bool:\n    return extra is not None and extra.register_mapper is not None","tryCatchPattern":"try:\n    rm = STATE.trace.extra.require_rm()\nexcept RuntimeError:\n    start_trace(compute_name())\n    rm = STATE.trace.extra.require_rm()","preventionTips":["Always run 'ghidra trace start' before issuing register commands.","Verify start_trace set the register_mapper without errors.","Check STATE.trace.extra.register_mapper is not None before register operations."],"tags":["x64dbg","debugger-agent","state-machine","runtimeerror","register-mapper","initialization"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}