Executed reproducer
zig build threadfuzz \
-Dfuzz-lifecycle=true \
-Dfuzz-iters=4 \
-Dfuzz-seed=1027 \
-j1This deterministically reports four failures from 224 generated lifecycle programs:
seed 1027: mixed waiter race threw before teardown point: Error: property notify woke wrong count pn0
seed 1028: mixed waiter race threw before teardown point: Error: property notify woke wrong count pn0
seed 1029: mixed waiter race threw before teardown point: Error: property notify woke wrong count pn0
seed 1030: mixed waiter race threw before teardown point: Error: property notify woke wrong count pn0
threadfuzz lifecycle: 224 programs from seed 1027, 4 failuresThe failure is at conformance/threadfuzz.zig:5618: after every generated waiter has incremented the shared ready count, Atomics.notify(gate, "pn0", 1) returns a count other than one. The script therefore throws before reaching its intentional teardown throw.
Exact-parent control
The same command was run from archive snapshots with identical Zig, zig-gc, and zig-regex inputs on:
- exact parent
b4f5544d61036e296ebd0046579d0b991b509025; - current main
d55b4456(including #1027).
Both produce the same four seeds, message, and 224/4 summary. This is therefore pre-existing and not caused by #1027's scratch-accounting changes.
Control
The deterministic no-GIL correctness profile passes:
threadfuzz verify: 8 programs from seed 1027, 0 failures
threadfuzz verify under unsuppressed TSan: 4 programs from seed 1027, 0 failuresRequired resolution
- Determine whether property-backed
Atomics.waitAsyncpublishes its waiter ticket after returning, or whether readiness/notify has another ordering defect. - Preserve typed-array and property-backed waiter semantics; do not weaken the generated assertion or hide the failure with timing sleeps/retries.
- Add a focused deterministic regression test, then make the lifecycle seeds pass normally and under unsuppressed TSan.
Found while closing #1027; tracked separately because exact parent reproduces identically.