nx_panic.nx
buildroot/runtime/nx_panic.nx
about
nx_panic.nx -- enterprise panic handler.
When Nishi-owned code encounters a condition it cannot handle
(unreachable branch taken, invariant violated, untrusted input
poisoned the parser), the panic handler produces a STRUCTURED
post-mortem dump and exits cleanly.
What a proper panic produces:
* A header line with tag + message (nx_log FATAL level).
* Register state -- sp, ra, optionally t0..t6 (future: read
via signal handler ucontext_t).
* Stack hex dump -- 128 bytes starting at sp (future: walk
CFI to unwind frames symbolically).
* A structured footer (seq + exit code) so harnesses can
correlate the panic to the exit.
* Exit with NX_PANIC_EXIT=200, same as nx_assert.
Comparison to production systems:
* Rust std::panic! with RUST_BACKTRACE=1 -- tag + msg + sym
bt. Our v0.0.1 matches on tag+msg; bt is symbolic via
future DWARF-native parser.
* Go's panic(x) -- dumps stack + goroutine info. Same shape.
* Google glog LOG(FATAL) -- msg + crash dump + core. Same
shape.
* Linux kernel oops -- registers + stack + modules. Our
long-term target.
The panic handler is ENTRY-LEVEL enterprise today, upgrade
path to full-fidelity when:
* SIGSEGV handler installed (runtime can catch hardware
faults, not just invariant violations)
* DWARF symbol table lookup available (symbolic bt)
* Record-replay captures state for offline analysis
dependencies 3 imports · 1 importers
imports: syscalls.nxnx_log.nxnx_hex.nx
imported by: nx_panic_fire_test.nx
structs
| none |
consts
| 45 | const NX_PANIC_EXIT: i64 = 200 |
| 46 | const NX_PANIC_STACK_DUMP: i64 = 128 // bytes above sp to dump |
| 47 | const NX_PANIC_FD: i64 = 2 // stderr for post-mortem |
functions
| 53 | func nx_panic(tag: *u8, msg: *u8) -> i64 calls 1: nx_log_fatal |
| 62 | func nx_panic_ctx(tag: *u8, msg: *u8, ctx_label: *u8, |
| 85 | func main() -> i64 |