{"record":{"id":"dbedf4292effeed1","repo":"NationalSecurityAgency/ghidra","slug":"trace-already-started-dbedf4","errorCode":null,"errorMessage":"Trace already started","messagePattern":"Trace already started","errorType":"validation","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py","lineNumber":116,"sourceCode":"            raise RuntimeError(\"Not connected\")\n        return self.client\n\n    def require_no_client(self) -> None:\n        if self.client is not None:\n            raise RuntimeError(\"Already connected\")\n\n    def reset_client(self) -> None:\n        self.client: Optional[Client] = None\n        self.reset_trace()\n\n    def require_trace(self) -> Trace[Extra]:\n        if self.trace is None:\n            raise RuntimeError(\"No trace active\")\n        return self.trace\n\n    def require_no_trace(self) -> None:\n        if self.trace is not None:\n            raise RuntimeError(\"Trace already started\")\n\n    def reset_trace(self) -> None:\n        self.trace: Optional[Trace[Extra]] = None\n        util.set_convenience_variable('_ghidra_tracing', \"false\")\n        self.reset_tx()\n\n    def require_tx(self) -> Tuple[Trace[Extra], Transaction]:\n        trace = self.require_trace()\n        if self.tx is None:\n            raise RuntimeError(\"No transaction\")\n        return trace, self.tx\n\n    def require_no_tx(self) -> None:\n        if self.tx is not None:\n            raise RuntimeError(\"Transaction already started\")\n\n    def reset_tx(self) -> None:\n        self.tx: Optional[Transaction] = None","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py#L98-L134","documentation":"Raised by State.require_no_trace in the Ghidra LLDB agent when STATE.trace is already set — i.e. a trace is already active. The start-trace command (commands.py:415 calls require_no_trace) calls this to prevent starting a second trace over an existing one; an existing trace is rejected with RuntimeError.","triggerScenarios":"Running the start-trace command a second time without first closing/stopping the existing trace. The start command asserts require_no_trace before creating a new Trace.","commonSituations":"User runs 'ghidra_trace_start' twice; previous trace was not closed (ghidra_trace_stop/trace.close not run); script re-starts without teardown.","solutions":["Run the stop-trace command (ghidra_trace_stop, commands.py:432 close) before starting again.","Guard scripts: if STATE.trace is not None, stop/close it first.","Catch RuntimeError and hint 'trace already started; run ghidra_trace_stop first'.","Ensure stop is called on script exit to reset STATE.trace."],"exampleFix":"// before\nSTATE.require_no_trace()\nSTATE.trace = STATE.require_client().create_trace(...)\n// after\nif STATE.trace is not None:\n    STATE.require_trace().close()\n    STATE.reset_trace()\nSTATE.require_no_trace()\nSTATE.trace = STATE.require_client().create_trace(...)","handlingStrategy":"validation","validationCode":"if STATE.trace is not None:\n    STATE.require_trace().close()\n    STATE.reset_trace()\nSTATE.require_no_trace()\nSTATE.trace = STATE.require_client().create_trace(...)","typeGuard":"def no_trace_active() -> bool:\n    return STATE.trace is None","tryCatchPattern":"try:\n    STATE.require_no_trace()\nexcept RuntimeError:\n    print(\"Trace already started; run ghidra_trace_stop first\")\n    return","preventionTips":["stop the current trace before starting a new one","guard re-start scripts","call stop on script exit to reset STATE.trace"],"tags":["ghidra","lldb","runtime-error","state-machine","trace"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}