#240 asdf load: wild jump (SIGSEGV at unmapped-symbol rip) right after uiop's WITH-TEMPORARY-FILE defmacro

closed
Opened by atgreen

Next domino after cave#239 (define-package accumulator fix, f2cb3c7). Loading ./asdf.lisp in build/funcl now proceeds through all uiop define-package forms and deep into uiop/stream, then SIGSEGVs immediately after the WITH-TEMPORARY-FILE defmacro echoes.

gdb: fault rip=0x40812ed7 — arena address with NO symbol (not a known function); backtrace frames are garbage (0x592b000000000000, 0x80b634c41...); rax=0x41000000004081 at fault. This is a jump/call through a corrupted or misresolved function pointer (or execution of data), not a data-access fault like #239.

Repro: printf '(load "./asdf.lisp")\n' | build/funcl (deterministic, ~2 min to reach). gdb transcript at /tmp/asdf-gdb.txt (2026-07-06 session).

Suggested start per the playbook: break on the last named function before the wild jump (watch the loader echo to find the form being EXECUTED — the defmacro after WITH-TEMPORARY-FILE), and check the fn-table/backpatch resolution for the callee — rax's shape (0x41 in the high byte, 0x4081 low) smells like a partially-written or byte-shifted code pointer.

Comments (2)

atgreen3992386496

ROOT CAUSE FOUND (and it retro-explains #239 too). Not a corrupted code pointer: the compiled hosted expander for uiop's with-temporary-file null-tests and SPREADS a symbol record where the local alias BEFORE should be read — the variable compiled as a quoted constant.

Chain: ag-image-rebuild-symbol-pool-offsets-range (src/warm/image.lisp, restore path, 'ADR 0026 collapse door 7') rebuilds ag-symbol-pool-offsets from the kind-symbols root ranges with NO home-pkg filter — while ag-warm-pool-scan-range (reader.lisp) explicitly carries the Phase 5 hardening for exactly this ('a name-only match lets a keyword record shadow a same-named CL lookup'). On the restored image, every prelude-quoted keyword lands in the SYMBOL offsets map under its stripped name (":BEFORE" under "BEFORE", ":EXPORT" under "EXPORT", ...). ag-canon-hosted-sym then swaps hosted-macro arg symbols to keyword records; ir-lower-atom correctly quotes keywords as self-evaluating; (when before ...) is never false and ,@before spreads a 40-byte symbol record as a list -> reads its interior bytes as car/cdr -> SEGV.

Probes: (ag-runtime-pooled-symbol-ptr "BEFORE") -> keywordp=T, baked=-1 (why the #239 baked-first fix didn't cover it; "EXPORT" was baked so it got fixed incidentally). stage2 unaffected (no image restore) — completes the full asdf load.

5-line deterministic repro (/tmp/w6.lisp): (defmacro m (keep &body body) (let ((before body)) (f (,@(when before ((g ,@before))))))) (defun u (&key (keep t)) (m keep 42))

Fix: mirror the Phase 5 home-pkg = primordial-CL guard in ag-image-rebuild-symbol-pool-offsets-range. Rebuilding + gating now.

atgreen3992386698

Fixed in c3cfdd5 (home-pkg filter in ag-image-rebuild-symbol-pool-offsets-range). All 14 reduced repros pass, suite 8/8, hosted gate 42, fixed point held. asdf load on build/funcl now advances from uiop/stream (~line 4600) to asdf/bundle (~line 11945) — the next blocker (core dump right after the asdf/bundle define-package) is a separate issue, filing next.