-
-
Notifications
You must be signed in to change notification settings - Fork 63
Description
Problem
testJSWrapperIsDeallocatedAfterFinalization intermittently crashes in CI with:
RuntimeError: memory access out of bounds
at _swift_release_dealloc
at swift_nonatomic_release
at swift_release
at $s20BridgeJSRuntimeTests19_bjs_Greeter_deinityySvF
at bjs_Greeter_deinit
at swiftHeapObjectFinalizationRegistry (bridge-js.js)
at FinalizationRegistry.cleanupSome (<anonymous>)
Sometimes the error is table index is out of bounds instead of memory access out of bounds, but the stack is identical.
Frequency
Examples from main:
- https://github.com/swiftwasm/JavaScriptKit/actions/runs/22139006233/job/63998050226
- https://github.com/swiftwasm/JavaScriptKit/actions/runs/22134917335/job/63984008406
Also hits PRs with no related changes (e.g. #656).
Origin
Introduced in #648 (merged Feb 18), which added the shared swiftHeapObjectFinalizationRegistry and the testJSWrapperIsDeallocatedAfterFinalization test. The first failure was the very next CI run after that merge (run 22134917335, commit b10bee6).
The hasReleased guard added in that PR prevents double-release, but doesn't protect against calling into Wasm after the instance's memory is no longer valid.
Root cause
After all tests complete, Node.js starts shutting down and V8 GC collects remaining SwiftHeapObject JS wrappers. The FinalizationRegistry callback fires and calls state.deinit(state.pointer), which is a Wasm export (bjs_Greeter_deinit). That calls Unmanaged<Greeter>.fromOpaque(pointer).release(), which triggers swift_release -> _swift_release_dealloc.
At this point the Wasm linear memory or function table is already in an invalid state (the Swift runtime may have already run its own cleanup during process teardown), so the release crashes.
The test itself explicitly triggers GC and waits for finalization in a loop (lines 48-56 of SwiftClassSupportTests.swift). The non-deterministic part is whether GC runs the finalizer before or after Wasm teardown begins.
Environment
- Node.js v20.20.0 on ubuntu-22.04
- Swift 6.1 release toolchain