ReviewOS

home-lang/home

Bun parity: fix fdleak_ls child segmentation fault

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

Scope

Fix the native shell ls -R lifecycle crash exposed by Bun's unchanged fd-leak stress matrix. The generated child completes repeated shell work but exits with status 139 in fdleak_ls.

Evidence

Validated against Bun checkout 4982b91e3702094330f3be3883354c52b8c01323 with Home invoked through the same absolute-executable contract used by bunExe():

HOME_NATIVE_VM=1 HOME_CORPUS_FULL_VM=1 /Users/chris/Code/Home/lang-bun-port/zig-out/bin/home test packages/runtime/test/test/js/bun/shell/leak.test.ts

Result: 41 pass and 1 fail. The sole failing test is fd leak > fdleak_ls; its child exits 139 after the recursive-listing stress loop. All memory-leak cases, other fd-leak cases, issue #11816 checks, and never-run interpreter lifecycle checks pass unchanged.

The earlier 4-pass/38-fail observation used a relative ./zig-out/bin/home invocation. Bun and Home both preserve the original invocation string in process.argv0; changing cwd therefore made that ad hoc command unspawnable. That was a probe setup error, not a runtime parity gap.

Acceptance criteria

  • Identify and fix the native lifetime or ownership fault behind the fdleak_ls child exit 139.
  • Pass all 42 unchanged upstream cases with their original iteration counts, heap checks, fd thresholds, and deadlines.
  • Do not rewrite the fixture, force a repository cwd, skip the case, reduce the 500-iteration ls -R workload, or mask the signal.
9 days ago

Correction after a harness-equivalent rerun: Bun and Home both preserve the original invocation string in process.argv0. Invoking Home by absolute path removes the artificial ENOENT failures and yields 41 pass / 1 fail. I updated this issue to track the actual remaining fdleak_ls exit-139 crash.

9 days ago

Resolved by fe85ff1.

The failure was a real intermittent use-after-free in Homes VM shutdown barrier, not an argv0 problem. A macOS crash report captured EXC_BAD_ACCESS on Bun Pool 0 in ShellTouchTask.runFromThreadPool while calling EventLoopHandle.completeNativeWorkPoolJob; the fault address carried the allocator poison pattern. The event-loop completion could run and destroy the shell task immediately after enqueue, after which the worker dereferenced this.event_loop.

The fix preserves the EventLoopHandle by value before transferring task ownership, then releases the native-work admission through that stable value. The same unsafe sequence was corrected in touch, mkdir, glob expansion, and nested-shell workers; rm, cp, and ls already used a preserved handle.

Validation:

  • pre-fix unchanged full leak matrix reproduced the fault: 41 pass, 1 fail (fdleak_ls, child exit 139)
  • post-fix unchanged full leak matrix passed 42/42 three consecutive times (126/126 total)
  • ReleaseFast/JSC install build passed
  • final home_rt: substrate compiles: 4/4 passed.
9 days ago

Follow-through pushed in f5ceee0: the now-green unchanged js/bun/shell/leak.test.ts is routed through the native Home corpus runner, and its blanket TODO rewrite has been removed. The router regression locks 42 pass, 0 TODO, 0 fail, and 0 unsupported. A fourth consecutive full native run passed 42/42, bringing post-fix stress coverage to 168/168 tests.

Sign in to comment on this issue.