FAILURE MAP
← Case archive

FA-90384 / Garbage collector invariants / Member archive

Reference counting: control block freed while weak references remain · case 04

A later upgrade or unweak through a surviving weak reference touches freed memory.

Member previewVariant 4 · 3 implementations · 7 checks per implementation

Case contract

Objects carry a strong count and a weak count. new id k: strong 1 (the creating reference), k null fields. drop id: release one strong reference. store src i dst: retain dst, then write, then release the old value. When the strong count reaches 0 the object is destroyed (recorded in freed, its fields released recursively in field order) and, if no weak references remain, its control block is deallocated too; unweak deallocates a destroyed object's block when the last weak reference goes. upgrade id succeeds (and adds a strong reference) only while the strong count is positive. Touching a deallocated block reports "use-after-free".

Why this case matters

Reference-counting collectors must order retains and releases and separate destruction from deallocation.

One recorded failure

Sample boundary fixture

This sample comes from the broken implementation of a controlled reproducer.

Boundary fixtureActualExpectedOutcome
upgrade after the last strong reference dies{"dealloc": [41], "freed": [41], "out": ["use-after-free"], "rc": {}}{"dealloc": [41], "freed": [41], "out": [false], "rc": {}}Failed

MEMBER ARCHIVE

The complete case is available to members.

This record includes three runnable implementations, regression fixtures, execution results, and source hashes.

Member access is invitation-based. Sign in with your invited account to inspect the sources.

Sign in to the archive ↗