code wiki / (root) / nx_sigfixture.nx

nx_sigfixture.nx

buildroot/runtime/nx_sigfixture.nx

5214 B97 linesdepth 2pulls 2 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_sigfixture.nx -- A PROCESS THAT DIES BY THE SIGNAL YOU NAME: THE ONE FIXTURE FOR EVERY WAIT-STATUS RULER. WHY (2026-09-05, measured on the promote path). nx_behaveprobe reported rc=0 for a gate the crash guard had killed with SIGSEGV, twice, and that receipt cleared a crashing gate for promote. The estate's rule already existed (wait_status_rc: a signal death reads 128+signal, never 0; nx_waitrc_gate proves it in-process with a forked child) -- the served probe was simply older than the rule. What the estate had no way to do was ASK A LIVE, REGISTERED RULER how it reads a signal death, because no registered subject dies by a signal on purpose. This organ is that subject: nx_behaveprobe, nx_job_run, /api/gate_run and every other consumer of the tr_run_capture family can be pointed at it and their rc read back. usage: nx_sigfixture <signal 1..64> -- prints one line, then kill(getpid(), signal) on ITSELF nx_sigfixture exit <code> -- prints one line, then exits with that code (the control arm) SIGTERM (15) is the honest signal: no guard catches it, so the wait status carries a TRUE signal death and a correct ruler reads 143 where the old accessor read 0. SIGKILL (9) is the watchdog class (the bounded capture maps its own kill to TR_ERR_TIMEOUT). A guarded fault signal (SIGSEGV 11) is caught by the default-on crash guard and surfaces as exit 139 -- that is the guard's contract and this fixture does not pretend otherwise: pass 11 and you measure the guard, pass 15 and you measure the ruler. The line it prints BEFORE dying exists so a capture is never empty by cause: an empty capture plus rc=0 is the shape of a tool that never ran, and this fixture must never be mistaken for one. If the signal is blocked or ignored the process is still alive afterwards; it says so and exits SF_EXIT_SURVIVED, never 0, so a ruler cannot be acquitted by a signal that never landed. license_tier: ORIGINAL expect_exit: 143

dependencies 1 imports · 0 importers

nx_syscalls.nx nx_sigfixture.nx

imports: nx_syscalls.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main sf_usage sf_puts sys_write sys_exit sf_eq sf_atoi sf_puts ↻ sf_pn sf_puts ↻ sys_mmap nxa_die sys_write ↻ sys_exit ↻ nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ nx_kill

structs

none

consts

25const SF_SYS_GETPID_RV64: i64 = 172 // rv64 getpid, translated by __syscall (witness: nx_getpid_const_probe)
26const SF_EXIT_USAGE: i64 = 2
27const SF_EXIT_SURVIVED: i64 = 3 // the fleet's UNOBSERVABLE code: the signal never landed
28const SF_SIGNAL_MIN: i64 = 1
29const SF_SIGNAL_MAX: i64 = 64
30const SF_DIGIT_ZERO: i64 = 48
31const SF_DIGIT_NINE: i64 = 57
32const SF_DEC_BASE: i64 = 10
33const SF_NUM_CAP: i64 = 32

functions

35func sf_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 3: sf_pnsf_usagemain calls 1: sys_write
36func sf_pn(v: i64) -> i64
called by 1: main calls 2: sf_putssys_mmap
52func sf_atoi(s: *u8) -> i64
called by 1: main
65func sf_eq(a: *u8, b: *u8) -> i64
called by 1: main
71func sf_usage() -> i64
called by 1: main calls 1: sf_puts
76func main(argc: i64, argv: *i64) -> i64