#306 asdf fasl replay: 'assertion failed' aborts the load at uiop/lisp-build's define-package (next layer after cave#304)

closed
Opened by atgreen

Residue after cave#304 (2beac09). The asdf fasl replay now clears uiop/image completely — image-restore-hook holds the real 5-hook list, the hooks run — and aborts with:

; Error: assertion failed | in: LOAD

Post-abort state: session left in UIOP/IMAGE, (find-package "UIOP/LISP-BUILD") = NIL — so the abort is at/inside uiop/lisp-build's define-package CO-RUN (asdf.lisp:5197), the first action after uiop/image's forms. uiop's ensure-package machinery contains (assert …) forms; at source-load the same define-package succeeds, so some input to one of those asserts diverges at replay (likely another door/identity split in the package graph the replayed ensure-package sees — use/export state accumulated by the preceding 9 uiop packages).

Repro: (fasl-compile "asdf.lisp" X) ~250s, then (load X) in a fresh image, 0.15s. Next step: funcl's assert signals a bare 'assertion failed' with no form context — either enrich assert's report with the failing form, or gdb-watchpoint handler-condition (0x1000018) during the cheap replay and walk back to the raising assert site. The onion pattern (#302→#303→#304→this) says expect more layers behind it; each fix so far has been a one-door unification.

Comments (1)

atgreen3992948269

FIXED in f9c6e27. The 'assertion failed' was uiop's (assert (plusp (length filename))) in split-name-type — reached because EVERY (equal x "") in replayed asdf code misfired. Root cause: load-read-bv returns NIL for a ZERO-LENGTH payload (the absent-field convention the optional home-pkg field and thunk CO names rely on), so a KIND-5 reloc for an EMPTY STRING literal interned NIL into the string pool and the lea patched to a corrupt record (the fasl-loaded "" made even PRIN1/TERPRI raise 'not a byte-vector' in a 5-line micro-repro). split-unix-namestring-directory-components then classified "/tmp/" as (:RELATIVE ("" "tmp") "" NIL) — three failed ""-comparisons in one function — and setup-temporary-directory (running now that cave#304 made the restore hooks fire) handed "" to split-name-type.

Fix: load-read-content-bv materializes zero-length CONTENT payloads as real empty bvs, used at the KIND-5 arm, the serialized-form tag-4 string reader, and the patch-list reader; CO-name/home-pkg sites keep nil-for-absent.

Bonus: (assert TEST) now reports 'assertion failed: TEST' via a runtime %assert-fail reporter — the expansion-time first cut broke stage1's tree-walker macro path (funcl-stage1-compiles-asdf-lisp SEGV), so the macro body stays list/quote-only and formats at raise time.

Replay progress: uiop/image → asdf/source-registry (~8600 lines further); setup-temporary-directory => #P"/tmp/". The NEXT layer (distinct, filed separately): WILD resolves from ASDF/SOURCE-REGISTRY to an UNBOUND package-own twin while UIOP/PATHNAME's record holds :WILD — wild-asd's defparameter init dies with 'the value is not a sequence' (length of the unbound marker). Gates: sharded suite 8/8, spike oracle green, --hosted 42, fixed point held.