Split out of the post-#7019 matrix re-measurement. New red, attributed to #7019 by A/B on the same source and compiler.
Symptom
test_gap_repsel_gc_stress — the corpus member deliberately built to be GC-live — SIGSEGVs (exit 139) in 12 of 20 arms of scripts/gc_repsel_matrix.sh --arms all --pressure 8. It produces zero stdout lines against an oracle of 7.
The failing arm set is exactly the 12 arms that carry PERRY_CONSERVATIVE_STACK_SCAN=off (directly, or via the %E% evacuating base): evac_minor, force_evac, force_verify, cons_scan_off, cons_scan_off_force, loop_polls, and the six rep_*_off arms. The other 8 arms pass.
This is a PASS → FAIL transition, not an inert cell going red. test-parity/gc_repsel_triage.txt records this file's cons_scan_off cells as green hard gates since #6951, and the last pre-#7019 full matrix (#7015, base 4ad27a15b) had FAIL=20 consisting only of the two #6981 rows.
Attribution — measured, not inferred
Same source, same compiler binary, A/B'd through #7019's own kill switch with PERRY_GC_MOVING_LOOP_POLLS=0 set at both compile and run time (the runtime and codegen halves must match — see the comment on gc_moving_loop_polls_enabled). Config PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off:
| build |
exit codes (5 consecutive runs) |
output |
| default (#7019 on) |
139 139 139 139 139 |
truncated |
PERRY_GC_MOVING_LOOP_POLLS=0 (#7019 off) |
0 0 0 0 0 |
byte-exact vs node 26.5.0 |
Deterministic, 23/23 crashes observed with #7019 on across repeated batches; 0/11 with it off. Reproduced on two hosts and by the matrix harness itself (exit=139 cycles=27 moved=1727552, identical across all 12 arms and across re-runs).
Where it dies
Immediately after a successful evacuating minor — the last three stderr lines before the fault:
[gc-copy-minor] eligible=true fallback=none
[gc-copy-minor] ran copied_objects=101215 copied_bytes=4594776 promoted_objects=44933 promoted_bytes=2039816 freed_bytes=14384
[gc-step] pre_in_use=10790856 post_in_use=10776472 sweep_freed=14384 block_reclaim=14384 pct=0% step=1073741824→1073741824
[gc] cycle
So relocation completed and the mutator faulted afterwards — the shape of a survivor reference that was moved but not rewritten, or a root the copying minor did not see. Note promoted_objects=44933: this cycle both copies and promotes, so the old-gen handoff path is in play as well.
Why this one matters more than a normal corpus row
gc_stress is the only corpus member that holds each representation-selected local live across escaping allocation churn heavy enough to reach the collector. With it crashing, the 12 arms that were the strongest evidence in the matrix now assert nothing about representation safety under relocation — they assert only that the process dies.
Environment: origin/main @ 4340bffc9, release build, macOS arm64 (reproduced on both a 64 GB and an 8 GB host), node 26.5.0 pinned.
Related: #6981 (same PERRY_CONSERVATIVE_STACK_SCAN=off discriminator, different rows), #6982 (a different, intermittent gc_stress SIGSEGV with the conservative stack scan ON), #7019.
Split out of the post-#7019 matrix re-measurement. New red, attributed to #7019 by A/B on the same source and compiler.
Symptom
test_gap_repsel_gc_stress— the corpus member deliberately built to be GC-live — SIGSEGVs (exit 139) in 12 of 20 arms ofscripts/gc_repsel_matrix.sh --arms all --pressure 8. It produces zero stdout lines against an oracle of 7.The failing arm set is exactly the 12 arms that carry
PERRY_CONSERVATIVE_STACK_SCAN=off(directly, or via the%E%evacuating base):evac_minor,force_evac,force_verify,cons_scan_off,cons_scan_off_force,loop_polls, and the sixrep_*_offarms. The other 8 arms pass.This is a PASS → FAIL transition, not an inert cell going red.
test-parity/gc_repsel_triage.txtrecords this file'scons_scan_offcells as green hard gates since #6951, and the last pre-#7019 full matrix (#7015, base4ad27a15b) hadFAIL=20consisting only of the two #6981 rows.Attribution — measured, not inferred
Same source, same compiler binary, A/B'd through #7019's own kill switch with
PERRY_GC_MOVING_LOOP_POLLS=0set at both compile and run time (the runtime and codegen halves must match — see the comment ongc_moving_loop_polls_enabled). ConfigPERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off:139 139 139 139 139PERRY_GC_MOVING_LOOP_POLLS=0(#7019 off)0 0 0 0 0Deterministic, 23/23 crashes observed with #7019 on across repeated batches; 0/11 with it off. Reproduced on two hosts and by the matrix harness itself (
exit=139 cycles=27 moved=1727552, identical across all 12 arms and across re-runs).Where it dies
Immediately after a successful evacuating minor — the last three stderr lines before the fault:
So relocation completed and the mutator faulted afterwards — the shape of a survivor reference that was moved but not rewritten, or a root the copying minor did not see. Note
promoted_objects=44933: this cycle both copies and promotes, so the old-gen handoff path is in play as well.Why this one matters more than a normal corpus row
gc_stressis the only corpus member that holds each representation-selected local live across escaping allocation churn heavy enough to reach the collector. With it crashing, the 12 arms that were the strongest evidence in the matrix now assert nothing about representation safety under relocation — they assert only that the process dies.Environment:
origin/main@4340bffc9, release build, macOS arm64 (reproduced on both a 64 GB and an 8 GB host), node 26.5.0 pinned.Related: #6981 (same
PERRY_CONSERVATIVE_STACK_SCAN=offdiscriminator, different rows), #6982 (a different, intermittentgc_stressSIGSEGV with the conservative stack scan ON), #7019.