RESOLVED FIXED327596
REGRESSION(321775@main): [WPE] Web process crashes on exit in BitmapTexturePool::releaseUnusedTexturesTimerFired()
https://bugs.webkit.org/show_bug.cgi?id=327596
Summary REGRESSION(321775@main): [WPE] Web process crashes on exit in BitmapTexturePo...
Yury Semikhatsky
Reported 2026-10-14 15:12:34 PDT
Since 321775@main (bug 305909), WebProcess::stopRunLoop() calls PlatformDisplay::destroySharedDisplay(). The BitmapTexturePool release timer is a RunLoop::Timer on the main run loop, and it can still fire after the display is destroyed. When no GL context is current, BitmapTexturePool::releaseUnusedTexturesTimerFired() calls PlatformDisplay::sharedDisplay().sharingGLContext(). The display is gone, so RELEASE_ASSERT(s_sharedDisplay) in PlatformDisplay::sharedDisplay() fails and the web process aborts. The problem is still present in 323770@main. Why it happens on WPE and not on GTK: In Source/WTF/wtf/glib/RunLoopSourcePriority.h, RunLoopDispatcher and ReleaseUnusedResourcesTimer are both 0 on WPE (100 and 200 on GTK). GLib dispatches all ready sources that have the highest priority in one main loop iteration. If the RunLoop::dispatch() source that delivers the connection close and the pool timer are ready in the same iteration, the dispatcher runs first: stopRunLoop() destroys the display and stops the run loop. Then the pool timer runs in the same iteration and aborts. On GTK the timer has a lower priority than the dispatcher, so it does not run in that iteration, and the loop stops before the next one. Both sources are ready at the same time when the main thread is busy while the connection closes, for example during a slow page teardown. The pool must also have textures. CPU rendering with Skia (WEBKIT_SKIA_ENABLE_CPU_RENDERING=1) makes this likely, because the painted tiles are uploaded to textures from the pool. Backtrace (WPE release build without symbols, frames matched by machine code): #4 abort() #5 WTFCrashWithInfo #6 WebCore::PlatformDisplay::sharedDisplay() PlatformDisplay.cpp:68, RELEASE_ASSERT(s_sharedDisplay) #7 WebCore::BitmapTexturePool::releaseUnusedTexturesTimerFired() #8 RunLoop timer dispatch #11 g_main_context_dispatch() #14 WebKit::WebProcessMain(int, char**) Steps to reproduce: The crash was found with Playwright, which uses the WPE MiniBrowser: https://github.com/microsoft/playwright/issues/43394 That report has a full reproduction. In short, on a machine without a GPU (Mesa llvmpipe), with WEBKIT_SKIA_ENABLE_CPU_RENDERING=1: 1. Start 16 browser instances at the same time. 2. In each instance, 50 times: create a new ephemeral context, open a page with a large DOM and a large JavaScript heap (so that the teardown is slow), and close the context. Each close ends a web process. 3. Count the web processes that end with SIGABRT. Result on a build based on 323445@main: 36 web processes aborted out of 800 closes, all with the backtrace above. The tests themselves pass; the only effect is the crash (and a core dump) when the process exits. Expected: the web process exits without a crash.
Attachments
Yury Semikhatsky
Comment 1 2026-10-14 16:34:32 PDT
EWS
Comment 2 2026-10-16 08:46:01 PDT
Committed 323970@main (8d497e8ac649): <https://commits.webkit.org/323970@main> Reviewed commits have been landed. Closing PR #77070 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.