microsoft / microsoft/playwright

[Bug]: Linux WebKit compositor SIGSEGV when closing a nested Base UI drawer (standalone reproduction)

Open
#42,637 3 comments 1 reaction 1 assignee Claimed by @dcrousso View on GitHub
v1.64
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

## Reproducer

[Exact tested standalone source, pinned lockfile, run instructions and SHA-256 manifest](https://github.com/m0dded/webkit-nested-drawer-repro/tree/b4f5848c4e9e209d7bf986616ca8faa619b90ca5). [Download ZIP](https://github.com/m0dded/webkit-nested-drawer-repro/archive/b4f5848c4e9e209d7bf986616ca8faa619b90ca5.zip).

## Summary

On Linux WebKit in the official `mcr.microsoft.com/playwright` images (native amd64, no GPU), closing a nested Base UI `Drawer` inside another `Drawer`'s popup at a phone viewport (`iPhone 15` device descriptor) intermittently crashes the web-content process on its compositor thread with a null object read. In the originating application, protocol logging reports `Target.targetDestroyed {crashed:true}`; a `locator.click()` on a button in the outer drawer rejects with `TargetClosedError` while waiting for the element to be stable. The launcher process later exits 0, so `DEBUG=pw:browser` alone does not show the child crash.

## Standalone reproduction (this package, Playwright 1.63.0 / WebKit 26.6 build 2359)

Vite + React 19.2.8, `@base-ui/react` 1.6.0, the shadcn `drawer.tsx` wrapper verbatim, Tailwind 4.3.3, `@playwright/test` 1.63.0, pinned lockfile. One container command (see the linked README). Test: open outer drawer → open inner drawer → "Go back" (closes inner) → click "Submit" in the outer drawer → expect outer hidden. One worker, no retries, new context per test.

| Server | Repetitions | Outcome |
|---|---|---|
| `vite preview` (production build) | 40 | all passed, 0 kernel segfaults |
| `vite preview` (production build) | 120 | all passed, 0 kernel segfaults |
| `vite` dev server | 120 | 118 passed, 2 failed (repetitions 46, 65), 2 kernel segfaults, 2 cores |

Both failures: `locator.click` on Submit → "element is not stable" retries → `Target page, context or browser has been closed`; kernel `eadedCompositor[…]: segfault at 0 ip … error 4 in libWPEWebKit-2.0.so.1.12.0[60a0f8a,…]`. Only the dev-server setting reproduced; no explanation for the difference is claimed.

## Native signature (from the originating application's runs, both builds)

- WebKit 26.5 build 2311 (Playwright 1.61.1): `libWPEWebKit-2.0.so.1.10.2` offset `0x5ec36ca`
- WebKit 26.6 build 2359 (Playwright 1.63.0): `libWPEWebKit-2.0.so.1.12.0` offset `0x60a0f8a`

Same faulting instruction `mov (%rdi),%rax` with `rdi=0` (also `rbp=0`, `r14=0`), immediately before an indirect call at vtable offset `0x40`. The surrounding 115-byte routine is byte-identical across the builds except for relocation operands. Thread name `ThreadedCompositor`. Symbols are stripped; no function name is claimed.

## Historical observations in the originating application (Next.js dev server, same drawer wrapper)

Individual runs, each a single observation, on 1.63.0 unless noted: full 185-test WebKit shard failed on this flow once on 1.61.1 and once on 1.63.0 (three other full-shard runs on 1.63.0 passed); a 40-copy loop of the application flow failed at repetitions 11, 12, 6 (three fresh runs); a 40-copy loop of an in-app harness page with only the drawer and button primitives failed at repetition 30.

## Settings tested that did not prevent the fault (application loop, 1.63.0)

Each value was injected into the isolated test environment and confirmed present in every web-content process's environment. Delivery is proven; effective use inside WebKit was confirmed only for the CPU-rendering switch (worker threads renamed `SkiaCPUWorker`). Presence in the shipped build-2359 library (`libWPEWebKit-2.0.so.1.12.0`, SHA-256 prefix `830ab277f4de888a`): `WEBKIT_SKIA_ENABLE_CPU_RENDERING`, `WEBKIT_DISABLE_DMABUF_ATLAS`, `WEBKIT_FORCE_VBLANK_TIMER`, `WEBKIT_DISPLAY_REFRESH_THROTTLE_FPS` are present; `WEBKIT_USE_SKIA_FOR_COMPOSITION` is **absent** from build 2359 (it is present in build 2311), so that arm was an inert control on the build it ran against and is listed for completeness only.

- `WEBKIT_SKIA_ENABLE_CPU_RENDERING=1`
- `WEBKIT_USE_SKIA_FOR_COMPOSITION=1`
- `WEBKIT_DISABLE_DMABUF_ATLAS=1`
- `WEBKIT_FORCE_VBLANK_TIMER=1`
- `WEBKIT_DISPLAY_REFRESH_THROTTLE_FPS=30`

Also observed in the application loops: replacing the final click with visibility polling still crashed, and the inner drawer never finished closing before the process died; a fresh container with no preceding workload still crashed; in the sampled runs cgroup OOM counters were 0 and persistent browser RSS did not grow monotonically (the standalone package does not collect memory samples).

## Environment

Docker on x86_64 Linux, 2 GiB `/dev/shm`, no GPU (each page logs `libEGL … failed to create dri2 screen` and `ZINK: vkCreateInstance failed (VK_ERROR_INCOMPATIBLE_DRIVER)`). On 1.61.1 the application shard additionally showed exit-time faults (`SkiaGPUWorker` / compositor, unmapped-code, during `exit → libEGL → dlclose`) in 55 of 185 web-content processes in one run; those were absent in the sampled 1.63.0 runs. Reported for context only; not claimed as related.

## Expected behavior

Closing the nested drawer and submitting the outer drawer should complete without crashing the web-content process.

Physical iPhone Safari has not yet been checked; this report establishes a Linux WebKit reproduction independent of the originating application. Raw application traces and cores are omitted to avoid disclosing application data.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.