WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED DUPLICATE of
bug 312782
312587
[WPE] REGRESSION(
311266@main
): SkiaGPUAtlas::uploadImages RELEASE_ASSERT crashes WebProcess when GPU buffer mmap fails
https://bugs.webkit.org/show_bug.cgi?id=312587
Summary
[WPE] REGRESSION(311266@main): SkiaGPUAtlas::uploadImages RELEASE_ASSERT cras...
Yury Semikhatsky
Reported
2026-04-17 10:08:25 PDT
Created
attachment 479150
[details]
test page We discovered this as a crash when running playwright tests in headless mode. The issue seems specific to Nvidia drivers as clopez was not able to reproduce it locally. Below is a detailed summary.md from Claude. I tried it myself in the dev container and can confirm that the release assert turned into return false, the crash is gone, but the rendered content is garbage (in headed mode). # [WPE] SkiaGPUAtlas::uploadImages RELEASE_ASSERT crashes WebProcess when GPU buffer mmap fails ## Summary [
311266@main](https://commits.webkit.org/311266@main
) (commit [`31dab2d9da5a`](
https://github.com/WebKit/WebKit/commit/31dab2d9da5a0b131f329b57f774e24d1266f1b9
), "[GBM] REGRESSION(
310393@main
): Always use DRM_RDWR when exporting dma-buf FDs for GPU buffer mapping") added a `RELEASE_ASSERT_WITH_MESSAGE` at the failure-to-map path in `SkiaGPUAtlas::uploadImages()`:
https://github.com/WebKit/WebKit/blob/main/Source/WebCore/platform/graphics/skia/SkiaGPUAtlas.cpp#L125-L126
```cpp auto writeScope = makeGPUBufferWriteScope(*gpuBuffer); RELEASE_ASSERT_WITH_MESSAGE(writeScope, "Failed to map GPU buffer for atlas upload"); ``` The assert assumes that, after
311266@main
enforced `DRM_CLOEXEC | DRM_RDWR` on the exported dma-buf FD, `makeGPUBufferWriteScope()` never returns null. That is not true in practice: real-world GBM/driver combinations can still return dma-buf FDs that cannot be `mmap`'d for writing, in which case `MemoryMappedGPUBuffer::mapIfNeeded()` returns false, `AccessScope::create()` returns nullptr, and the assert aborts the WebProcess on any page that batches images through the Skia atlas. Before
311266@main
the caller returned `false` and the atlas code fell through to the GL upload path. ## Environment where we see it - Linux (Ubuntu 24.04, kernel 6.8). - NVIDIA GPU with the proprietary userland driver; Mesa GBM is the system GBM implementation. - Headless WPE WebKit run **outside of `webkit-container-sdk`** (i.e. Playwright's build of playwright-webkit). - libEGL prints during WebProcess startup: ``` libEGL warning: failed to get driver name for fd -1 libEGL warning: MESA-LOADER: failed to retrieve device information ``` i.e. GBM side succeeds enough to produce an `m_atlasTexture` with a non-null `memoryMappedGPUBuffer()`, while the subsequent writable mmap fails. ## Deterministic repro via test hook The crash only manifests on specific driver/Mesa combinations; to make this reproducible on any GBM-capable host, apply the attached [`simulate-mmap-failure.patch`](simulate-mmap-failure.patch) which adds an opt-in environment-variable hook to `MemoryMappedGPUBuffer::mapIfNeeded()`: ```diff + if (const char* env = getenv("WEBKIT_SIMULATE_GPU_BUFFER_MMAP_FAILURE"); env && *env == '1') + return false; ``` This emulates exactly what the affected environment does: return false from `mapIfNeeded()` so `AccessScope::create()` / `makeGPUBufferWriteScope()` return nullptr, hitting the RELEASE_ASSERT. Steps: 1. Apply `simulate-mmap-failure.patch`. 2. Build WPE: ``` Tools/Scripts/build-webkit --wpe --release ``` 3. Run MiniBrowser on the attached [`grid.html`](grid.html) (a self-contained page of ~200 small `<img>` elements from 11 distinct canvas-generated data URLs, matching the structure that populates the Skia image atlas): ``` WEBKIT_SIMULATE_GPU_BUFFER_MMAP_FAILURE=1 \ WebKitBuild/WPE/Release/bin/MiniBrowser --headless file:///path/to/grid.html ``` 4. The WebProcess aborts on `SkiaGPUAtlas.cpp:126`. Verified by tracing (with temporary `fprintf`s at the relevant call sites): ``` [SkiaGPUAtlas::uploadImages called, entries=11] [ has memoryMappedGPUBuffer, linear=1 vivante=0] [ writeScope=(nil), about to RELEASE_ASSERT] <process aborts here> ``` Without the env var (same binary, same HTML): page renders without incident. This confirms the only differing condition is the null `writeScope`. ## Evidence this is the real regressing commit Bisected over the 336 commits between two consecutive weekly Playwright WebKit rolls. The crash flips exactly at
311266@main
. The only other candidate in the final bisect step (
311265@main
) is a no-op `IGNORE_WARNINGS` pragma change with no runtime effect. Reverting just the assert (keeping the rest of
311266@main
intact): ```diff - RELEASE_ASSERT_WITH_MESSAGE(writeScope, "Failed to map GPU buffer for atlas upload"); + if (!writeScope) + return false; ``` fixes ~40 previously-crashing tests in the Playwright WebKit test suite with no other change. ## Suggested fix Two options: 1. **Restore the graceful fallback** (one-line revert of just the assert; this is what we shipped downstream): ```diff - RELEASE_ASSERT_WITH_MESSAGE(writeScope, "Failed to map GPU buffer for atlas upload"); + if (!writeScope) + return false; ``` The caller falls through to the existing GL atlas upload path. The original 312266 bug was about the *contents* of a successful mmap being wrong (because `DRM_RDWR` was missing); it was never about *handling* a genuinely-failed mmap. The assert is therefore over-broad in scope. 2. If keeping the assert is preferred for diagnostic value, the GBM code path needs to guarantee — beyond the DRM_RDWR fix — that any `gbm_bo` for which `gbm_bo_get_handle_for_plane()` succeeds produces an FD that `makeGPUBufferWriteScope` can actually map writable. The NVIDIA + system-Mesa combination observed here shows that is not today a guarantee. ## Workaround Downstream playwright-webkit ships option 1 as a one-line patch on its rebase-to-main branches until this is resolved upstream. ## Attachments - [`grid.html`](grid.html) — self-contained repro page. - [`simulate-mmap-failure.patch`](simulate-mmap-failure.patch) — opt-in env-var hook that makes the crash deterministic on any host. Not for merging; just for reproducing the bug without the specific broken driver combo.
Attachments
test page
(1.43 KB, text/html)
2026-04-17 10:08 PDT
,
Yury Semikhatsky
no flags
Details
workaround demo
(1.12 KB, patch)
2026-04-17 10:09 PDT
,
Yury Semikhatsky
no flags
Details
Formatted Diff
Diff
View All
Add attachment
proposed patch, testcase, etc.
Yury Semikhatsky
Comment 1
2026-04-17 10:09:37 PDT
Created
attachment 479151
[details]
workaround demo
Carlos Alberto Lopez Perez
Comment 2
2026-04-30 08:30:53 PDT
*** This bug has been marked as a duplicate of
bug 312782
***
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug