Bug 312228
| Summary: | GPU process leaks RemoteRenderingBackend due to retain cycle with RemoteDisplayListRecorder and RemoteSnapshotRecorder maps | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | David Kilzer (:ddkilzer) <ddkilzer> |
| Component: | Compositing | Assignee: | David Kilzer (:ddkilzer) <ddkilzer> |
| Status: | RESOLVED FIXED | ||
| Severity: | Normal | CC: | kkinnunen, sabouhallawa, simon.fraser, webkit-bug-importer |
| Priority: | P2 | Keywords: | InRadar |
| Version: | WebKit Nightly Build | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Bug Depends on: | 282664, 297727 | ||
| Bug Blocks: | |||
David Kilzer (:ddkilzer)
`RemoteRenderingBackend::workQueueUninitialize()` clears `m_remoteImageBuffers` and `m_remoteImageBufferSets` but not `m_remoteDisplayListRecorders` or `m_remoteSnapshotRecorders`. Each `RemoteDisplayListRecorder` (via its `RemoteGraphicsContext` base class) holds a `Ref<RemoteRenderingBackend>`, forming a retain cycle through the `ScopedActiveMessageReceiveQueue` wrappers in the HashMap:
Backend -> `m_remoteDisplayListRecorders` -> `ScopedActiveMessageReceiveQueue` -> `RemoteDisplayListRecorder` -> `Ref<RemoteRenderingBackend>` -> Backend
When `GPUConnectionToWebProcess::releaseRenderingBackend()` destroys the backend's `ScopedActiveMessageReceiveQueue`, `stopListeningForIPC()` calls `workQueueUninitialize()`. Because the display list recorder and snapshot recorder maps are not cleared, the remaining `Ref` back-references prevent the backend's reference count from reaching zero. The backend, its `StreamServerConnection`, `StreamConnectionWorkQueue`, and all unsunk recorders are leaked.
The `m_remoteDisplayListRecorders` map was introduced in Bug 297727 (299747@main) and `m_remoteSnapshotRecorders` in Bug 282664 (300358@main). Neither commit added the corresponding `clear()` call in `workQueueUninitialize()`, unlike the pre-existing `m_remoteImageBuffers` and `m_remoteImageBufferSets` maps which do have `clear()` calls.
The `leaks` tool on a memgraph of the GPU process directly identifies the cycle:
```
ROOT CYCLE: <WebKit::RemoteRenderingBackend 0x...> [448]
ROOT CYCLE: <non-object 0x...> [320]
ROOT CYCLE: <WebKit::RemoteDisplayListRecorder 0x...> [96]
CYCLE BACK TO <WebKit::RemoteRenderingBackend 0x...>
```
The same pattern applies to `m_remoteSnapshotRecorders` via `RemoteSnapshotRecorder` -> `RemoteGraphicsContext` -> `Ref<RemoteRenderingBackend>`.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Radar WebKit Bug Importer
<rdar://problem/174706941>
David Kilzer (:ddkilzer)
Pull request: https://github.com/WebKit/WebKit/pull/62701
EWS
Committed 311189@main (0de81382cce8): <https://commits.webkit.org/311189@main>
Reviewed commits have been landed. Closing PR #62701 and removing active labels.