From f23cb5b299a65b111b3df1b6cdb566de825633c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Victor=20Ramires=20Guimar=C3=A3es=20Brito?= Date: Sat, 22 Aug 2026 23:28:24 -0300 Subject: [PATCH] docs(linux): add the camera-enumeration WebKit crash A page calling navigator.mediaDevices.enumerateDevices() aborts the WebKitGTK web process when any capture device advertises caps with no framerate field. GStreamerVideoCaptureSource handles a fraction range and a single fraction and otherwise assumes a list, so an absent field reaches gstStructureGetList, whose RELEASE_ASSERT sits one line above its own graceful early-return. Intel IPU6 laptops hit this because the sensor is published twice: once through icamerasrc/v4l2loopback, which is fine, and once through libcamera with no framerate. The crash lands ~20-30s after first paint, so it reads as a hang rather than a crash and any check in the first few seconds sees a healthy process. Documents how to detect it in one command and how to hide the duplicate device, which needs disabling libcamera in both PipeWire and GStreamer. The real fix belongs upstream in WebKit. Refs #6339 Signed-off-by: Joao Victor Ramires --- docs/linux-rendering-troubleshooting.md | 93 +++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/docs/linux-rendering-troubleshooting.md b/docs/linux-rendering-troubleshooting.md index 4bc8e80eb83..3da0222cb16 100644 --- a/docs/linux-rendering-troubleshooting.md +++ b/docs/linux-rendering-troubleshooting.md @@ -9,6 +9,7 @@ This guide covers the most common rendering failures on Linux and how to resolve | Blank or transparent window, then `SIGABRT` with `colrv1_configure_skpaint` in the output | COLRv1 color emoji font (AppImage only) | Upgrade to the latest AppImage (v0.5.2+) | | Blank window on startup / SIGSEGV when switching workspaces | dmabuf renderer incompatibility (NVIDIA or AppImage) | Prefer `WEBKIT_DMABUF_RENDERER_FORCE_SHM=1` (shipped automatically) or `--safe-rendering`. Do **not** set `WEBKIT_DISABLE_DMABUF_RENDERER=1` on current WebKitGTK — see [#3654](https://github.com/block/buzz/issues/3654). On Debian/Ubuntu with the proprietary NVIDIA driver the crash can persist (distro WebKit patch) — [#3654](https://github.com/block/buzz/issues/3654) stays open for that path. | | Blank window on any hardware, no crash output | Unknown GPU/driver combination | `--safe-rendering` flag (see below) | +| UI paints, then the window freezes and the web process `SIGABRT`s ~20-30s in | A camera whose caps carry no `framerate` field (Intel IPU6 laptops expose one via libcamera) | Hide the offending camera — see [Crash after the UI loads](#crash-after-the-ui-loads-camera-enumeration) | --- @@ -117,6 +118,98 @@ A dedicated fix for RDNA4 detection is being tracked in [#2643](https://github.c --- +## Crash after the UI loads: camera enumeration + +**Affected hardware:** Laptops whose camera stack publishes a capture device with +no `framerate` field in its caps. Confirmed on Intel IPU6 machines (Dell XPS 9320, +sensor `ov01a10`) on Ubuntu 26.04 with webkit2gtk 2.52.3. Issue +[#6339](https://github.com/block/buzz/issues/6339). + +**Symptom:** Buzz starts normally and the UI paints — you see the loading screen or +the app itself. Roughly 20-30 seconds later the window freezes on whatever it last +drew and never progresses. There is no error in Buzz's output. The web process is +gone: + +```bash +pgrep -x WebKitWebProces || echo "web process died" +``` + +This is easy to misread as a hang or a slow network. It is a crash, and because it +lands *after* first paint, any check taken in the first ~15 seconds reports a +healthy process. + +**Root cause:** This is a WebKitGTK bug, not a Buzz bug. When a page calls +`navigator.mediaDevices.enumerateDevices()`, WebKit builds video presets for every +capture device it can see. `GStreamerVideoCaptureSource.cpp` handles a `framerate` +that is a fraction range or a single fraction, and otherwise assumes a list. When +the field is absent entirely, `gst_structure_get_value()` returns `NULL` and +`gstStructureGetList()` aborts the whole web process on a `RELEASE_ASSERT` that sits +one line above its own graceful early-return. Symbolicated: + +``` +#2 abort () +#3 WTFCrashWithInfo(int, char const*, char const*, int) WTF/Assertions.h:987 +#4 gstStructureGetList() GStreamerCommon.cpp:1460 +#5 generatePresets() GStreamerVideoCaptureSource.cpp:326 +#8 capabilities() GStreamerVideoCaptureSource.cpp:256 +#25 enumerateDevices() RealtimeMediaSourceCenter.cpp:307 +``` + +On IPU6 laptops the sensor reaches userspace twice. The usable device, fed by +`icamerasrc` through `v4l2loopback`, is fine. The libcamera duplicate is not: + +``` +Intel MIPI Camera (V4L2) video/x-raw, format=NV12, width=1280, height=720, framerate=30/1 +Built-in Front Camera video/x-raw, format=RGBA, width=640, height=480, colorimetry=sRGB +``` + +**Check whether you are affected:** + +```bash +gst-device-monitor-1.0 Video/Source 2>/dev/null | grep 'caps :' | grep -v framerate +``` + +Any line printed is a device that will abort WebKit. No output means this is not +your problem. + +**Workaround:** Hide the framerate-less duplicate. Both steps are needed — PipeWire +and GStreamer enumerate libcamera independently — and neither disturbs the working +camera, which does not go through libcamera: + +```bash +# 1. PipeWire's libcamera backend +mkdir -p ~/.config/wireplumber/wireplumber.conf.d +cat > ~/.config/wireplumber/wireplumber.conf.d/50-disable-libcamera.conf <<'CONF' +wireplumber.profiles = { + main = { + monitor.libcamera = disabled + } +} +CONF +systemctl --user restart wireplumber + +# 2. GStreamer's own libcamera device provider +sudo apt remove gstreamer1.0-libcamera +``` + +Re-run the check above; it should print nothing. Note that removing +`gstreamer1.0-libcamera` also removes GNOME's Camera app (`gnome-snapshot`), which +depends on it. + +Verify your camera still works afterwards — on IPU6 the capture path is +`icamerasrc` → `v4l2loopback`, so it is unaffected: + +```bash +gst-device-monitor-1.0 Video/Source 2>/dev/null | grep 'name :' +``` + +**Upstream:** The fix belongs in WebKit — the `RELEASE_ASSERT` should be dropped so +the existing `GST_WARNING` and early return can skip the device instead of killing +the process. Still present on WebKit `main` at the time of writing +(`GStreamerCommon.cpp:1403-1408`). + +--- + ## Diagnosing an unrecognised crash If none of the above match your situation: