From 784df98d19b70eca5906ce0ac7fcf2bfcd0f3515 Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 24 Jul 2026 01:42:43 +0200 Subject: worker: surface the real startup failure (not just "code 1") The worker's stderr was swallowed by the TUI, so an open failure showed only "worker exited during startup (code 1)". Now: * WorkerClient captures the worker's stdout+stderr to /tmp/idatui-worker-*.log and, on a startup exit, surfaces the last meaningful line in the error (the worker prints a clean 'WORKER-FATAL: ...' marker; _log_tail prefers it). * worker.py wraps main() to print that marker + traceback before exiting 1, and gives an ACTIONABLE open error: "failed to open : the .i64 is likely held by a running ida-mcp worker (pkill -f idalib) or wedged (delete .id0/.id1/ .id2/.nam/.til)". Also calls ida_auto.auto_wait() after open to fully match ida-mcp's session manager (open_database + auto_wait). Root cause of the reported failure is almost certainly a leftover ida-mcp worker still holding bash's .i64 from earlier --backend mcp runs: idalib can't open a database another process has locked. Fix: pkill -f idalib, then retry --backend worker; the error message now says so instead of "code 1". --- idatui/worker.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'idatui/worker.py') diff --git a/idatui/worker.py b/idatui/worker.py index d5fab20..e1d3c44 100644 --- a/idatui/worker.py +++ b/idatui/worker.py @@ -64,9 +64,13 @@ def _open_and_register(binpath: str): against this live database. Returns (tools_dict, module_name, save_fn).""" import idapro idapro.enable_console_messages(False) - rc = idapro.open_database(binpath, run_auto_analysis=True) - if rc: - raise RuntimeError(f"open_database({binpath!r}) failed rc={rc}") + if idapro.open_database(binpath, run_auto_analysis=True): # nonzero == failure + raise RuntimeError( + f"failed to open {binpath}: the .i64 is likely held by a running " + f"ida-mcp worker (try: pkill -f idalib) or wedged from a crash " + f"(delete its .id0/.id1/.id2/.nam/.til next to the binary)") + import ida_auto + ida_auto.auto_wait() # block until auto-analysis settles (match ida-mcp) # importing the package registers all api_*/patched tools against MCP_SERVER from ida_pro_mcp.ida_mcp import MCP_SERVER # noqa: WPS433 @@ -153,7 +157,16 @@ def main(argv=None) -> None: if len(argv) < 2: sys.stderr.write("usage: python -m idatui.worker \n") raise SystemExit(2) - serve(argv[0], argv[1]) + try: + serve(argv[0], argv[1]) + except SystemExit: + raise + except BaseException as e: # noqa: BLE001 -- surface a clean cause + code 1 + import traceback + sys.stderr.write(f"\nWORKER-FATAL: {type(e).__name__}: {e}\n") + traceback.print_exc() + sys.stderr.flush() + raise SystemExit(1) if __name__ == "__main__": -- cgit v1.3.1-sl0p