<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/idatui/diag.py, branch main</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/idatui/diag.py?h=main</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/idatui/diag.py?h=main'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-08-06T22:33:28Z</updated>
<entry>
<title>diag: somewhere for swallowed errors to go</title>
<updated>2026-08-06T22:33:28Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-08-06T22:33:12Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=2b0ae8df463edb597007186688ee557c18f1ac18'/>
<id>urn:sha1:2b0ae8df463edb597007186688ee557c18f1ac18</id>
<content type='text'>
A TUI must not die because one background load failed, so this codebase catches
broadly -- ~50 `except Exception` sites, two dozen resolving to `pass`. Right
policy, one bad consequence: with 44 `@work(thread=True)` workers, a failure in
a background load leaves no trace whatsoever. The view stays empty and there is
nothing to read afterwards, because the app owns the screen.

kittygfx already solved this for itself with $IDATUI_KITTY_LOG. idatui/diag.py
is the same idea for everything else: $IDATUI_LOG writes every swallowed error
plus its traceback to a file, and the last 50 are kept in memory regardless so a
driver can ask a live app what went wrong. Unset, it costs an environ lookup.

Wired in where losing the error changes a DECISION rather than just a pixel:

  * rename: a resolve() that throws renames as DATA instead of as a function.
  * name: a function_of() that throws means we never learn the address is a
    function start, so the index keeps the old name and every readback says the
    rename didn't happen.
  * retype: a resolve() that throws retypes the ENCLOSING function instead.
  * decompile: a failed full-body fetch silently returns CLIPPED pseudocode.
  * trail: a failed decomp_map stops the pseudocode being painted, silently.

Deliberately NOT wired into the query_one guards -- a modal owning the screen is
normal and constant, and logging it would bury the real entries in noise.

New RPC verb `diag {n?, clear?}`, documented in docs/RPC.md: the answer to "the
verb reported success and the pane shows nothing".

Also a flake, same shape as the others: follow_xrefs waited on the nav depth but
asserted on _cur, and a follow pushes the source entry BEFORE opening the
target -- so the check could run in between and see the function it jumped
from. About one run in ten. It waits on the postcondition it asserts now; three
clean full runs since.

833 checks; --fast is 344 in 3.5s.
</content>
</entry>
</feed>
