{"record":{"id":"530ebf46ae717c97","repo":"NationalSecurityAgency/ghidra","slug":"timed-out-waiting-for-thread-to-stop","errorCode":null,"errorMessage":"Timed out waiting for thread to stop","messagePattern":"Timed out waiting for thread to stop","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py","lineNumber":2092,"sourceCode":"    An optional timeout may be given in seconds. If omitted, the timeout is 1\n    second.\n    \"\"\"\n\n    args = shlex.split(command)\n    if len(args) == 0:\n        timeout = 1\n    elif len(args) == 1:\n        timeout = int(args[0])\n    else:\n        raise RuntimeError(\"Usage: ghidra util wait-stopped [SECONDS]\")\n\n    start = time.time()\n    p = util.get_process()\n    while p is not None and p.state == lldb.eStateRunnig:\n        time.sleep(0.1)\n        p = util.get_process()  # I suppose it could change\n        if time.time() - start > timeout:\n            raise RuntimeError('Timed out waiting for thread to stop')\n    print(f\"Finished wait. State={p.state}\")\n","sourceCodeStart":2074,"sourceCodeEnd":2094,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py#L2074-L2094","documentation":"Raised by ghidra_util_wait_stopped when the target does not reach a stopped state within the given timeout (default 1s). The loop polls util.get_process().state every 0.1s and raises at commands.py:2092 once elapsed time exceeds the timeout. IMPORTANT BUG: the loop compares against `lldb.eStateRunnig` (typo, missing 'n'); the correct constant is `lldb.eStateRunning`. Accessing the misspelled attribute typically raises AttributeError before the timeout branch, so this exact message is effectively a dead path until the typo is fixed.","triggerScenarios":"Issuing `ghidra util wait-stopped` (or with N seconds) when the target is still running/resuming and doesn't stop within the window — e.g. right after `process continue` on a long-running target, or with a too-small timeout on a slow remote/gdb-protocol target. In practice you may instead hit AttributeError on `lldb.eStateRunnig`.","commonSituations":"Race after a continue/step where the stop event hasn't arrived; slow remote debugging where 1s default is too short; or a target that never stops (runs to exit). The typo means the intended 'running' comparison is broken.","solutions":["Increase the timeout: `ghidra util wait-stopped 10`.","Ensure the target was actually commanded to stop (breakpoint/step) before waiting; wait-stopped cannot create a stop.","Fix the typo at commands.py:2088: `lldb.eStateRunning` so the poll correctly detects running state and the timeout path works as designed.","If you see AttributeError mentioning eStateRunnig, that is the same line — patch the constant name."],"exampleFix":"// before\nwhile p is not None and p.state == lldb.eStateRunnig:\n// after\nwhile p is not None and p.state == lldb.eStateRunning:","handlingStrategy":"try-catch","validationCode":"import lldb, time\n# Guard before waiting: only wait if a stop is actually expected,\n# and use the CORRECT constant (eStateRunning, not the codebase typo).\nrunning = getattr(lldb, 'eStateRunning', None)\nif running is None:\n    raise AttributeError(\"lldb.eStateRunning missing; cannot poll state\")","typeGuard":null,"tryCatchPattern":"try:\n    dbg.HandleCommand('ghidra util wait-stopped 10')\nexcept RuntimeError as e:\n    if 'Timed out waiting' in str(e):\n        # target did not stop in time — retry with larger timeout or\n        # verify a stop was actually requested\n        ...","preventionTips":["Give an explicit larger timeout for slow/remote targets.","Only wait after issuing a command that will stop the target.","Patch the eStateRunnig typo (commands.py:2088) so the poll works; otherwise you'll see AttributeError instead of this timeout."],"tags":["lldb","ghidra","timeout","typo-bug","debugger-agent","wait"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}