Hey everyone, I wrote this tool for inspecting linux signals across proceses Comments URL: https://news.ycombinator.com/item?id=48898071 Points: 27 # Comments: 10

tail -f for signals. Every signal any process on the box raises — who sent it, who it hit, which signal, how it was raised (kill(2), the kernel, a POSIX timer), whether the target caught it and how long its handler ran, whether it tore a blocked syscall out with EINTR — decoded off the kernel's signal tracepoints and streamed live to your terminal. No strace -f on one pid, no ptrace, no cooperation from the processes involved. sigwire turns the kernel's signal machinery into a live patchbay: each line is sender ──SIGNAL──▶ target, coloured by severity, tagged with how it was raised, whether the target caught it (and how long its handler ran), whether it interrupted a blocked syscall (↯ EINTR read), collapsed to ×N when something spams, and marked ☠ when it's a genuine killing blow. A side rail tallies what's flying across the wire; pause and pick a row to inspect the full picture — disposition, handler address, sigaction flags, and the signals the target was blocking at that instant. Because it hooks the kernel's tracepoints, not any one process, a single run watches every signal on the host at once — your app, a supervisor, the kernel's own fault machinery — with none of them aware they're being traced. Two sides of every signal. sigwire watches both signal:signal_generate (the sender's view — who raised what, the switchboard line) and signal:signal_deliver (the target's view — did it catch it, with which handler and flags, what was it blocking, and did it interrupt a syscall). Two more hooks — rt_sigreturn(2) and the syscall-exit tracepoint — time the handler and catch EINTR. It's all correlated back into one row. This split is also why the ☠ fatal count is deliberately conservative (see What counts as fatal): generation happens before delivery, so the sender side can't know a signal's fate — only the delivery side can, and only for the cases it observes. Nothing to configure — signals are constant background traffic on any box, so rows start landing at the top immediately. Want to make some yourself? kill -USR1 <pid>, Ctrl-C a foreground job, or start any managed runtime and watch its GC/scheduler ping its own threads (↯ EINTR futex scrolling by). The feed follows the newest signal by default; select a row or pause and it holds still while data keeps flowing underneath. Each row is one block: the sender → target are comm·pid (the sender is whoever raised the signal, current; the target is who it's aimed at), the wire in the middle carries the signal name coloured by severity, ×N folds a burst of the identical signal into one line, and the note on the right gives the source, then any syscall interruption, then the disposition. Each row is frozen the moment its delivery resolves and never mutates again — so a burst scrolls past as a stable log, not a flickering aggregate.