You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found while validating PR #7136's GC-survival test (macOS arm64, deterministic under --test-threads=1, using only documented FFI):
perry_ffi::alloc_object() followed by a later gc_collect_minor() in the same process makes the copying collector walk a bogus slot (0x9) and SIGSEGV in gc::copying::scan_slot.
Why this matters
Reachable through the documented FFI surface alone — any ext crate that allocates an object and later experiences a copying minor can hit it.
let obj = perry_ffi::alloc_object(/* … */);// … later, same process:gc_collect_minor();// SIGSEGV in gc::copying::scan_slot walking slot value 0x9
Deterministic single-threaded. Observed on macOS arm64; not yet reproduced on Linux (untested, not ruled out).
Suggested first checks
Does perry_ffi::alloc_object zero/initialize payload slots (or set a layout state that keeps the scanner out of uninitialized ones)? Compare against the compiled-TS allocation path's initialization.
Found while validating PR #7136's GC-survival test (macOS arm64, deterministic under
--test-threads=1, using only documented FFI):perry_ffi::alloc_object()followed by a latergc_collect_minor()in the same process makes the copying collector walk a bogus slot (0x9) and SIGSEGV ingc::copying::scan_slot.Why this matters
0x9looks like a tag-pattern or uninitialized word being treated as a heap slot — same family as the uninitialized-capacity findings (gc: run the allocation-point GC trigger outside the&mut Arenaborrow (#7022) #7050: uninit bytes in unused array capacity decoding as pointers; fix(runtime): zero-fill new Uint8Array(n) — buffer_alloc returns reclaimed dirty memory #6429:new Uint8Array(n)returning uninit memory). The FFI object-alloc path plausibly leaves payload slots unwritten where compiled-TS construction would initialize them, and the copying scanner then dereferences garbage.Repro shape
Deterministic single-threaded. Observed on macOS arm64; not yet reproduced on Linux (untested, not ruled out).
Suggested first checks
perry_ffi::alloc_objectzero/initialize payload slots (or set a layout state that keeps the scanner out of uninitialized ones)? Compare against the compiled-TS allocation path's initialization.layout_note_slot/SIDE_MASKstate for FFI-allocated objects matches whatheap_payload_slot_selectionassumes (cf. fix(gc): keep live array elements traced and initialize unused array capacity #7138's stale-POINTER_FREEfix — same selection machinery).