You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 953faee
Browse filesBrowse the repository at this point in the historyBrowse files
[JSC][WASM][Debugger] Fix WasmDebugger RWI lifecycle: init ordering, cache handling, and process exit
https://bugs.webkit.org/show_bug.cgi?id=312094
rdar://174599638
Reviewed by Devin Rousso and BJ Burg.
Init ordering fix: WasmDebuggerDebuggable was created in didFinishLaunching()
before startRWI() was called, so early LLDB packets could arrive before the
debug server was ready. Fix by introducing a WasmDebugServerReady IPC sent
from WebContent after startRWI() succeeds. The UIProcess creates the debuggable
only in wasmDebugServerReady(), guaranteeing the debug server is initialized
before LLDB can attach.
Process cache improvement: Previously nothing happened on cache entry or exit,
leaving the debuggable alive when the process was cached (LLDB stayed attached
to an idle process) and never recreating it on cache reuse. Now on cache entry
the debuggable is destroyed and a ResetServer IPC is dispatched to the
WasmDebuggerDispatcher WorkQueue — which runs independently of the mutator —
to cleanly reset server state. On cache exit, WebContent resends WasmDebugServerReady
so the UIProcess recreates the debuggable for the new navigation.
Process exit fix: destroyWasmDebuggerTarget() is now called before shutDownProcess()
in shutDown() so LLDB is notified via RemoteInspector and detaches cleanly before
the WebContent process is killed.
Make DebugServer::reset() public so WasmDebuggerDispatcher can call it directly.
Change DebugServer::startRWI() to return void since it always succeeds.
Remove m_createWasmDebuggerDebuggable and move the enableWebAssemblyDebugger
parameter from WebProcessProxy::create() into initializeNewWebProcess(), since
debuggable creation is now driven by WasmDebugServerReady rather than launch.
Add a complete Component Lifecycle section to RWI_ARCHITECTURE.md.
Canonical link: https://commits.webkit.org/311292@main
-Calls `DebugServer::singleton().startRWI()` in `initializeWebProcess()` and sends `WasmDebugServerReady` IPC on success
82
82
- Sets up response handler for IPC communication
83
83
84
84
### JavaScriptCore (JSC)
@@ -113,21 +113,109 @@ WasmDebugServer (JSC)
113
113
114
114
**Key Points:**
115
115
- External client relays raw GDB packets between LLDB and WebKit
116
-
- Target registration: WebProcessProxy creates `WasmDebuggerDebuggable` with auto-assigned numeric Target ID and name showing OS PID
116
+
- Target registration: WebProcessProxy creates `WasmDebuggerDebuggable`in `wasmDebugServerReady()` (after `WasmDebugServerReady` IPC) with auto-assigned numeric Target ID and name showing OS PID
117
117
- IPC routing: Messages dispatched to WorkQueue in WebContent Process, NOT main thread
118
-
- WorkQueue enables debugging when main thread blocked in infinite loop
118
+
- WorkQueue enables debugging when main thread is blocked
**Key invariant**: The `WasmDebuggerDebuggable` is created only after `startRWI()` succeeds in the WebContent process. This guarantees that when LLDB attaches and sends packets, the `WasmDebugServer` is fully initialized and ready to handle them.
150
+
151
+
### Process Cache Entry
152
+
153
+
When a tab navigates away and the WebContent process enters the process cache:
**Why WorkQueue, not main thread**: The WorkQueue thread runs independently of the JS/Wasm mutator. If the main VM is stopped at a breakpoint when the tab closes, the main thread is unresponsive and cannot process IPCs. The WorkQueue handles `ResetServer` regardless, and `reset()` resumes the stopped VM before clearing state.
170
+
171
+
**STW invariant**: Stop-the-world stops ALL mutators simultaneously. If any VM is stopped (blocked in `stopCode()`), the main thread is also stopped — making it impossible to process `SetIsInProcessCache`. Therefore, when `setIsInProcessCache` runs on the main thread, no VM can be blocked in `stopCode()`, and the WorkQueue is always idle and ready to receive `ResetServer`.
172
+
173
+
### Process Cache Exit
174
+
175
+
When a cached process is reused for a new navigation:
The `WasmDebugServer` itself never stops — it is a process-lifetime singleton. Only the `WasmDebuggerDebuggable` (the RWI target visible to LLDB) is destroyed on cache entry and recreated on cache exit.
187
+
188
+
### Process Exit (No Cache)
189
+
190
+
When the WebContent process exits normally (tab closed, no process cache):
191
+
192
+
```
193
+
UIProcess (main thread)
194
+
────────────────────────
195
+
shutDown()
196
+
if m_wasmDebuggerDebuggable:
197
+
destroyWasmDebuggerTarget()
198
+
- detach from RemoteInspector
199
+
shutDownProcess()
200
+
```
201
+
202
+
The debuggable is destroyed before the process is killed so LLDB detaches cleanly
203
+
via RemoteInspector before the connection drops. No ResetServer IPC is needed —
204
+
all WebContent process state is discarded on exit.
0 commit comments