<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>312587</bug_id>
          
          <creation_ts>2026-04-17 10:08:25 -0700</creation_ts>
          <short_desc>[WPE] REGRESSION(311266@main): SkiaGPUAtlas::uploadImages RELEASE_ASSERT crashes WebProcess when GPU buffer mmap fails</short_desc>
          <delta_ts>2026-04-30 08:30:53 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WPE WebKit</component>
          <version>WebKit Nightly Build</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Linux</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>DUPLICATE</resolution>
          <dup_id>312782</dup_id>
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=312266</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Yury Semikhatsky">yurys</reporter>
          <assigned_to name="Nikolas Zimmermann">zimmermann</assigned_to>
          <cc>bugs-noreply</cc>
    
    <cc>clopez</cc>
    
    <cc>zimmermann</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>2201570</commentid>
    <comment_count>0</comment_count>
      <attachid>479150</attachid>
    <who name="Yury Semikhatsky">yurys</who>
    <bug_when>2026-04-17 10:08:25 -0700</bug_when>
    <thetext>Created attachment 479150
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),
&quot;[GBM] REGRESSION(310393@main): Always use DRM_RDWR when exporting dma-buf
FDs for GPU buffer mapping&quot;) 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, &quot;Failed to map GPU buffer for atlas upload&quot;);
```

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`&apos;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&apos;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(&quot;WEBKIT_SIMULATE_GPU_BUFFER_MMAP_FAILURE&quot;); env &amp;&amp; *env == &apos;1&apos;)
+        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 `&lt;img&gt;` 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]
   &lt;process aborts here&gt;
   ```

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, &quot;Failed to map GPU buffer for atlas upload&quot;);
+            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, &quot;Failed to map GPU buffer for atlas upload&quot;);
   +            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.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2201571</commentid>
    <comment_count>1</comment_count>
      <attachid>479151</attachid>
    <who name="Yury Semikhatsky">yurys</who>
    <bug_when>2026-04-17 10:09:37 -0700</bug_when>
    <thetext>Created attachment 479151
workaround demo</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2206262</commentid>
    <comment_count>2</comment_count>
    <who name="Carlos Alberto Lopez Perez">clopez</who>
    <bug_when>2026-04-30 08:30:53 -0700</bug_when>
    <thetext>

*** This bug has been marked as a duplicate of bug 312782 ***</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>479150</attachid>
            <date>2026-04-17 10:08:25 -0700</date>
            <delta_ts>2026-04-17 10:08:25 -0700</delta_ts>
            <desc>test page</desc>
            <filename>grid.html</filename>
            <type>text/html</type>
            <size>1468</size>
            <attacher name="Yury Semikhatsky">yurys</attacher>
            
              <data encoding="base64">PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KPHN0eWxlPgpib2R5IHsgbWFyZ2luOiAwOyBw
YWRkaW5nOiAwOyB9Ci5ib3ggewogIGRpc3BsYXk6IGlubGluZS1mbGV4OwogIHdpZHRoOiA1MHB4
OwogIGhlaWdodDogNTBweDsKICBib3JkZXI6IDFweCBzb2xpZCBkYXJrZ3JheTsKICBib3gtc2l6
aW5nOiBib3JkZXItYm94Owp9CmltZyB7IHdpZHRoOiA1MHB4OyBoZWlnaHQ6IDUwcHg7IH0KPC9z
dHlsZT4KPC9oZWFkPgo8Ym9keT4KPHNjcmlwdD4KLy8gR2VuZXJhdGUgfjIwMCBzbWFsbCA8aW1n
PiBlbGVtZW50cyB0aGF0IHNoYXJlIGEgc21hbGwgc2V0IG9mIGRpc3RpbmN0Ci8vIGltYWdlIHNv
dXJjZXMuIFdlYktpdCdzIFNraWEgR1BVIGltYWdlIGF0bGFzIGJhdGNoZXMgdGhlc2UgaW50byBh
Ci8vIHNpbmdsZSBHUFUtYmFja2VkIGF0bGFzIHRleHR1cmUgYW5kIHRoZW4gbW1hcCgpcyB0aGUg
R0JNIGJ1ZmZlciB0bwovLyB1cGxvYWQgcGl4ZWxzLiBJZiB0aGUgbW1hcCBmYWlscyAoZS5nLiBo
ZWFkbGVzcyAvIG5vIHJlYWwgR1BVIC8KLy8gc29mdHdhcmUgTWVzYSksIHVwc3RyZWFtIFdlYktp
dCBSRUxFQVNFX0FTU0VSVHMgYW5kIGNyYXNoZXMgdGhlCi8vIFdlYlByb2Nlc3MgaW5zdGVhZCBv
ZiBmYWxsaW5nIGJhY2sgZ3JhY2VmdWxseS4KY29uc3QgUEFMRVRURSA9IFsnZmYwMDAwJywnMDBm
ZjAwJywnMDAwMGZmJywnZmZmZjAwJywnZmYwMGZmJywnMDBmZmZmJywnMDAwMDAwJywnZmZmZmZm
JywnODA4MDgwJywnZmZhNTAwJywnODAwMDgwJ107CmNvbnN0IHNvdXJjZXMgPSBQQUxFVFRFLm1h
cChjID0+IHsKICAvLyBUaW55IGlubGluZSA4eDggUE5HLXN0eWxlIGRhdGEgVVJMIC0gb25lIHNv
bGlkIGNvbG9yIHBlciBzb3VyY2Ugc28KICAvLyB0aGUgYXRsYXMgaGFzIDExIGRpc3RpbmN0IGlt
YWdlcyAobWF0Y2hpbmcgV2ViS2l0J3MgYXRsYXMgYmF0Y2hpbmcKICAvLyBoZXVyaXN0aWNzKS4K
ICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsKICBjYW52
YXMud2lkdGggPSBjYW52YXMuaGVpZ2h0ID0gODsKICBjb25zdCBjdHggPSBjYW52YXMuZ2V0Q29u
dGV4dCgnMmQnKTsKICBjdHguZmlsbFN0eWxlID0gJyMnICsgYzsKICBjdHguZmlsbFJlY3QoMCwg
MCwgOCwgOCk7CiAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoJ2ltYWdlL3BuZycpOwp9KTsKZm9y
IChsZXQgaSA9IDA7IGkgPCAyMDA7ICsraSkgewogIGNvbnN0IGJveCA9IGRvY3VtZW50LmNyZWF0
ZUVsZW1lbnQoJ2RpdicpOwogIGJveC5jbGFzc05hbWUgPSAnYm94JzsKICBjb25zdCBpbWcgPSBk
b2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTsKICBpbWcuc3JjID0gc291cmNlc1tpICUgc291
cmNlcy5sZW5ndGhdOwogIGJveC5hcHBlbmRDaGlsZChpbWcpOwogIGRvY3VtZW50LmJvZHkuYXBw
ZW5kQ2hpbGQoYm94KTsKfQo8L3NjcmlwdD4KPC9ib2R5Pgo8L2h0bWw+Cg==
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>479151</attachid>
            <date>2026-04-17 10:09:37 -0700</date>
            <delta_ts>2026-04-17 10:09:37 -0700</delta_ts>
            <desc>workaround demo</desc>
            <filename>simulate-mmap-failure.patch</filename>
            <type>text/plain</type>
            <size>1150</size>
            <attacher name="Yury Semikhatsky">yurys</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1NvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBoaWNzL2dibS9NZW1vcnlN
YXBwZWRHUFVCdWZmZXIuY3BwIGIvU291cmNlL1dlYkNvcmUvcGxhdGZvcm0vZ3JhcGhpY3MvZ2Jt
L01lbW9yeU1hcHBlZEdQVUJ1ZmZlci5jcHAKaW5kZXggZDdmODY2MmU5NDk0Li4xZjEwYzJlODhk
ZGMgMTAwNjQ0Ci0tLSBhL1NvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBoaWNzL2dibS9NZW1v
cnlNYXBwZWRHUFVCdWZmZXIuY3BwCisrKyBiL1NvdXJjZS9XZWJDb3JlL3BsYXRmb3JtL2dyYXBo
aWNzL2dibS9NZW1vcnlNYXBwZWRHUFVCdWZmZXIuY3BwCkBAIC0yMjAsNiArMjIwLDE0IEBAIGJv
b2wgTWVtb3J5TWFwcGVkR1BVQnVmZmVyOjptYXBJZk5lZWRlZCgpCiAgICAgaWYgKGlzTWFwcGVk
KCkpCiAgICAgICAgIHJldHVybiB0cnVlOwogCisgICAgLy8gVEVTVC1PTkxZOiBlbXVsYXRlIHRo
ZSBlbnZpcm9ubWVudCB3aGVyZSB0aGUgZXhwb3J0ZWQgZG1hLWJ1ZiBjYW5ub3QKKyAgICAvLyBi
ZSBtbWFwJ2QgZm9yIHdyaXRpbmcgKGUuZy4gTlZJRElBIHByb3ByaWV0YXJ5IHVzZXJsYW5kICsg
c3lzdGVtIE1lc2EKKyAgICAvLyBHQk0sIHN1Y2ggYXMgUGxheXdyaWdodCdzIG5vbi1jb250YWlu
ZXIgaGVhZGxlc3MgV1BFIGJ1aWxkKS4gU2V0CisgICAgLy8gICBXRUJLSVRfU0lNVUxBVEVfR1BV
X0JVRkZFUl9NTUFQX0ZBSUxVUkU9MQorICAgIC8vIHRvIHNraXAgdGhlIHJlYWwgbW1hcCBhbmQg
ZXhlcmNpc2UgdGhlIGZhaWx1cmUgcGF0aC4gTm90IGZvciBzaGlwcGluZy4KKyAgICBpZiAoY29u
c3QgY2hhciogZW52ID0gZ2V0ZW52KCJXRUJLSVRfU0lNVUxBVEVfR1BVX0JVRkZFUl9NTUFQX0ZB
SUxVUkUiKTsgZW52ICYmICplbnYgPT0gJzEnKQorICAgICAgICByZXR1cm4gZmFsc2U7CisKICAg
ICBBU1NFUlQoaXNMaW5lYXIoKSB8fCBpc1ZpdmFudGVTdXBlclRpbGVkKCkpOwogICAgIG1fbWFw
cGVkTGVuZ3RoID0gcHJpbWFyeVBsYW5lRG1hQnVmU3RyaWRlKCkgKiBtX2FsbG9jYXRlZFNpemUu
aGVpZ2h0KCk7CiAgICAgbV9tYXBwZWREYXRhID0gbW1hcChudWxscHRyLCBtX21hcHBlZExlbmd0
aCwgUFJPVF9SRUFEIHwgUFJPVF9XUklURSwgTUFQX1NIQVJFRCwgcHJpbWFyeVBsYW5lRG1hQnVm
RkQoKSwgMCk7Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>