{"record":{"id":"6a3fb4f8cc21ec03","repo":"NationalSecurityAgency/ghidra","slug":"mismatch-on-frame","errorCode":null,"errorMessage":"Mismatch on frame","messagePattern":"Mismatch on frame","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py","lineNumber":858,"sourceCode":"\n\n@REGISTRY.method()\n@util.dbg.eng_thread\ndef write_mem(process: Process, address: Address, data: bytes) -> None:\n    \"\"\"Write memory.\"\"\"\n    nproc = find_proc_by_obj(process)\n    offset = process.trace.extra.require_mm().map_back(nproc, address)\n    dbg().write(offset, data)\n\n\n@REGISTRY.method()\n@util.dbg.eng_thread\ndef write_reg(frame: StackFrame, name: str, value: bytes) -> None:\n    \"\"\"Write a register.\"\"\"\n    f = find_frame_by_obj(frame)\n    current = util.selected_frame()\n    if f.FrameNumber != current:\n        raise Exception(\"Mismatch on frame\")\n    nproc = util.selected_process()\n    trace: Trace[commands.Extra] = frame.trace\n    rv = trace.extra.require_rm().map_value_back(nproc, name, value)\n    rval = int.from_bytes(rv.value, signed=False)\n    dbg().reg._set_register(name, rval)\n\n\n@REGISTRY.method(display='Refresh Events (custom)', condition=util.dbg.IS_TRACE)\n@util.dbg.eng_thread\ndef refresh_trace_events_custom(node: State,\n                                cmd: Annotated[str, ParamDesc(display='Cmd')],\n                                prefix: Annotated[str, ParamDesc(display='Prefix')] = \"dx -r2 @$cursession.TTD\") -> None:\n    \"\"\"Parse TTD objects generated from a LINQ command.\"\"\"\n    with commands.open_tracked_tx('Put Events (custom)'):\n        commands.ghidra_trace_put_trace_events_custom(prefix, cmd)\n\n\n@REGISTRY.method(action='add_handler', display='Add Handler')","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py#L840-L876","documentation":"Raised as a bare Exception by write_reg() when the frame resolved from the TraceObject (f.FrameNumber) does not equal util.selected_frame(). DbgEng register writes apply to the currently selected stack frame, so writing to a non-selected frame is rejected to avoid corrupting the wrong context.","triggerScenarios":"Issuing a register write targeting a stack frame that is not the engine's currently selected frame; the UI/model selected a non-top frame and dispatched write_reg against it.","commonSituations":"User selects a deeper stack frame in the Ghidra UI then tries to edit a register; the target resumed and the selected frame changed underneath the stale FrameNumber.","solutions":["Before writing, select the target frame in DbgEng so util.selected_frame() == f.FrameNumber.","Guard the call: compare util.selected_frame() to the desired FrameNumber and either select it or refuse with a clear message.","Refresh the stack trace and re-resolve the frame object so FrameNumber is current."],"exampleFix":"// before\ndef write_reg(frame, name, value):\n    f = find_frame_by_obj(frame)\n    if f.FrameNumber != util.selected_frame():\n        raise Exception(\"Mismatch on frame\")\n// after\nf = find_frame_by_obj(frame)\nif f.FrameNumber != util.selected_frame():\n    util.select_frame(f.FrameNumber)  # or surface 'select frame first'\ndbg().reg._set_register(name, rval)","handlingStrategy":"validation","validationCode":"f = find_frame_by_obj(frame)\nif f.FrameNumber != util.selected_frame():\n    raise RuntimeError(f'frame {f.FrameNumber} is not selected ({util.selected_frame()}); select it first')","typeGuard":"null","tryCatchPattern":"try:\n    write_reg(frame, name, value)\nexcept Exception as e:\n    if 'Mismatch on frame' in str(e):\n        log.warning('register write refused; select frame %s first', frame)\n    else:\n        raise","preventionTips":["Select the target stack frame in DbgEng before issuing register writes.","Re-resolve the frame object after the target resumes so FrameNumber is current.","Compare util.selected_frame() to the desired FrameNumber up front and fail with an actionable message."],"tags":["dbgeng","register-write","frame","state-mismatch"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}