ReviewOS

home-lang/home

ReleaseFast test runner intermittently exits 139 before third-party fixtures start

#655
Closed chris opened this 9 days ago ·
9 days ago

Parent tracking issue: #66

After restoring the complete N-API/Node-API export surface in ReleaseFast, the js/third_party corpus still shows nondeterministic exit-139 failures before individual files emit a test result. The affected filename changes between otherwise identical serial scans:

  • one scan: four Socket.IO files plus Svelte
  • a later quiescent scan: Pino plus socket.io-middleware

Every affected file passed on immediate standalone retry with the same HOME_NATIVE_VM=1 HOME_CORPUS_FULL_VM=1 environment. Svelte also passed 4/4 with 2,002 assertions under LLDB and then passed directly. The complete Debug scan had 0 crashes.

Current reproducible scan command:

HOME_BIN="$PWD/zig-out/bin/home-release-fast" ./scripts/vm-corpus-scan.sh js/third_party /tmp/third-party.tsv 30

Representative quiescent result:

SUB=js/third_party pass=115 fail=2 crash=2 hang=1 deps=0 oom=0 total=120

The two failures reproduce identically in pinned Bun (Astro missing ../tsconfig.base.json; gRPC missing a configured Rust toolchain), and Prisma exceeds the scanner's generic 30-second bound in both Home and pinned Bun. This issue is specifically for the changing ReleaseFast-only pre-result crashes. Do not mask them with retries, skips, or relaxed scanner classification; identify and fix the underlying optimized runner/runtime race.

9 days ago

Resolved on main by a51416b38 (fix(runtime): retain VM across async publication).

The macOS crash reports made the failure deterministic to diagnose: the triggered worker faulted in VirtualMachine.NativeWorkPoolJobs.complete() through a 0xaaaaaaaa... Zig poison pointer. RuntimeTranspilerStore.TranspilerJob.run() publishes its intrusive job to the JS-thread queue; the JS thread can process and return that job to its pool before run() returns. The worker had deferred this.vm.native_work_pool_jobs.complete(), so it reread this.vm after publication from memory that was already recycled or poisoned.

The fix retains the VM pointer before publishing the job and releases the barrier through that stable owner. The same ownership correction was applied to the four sibling paths with the same publish/free shape: ConcurrentPromiseTask, Archive async tasks, zstd jobs, and PBKDF2 jobs.

Verification without retries, skips, or relaxed deadlines:

  • New real-runtime regression loads 1,024 TypeScript modules and asserts both values and a zero native-job count. The old ReleaseFast binary exited 139 by run 3; the fixed binary passed 64/64 consecutive runs.
  • The unchanged Svelte corpus fixture (4 tests / 2,002 assertions per run) exited 139 on the old binary by run 5; the fixed binary passed 100/100 consecutive runs.
  • Focused transpiler/concurrent-Promise/Archive/PBKDF2/zstd/crypto worker regressions pass in Debug and ReleaseFast.
  • Complete installation-shaped ReleaseFast native runtime regression suite: 65/65.
  • Complete strict ReleaseFast js/third_party scan: 117 ordinary file passes, 2 upstream-environment failures, 1 generic-bound overrun, 0 crashes (120 files total). The two failures and Prisma overrun retain their previously documented pinned-Bun/environment classifications.
  • Debug and ReleaseFast builds pass.

No upstream fixture, assertion, annotation, workload, deadline, or skip was changed.

Sign in to comment on this issue.