nx_zombie_audit_gate.nx source
↩ module page · 37 lines · 1887 B
1// nx_zombie_audit_gate.nx -- KAT for the zombie detector. Forks a DISTINCTIVE cluster of unreaped
2// children (-> real zombies under this gate), asserts the detector counts that exact cluster, then
3// reaps them and asserts the cluster is gone (neg-control). exit 0 = pass, N = assertion N failed.
4import "nx_zombie_audit.nx"
5import "nx_assert.nx"
6
7func zg_has_count(cc: *i64, n: i64, target: i64) -> i64 { var i: i64=0; while i<n { if cc[i]==target { return 1 } i=i+1 } return 0 }
8
9func main() -> i64 {
10 let pp: *i64 = sys_mmap(8*2048) as *i64; let cc: *i64 = sys_mmap(8*2048) as *i64; let tot: *i64 = sys_mmap(16) as *i64
11 let N: i64 = 41 // distinctive (a real per-parent leak is unlikely to be exactly 41)
12
13 // fork N children that immediately exit -> N zombies under THIS process (not reaped yet)
14 var f: i64 = 0
15 while f < N { let pid: i64 = sys_fork(); if pid == 0 { sys_exit(0) } f = f + 1 }
16 sys_sleep_ms(300) // let them transition to defunct/zombie
17
18 let np1: i64 = za_scan(pp, cc, 2048, tot)
19 let found1: i64 = zg_has_count(cc, np1, N)
20 nx_puts_err("after fork 41: total_zombies="); nx_puti_err(tot[0])
21 nx_puts_err("detector counted a 41-cluster="); nx_puti_err(found1)
22 if found1 != 1 { return 1 } // detector must find our exact cluster
23
24 // reap our N -> they vanish
25 let st: *i64 = sys_mmap(16) as *i64; var r: i64 = 0
26 while r < N { sys_wait4(0 - 1, st, 0); r = r + 1 }
27 sys_sleep_ms(100)
28
29 let np2: i64 = za_scan(pp, cc, 2048, tot)
30 let found2: i64 = zg_has_count(cc, np2, N)
31 nx_puts_err("after reap: total_zombies="); nx_puti_err(tot[0])
32 nx_puts_err("41-cluster gone (neg-control)="); nx_puti_err(found2)
33 if found2 != 0 { return 2 } // NEG-CONTROL: reaped -> detector no longer sees it
34
35 nx_puts_err("nx_zombie_audit_gate verdict=GREEN pass=2\n")
36 return 0
37}