From e769336aa753639f26208fd7755c1585d59caf41 Mon Sep 17 00:00:00 2001 From: blasty Date: Sat, 11 Jul 2026 10:59:48 +0200 Subject: fix: don't hang drive pc on undecompilable functions toggle_view's settle predicate (lambda: app._active != before) never fired when tabbing toward pseudocode on a function Hex-Rays can't decompile: App._apply_decomp snaps the view back to disasm, so _active returns to its prior value -> full 20s settle timeout (x2 in _show_decomp, ~40s for drive pc). Recognize the decomp-failed fallback as settled. Also harden two amplifiers surfaced by the same case: - rpcclient: the CLI socket had no read timeout and would block forever on any server slowness; add a bounded settimeout (IDATUI_RPC_TIMEOUT, default 90s) with a clear error. - domain.decompile: pass a bounded 15s timeout and cache failures, so a failing decompile can't sit at the 30s client default or be re-run by transport retries. --- idatui/rpc.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'idatui/rpc.py') diff --git a/idatui/rpc.py b/idatui/rpc.py index 426b337..f41c734 100644 --- a/idatui/rpc.py +++ b/idatui/rpc.py @@ -587,7 +587,26 @@ class RpcServer: return await self._press(["escape"], timeout=timeout) if method == "toggle_view": before = app._active - return await self._press(["tab"], lambda: app._active != before, timeout) + + def _toggled(): + # Normal case: the shown view flipped. + if app._active != before: + return True + # Fallback case: a tab toward pseudocode on a function Hex-Rays + # can't decompile snaps `_active` back to disasm (see + # App._apply_decomp), so `_active` never changes and the naive + # `_active != before` predicate would block for the full + # timeout. Treat "requested decomp but it's known-failed" as + # settled (the decompile is cached, so this is cheap). + cur = app._cur + if before == "disasm" and cur is not None: + try: + return app.program.decompile(cur.ea).failed + except Exception: # noqa: BLE001 + return False + return False + + return await self._press(["tab"], _toggled, timeout) if method == "hex": return await self._press(["backslash"], lambda: app._active == "hex", timeout) if method == "xrefs": -- cgit v1.3.1-sl0p