[JSC][WASM][Debugger] Fix STW deadlocks when VM blocks in memory.atomic.wait or WebCore operations
da1f31b
Source/WebCore/workers/WorkerSTWParticipation.h
+void waitWithSTWParticipation(BinarySemaphore& semaphore, VM& vm)
+{
+ static constexpr auto kPollInterval = 50_ms;
+ while (!semaphore.waitFor(kPollInterval)) {
+ if (vm.needStopTheWorld())
+ notifyVMStop(vm, VMStopped);
+ }
+}
Source/JavaScriptCore/runtime/WaiterListManager.cpp
- result = waiter.wait(timeout);
+ while (!waiter.waitFor(kDebuggerSTWCheckInterval)) {
+ if (vm.needStopTheWorld())
+ notifyVMStop(vm, WasmAtomicsWaitBlocked); // skips clearStop()
+ if (MonotonicTime::now() >= deadline)
+ break;
+ }
+ clearStop(vm); // only cleared on exit from waitForSync()
The WASM debugger halts all VMs using a Stop-The-World protocol: a global NeedStopTheWorld flag is set and the debugger thread waits until every participating VM decrements an active count by calling notifyVMStop(). JSC normally achieves this through trap check points embedded in the interpreter loop. Worker threads blocked inside memory.atomic.wait or synchronous WebCore operations (which drive their own run loop internally via BinarySemaphore::wait()) never reach a trap check point, so they never call notifyVMStop() — the STW count never reaches zero and the debugger hangs forever.
This commit adds polling-based STW participation at each blocking site via a new waitWithSTWParticipation() helper and modifies WaiterListManager::waitForSync() to poll every 50ms, calling notifyVMStop() when NeedStopTheWorld is set. A new WasmAtomicsWaitBlocked callback type preserves stop state across multiple STW cycles rather than clearing it on each check-in, because the atomics-wait site may be entered across multiple STW cycles before the wait completes.
Significance
The WasmAtomicsWaitBlocked callback deliberately skips clearStop() so stop data persists across multiple STW cycles; any error path that fails to call the compensating clearStop() on exit leaves the debugger looking at stale PC/CFR/stack data for a live, running thread.
Audit directions
a Aaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaaaaa Aaaaa Aaaaa Aaaa Aa Aaaaaaaaaa Aa Aaaaaaaaaaaaaaa Aaaa Aaaaa Aaa Aaaaaaaaaaaa Aaaaaaaaaaaaaa a Aaaaaa Aaaaaa Aaaa Aaaa Aaaa Aaaaaaa Aaaaa Aaaa Aaa Aaaa Aaa Aaaaaa Aaaaaaaaaa Aaa Aaaaaaaaaa Aaaa Aa Aaaaaa Aaaaaa
a Aaaaaaaaaaa Aaaa Aa Aaaa Aaaaaaa Aaaaaaa Aaaaaaa Aaa Aaaaaaaaaaaaaaaaaa Aaaaa Aaa Aaa Aaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aaaaaaaaaaaaaaaa a Aaa Aaa Aaaaaaa Aaa Aaaaaaa Aa Aaa Aaaaaaaa Aaaaaaaaa Aaaaaaaaa Aaa Aaa Aa Aaaaaaaaa Aa Aaaaaa Aaa Aaaa Aaaaa Aa Aaa Aaaa Aa Aaa Aaaaa Aaaaaaaa Aa Aaaa Aaaaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaa Aaaaa Aaaaaaaa
a Aaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaaa Aaaa Aa Aaaaaaaaaaaa Aaaa Aaaaaaaaaaaaa Aa Aaaaaaaa Aaaaaaa Aaa Aaaa Aa Aaa Aaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaa Aaaaaaaa Aaaaaaaaaaa Aaaaaa Aaaaaaaa Aaaaa Aaa Aaaaaa Aaaaaa Aaa Aaaaaaaa Aaaaaaaa Aaaaaaa Aa Aaa Aaaa Aaaaaaaaaaaa Aaa Aaaaaa Aaa Aaaaaaa Aaaa Aaa Aaaaaaaa Aaaa Aaaaaa
a Aaaaaaaaaa Aaaaaaaaa Aaaaaaaaa Aaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaa Aaaaaaaa Aaaa Aaa Aaa Aaaaaa Aa Aaa Aaaaaaaa Aaaaaaa Aaa Aaaaa Aaaaaaaaa Aaaaa Aaaaa Aaa Aaa Aaaaaaaaaaaa Aaaaa a Aaaaaaaa Aaaaaaa Aaaa Aaa Aaa Aaaaaa Aaa Aaaa Aaa Aaa Aaaa Aaaa Aaaaa Aa Aaaa Aaaa Aaaaa Aaaaaa Aaa Aaaaa Aaaaaaaa Aa Aaa Aaaaaaaaa
a Aaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aaa Aaa Aaaaaaa Aaaaaaaaaa Aaaaaaaaa Aaaaa Aa Aaaaaaa Aaaaaaaaaaaaaaaaa Aaa Aaaaa Aa Aaaaaaaaaaaaaaaa Aaaaaa Aa Aaa Aa Aaaaaa Aaaaaa Aaaaaaaaa Aaaa a Aaaaaa Aa Aaaa Aaaaa Aaaaaaa Aaaaaa Aaaaa
🔒New STW participation paths at multiple blocking sites introduce edge cases in state lifetime and epoch ordering — audit directions included.
Subscribe to read more