code wiki / _hdl_build / nx_ccdiag.nx

nx_ccdiag.nx source

↩ module page · 69 lines · 4619 B

1// nx_ccdiag.nx -- ONE-STEP build diagnostic (<10s): why did `nx_sov_build_run <name>` fail with "empty .s"? 2// The runner MUTES nx_cc's stderr (2>/dev/null) + retries 12x, so a plain source error (undefined function, 3// parse error, arg-count) surfaces only as a mysterious "COMPILE-FAIL (empty .s after retries)" -- which cost a 4// ~15-build blind hunt. This tool runs the SAME sovereign compiler on the SAME source with stderr VISIBLE, once, 5// and prints the exit code + .s size + the real diagnostic line. Eats the debt: turn opaque empty-.s into the 6// actual cause in one look. Usage: nx_ccdiag <module-name> license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc) 9const K_MAGIC_65536: i64 = 65536 10 11func cd_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer 13// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the 14// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls). 15// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign. 16func cd_putn(v: i64) -> i64 { nxi_out(v); return 0 } 17func cd_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){d[o+i]=s[i]; i=i+1} return o+i } 18func cd_exists(p: *u8) -> i64 { let fd: i64 = sys_openat_rd(p); if fd < 0 { return 0 } sys_close(fd); return 1 } 19func cd_filesize(p: *u8) -> i64 { 20 let fd: i64 = sys_openat_rd(p); if fd < 0 { return 0 } 21 let buf: *u8 = sys_mmap(K_MAGIC_65536); var tot: i64 = 0 22 var r: i64 = sys_read(fd, buf, K_MAGIC_65536) 23 while r > 0 { tot = tot + r; r = sys_read(fd, buf, K_MAGIC_65536) } 24 sys_close(fd); return tot 25} 26// fork+execve the compiler: stdout -> the .s fd; stderr LEFT VISIBLE (inherited fd 2). returns exit code. 27func cd_run_cc(cc: *u8, src: *u8, sfd: i64) -> i64 { 28 let pid: i64 = sys_fork() 29 if pid == 0 { 30 if sfd >= 0 { sys_dup3(sfd, 1, 0) } // stdout -> .s (stderr fd2 UNTOUCHED = visible) 31 let argv: *i64 = sys_mmap(8 * 4) as *i64 32 argv[0] = cc as i64; argv[1] = src as i64; argv[2] = 0 33 let envp: *i64 = sys_mmap(16) as *i64; envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64; envp[1] = 0 34 sys_execve(cc, argv, envp) 35 sys_exit(127) 36 } 37 let st: *i64 = sys_mmap(16) as *i64 38 sys_wait4(pid, st, 0) 39 let sig: i64 = st[0] & 0x7f 40 if sig != 0 { return 128 + sig } 41 return (st[0] >> 8) & 0xff 42} 43 44func main(argc: i64, argv: *i64) -> i64 { 45 if argc < 2 { cd_puts("usage: nx_ccdiag <module-name>\n" as *u8); sys_exit(2); return 2 } 46 let name: *u8 = argv[1] as *u8 47 // resolve the source the same way nx_sov_build_run does 48 let src: *u8 = sys_mmap(512) 49 var o: i64 = cd_cat(src, 0, "runtime/_hdl_build/" as *u8); o = cd_cat(src, o, name); o = cd_cat(src, o, ".nx" as *u8); src[o] = 0 as u8 50 if cd_exists(src) == 0 { 51 o = cd_cat(src, 0, "runtime/" as *u8); o = cd_cat(src, o, name); o = cd_cat(src, o, ".nx" as *u8); src[o] = 0 as u8 52 if cd_exists(src) == 0 { 53 o = cd_cat(src, 0, "nxasm/" as *u8); o = cd_cat(src, o, name); o = cd_cat(src, o, ".nx" as *u8); src[o] = 0 as u8 54 if cd_exists(src) == 0 { cd_puts("nx_ccdiag: SOURCE-NOT-FOUND for " as *u8); cd_puts(name); cd_puts(" (probed runtime/_hdl_build/, runtime/, nxasm/)\n" as *u8); sys_exit(3); return 3 } 55 } 56 } 57 let spath: *u8 = sys_mmap(512) 58 o = cd_cat(spath, 0, "/tmp/ccdiag_" as *u8); o = cd_cat(spath, o, name); o = cd_cat(spath, o, ".s" as *u8); spath[o] = 0 as u8 59 60 cd_puts("=== nx_ccdiag: " as *u8); cd_puts(src); cd_puts(" (nx_cc_sovereign, stderr VISIBLE below) ===\n" as *u8) 61 let sfd: i64 = sys_openat_wr(spath, 0x1a4) // O_CREAT|O_WRONLY|O_TRUNC -> fresh .s, never a stale mask 62 let rc: i64 = cd_run_cc("_offc/nx_cc_sovereign.elf" as *u8, src, sfd) 63 sys_close(sfd) 64 let sz: i64 = cd_filesize(spath) 65 cd_puts("--- nx_cc exit=" as *u8); cd_putn(rc); cd_puts(" .s bytes=" as *u8); cd_putn(sz); cd_puts(" ---\n" as *u8) 66 if sz > 128 { if rc == 0 { cd_puts("VERDICT: .s produced OK -> the source COMPILES; any failure is downstream (nxasm/link) or the known nondeterministic-empty (retry).\n" as *u8); sys_exit(0); return 0 } } 67 cd_puts("VERDICT: EMPTY/short .s -> the REAL cause is the compiler message printed ABOVE (undefined function / parse error / arg-count). Fix the source; it is NOT a mysterious codegen crash.\n" as *u8) 68 sys_exit(0); return 0 69}