Skip to content

GC: #7207's spread-accessor reproducer still SIGSEGVs on main under the evac_minor arm (allocation-point relocation, not the safepoint route) #7217

Description

@proggeramlug

Summary

test-files/test_gap_gc_spread_accessor_rooting.ts — the reproducer #7207 added for #7200still SIGSEGVs on current main (1679e22b4) when the collection is forced at the allocation point rather than at a loop safepoint.

#7207 verified that fix on the PERRY_GC_MOVING_LOOP_POLLS=1 route, where it is clean 5/5. It is not clean on the evac_minor arm env.

Reproduction

$ export PERRY_RUNTIME_DIR=<main build>/release PERRY_NO_AUTO_OPTIMIZE=1
$ perry test-files/test_gap_gc_spread_accessor_rooting.ts -o /tmp/spread     # no compile-time env
$ PERRY_GC_HEAP_LIMIT=8 PERRY_GC_INCREMENTAL=0 PERRY_CONSERVATIVE_STACK_SCAN=off /tmp/spread
exit=139, no output

Compared against a build of PR #7216 on the same host under identical conditions: byte-identical, exit=139, output md5 d41d8cd9… on both. So this is main's behaviour, not #7216's, and #7216's A/B is what surfaced it.

test_gap_gc_static_block_this_rooting (the #7201 reproducer) reports bad 1 under the same env, also identically on both arms — the same story one notch quieter.

Why the two routes differ

gc_repsel_matrix.sh's own header states it: default and the polls route "relocate at a real safepoint (the JS stack has unwound, roots are precise by construction)", whereas the %E% arms "force it at the register-imprecise allocation point". #7207's fixes — the RuntimeHandleScope rooting inside js_object_assign_one and the codegen accumulator root — were reasoned about and verified against the safepoint route. An allocation-point collection inside the helper is a different window: it can fire between any two of the helper's own allocations, including ones inside object_assign_set_string_key's interning and keys-array growth, where #7207 re-reads its handles only at the top of each key iteration.

Caveat, stated because it changes what to do first

Both observations were made while a second agent's build was loading the box. In #7207's own idle --arms all --pressure 8 run this cell was PASS on evac_minor. So the failure is load-dependent, and the first step is an idle reproduction, not a fix — a load-dependent SIGSEGV that disappears when idle is still a real defect (it is the classic #7154 timing signature), but the mechanism should be pinned before anyone changes rooting code on the strength of it.

If it reproduces idle, the natural next instrument is #7196's PERRY_GC_PROTECT_FROMSPACE quarantine, which is built to fault at the stale dereference rather than one cycle later.

Why it matters

This is a residual of #7200, which #7207 reported as closed. It does not reopen the loop_polls result — that remains clean 5/5 — but it means the #7161 revert readiness statement should count the allocation-point route as unverified for the object-spread path, not merely the sites #7208/#7209/#7210 name.

Refs #7207, #7200, #7154, #7161, #7216, #7196.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions