Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
5.12.5, 5.13.2
-
None
-
-
93058de8d7e7c2f320c22b3bd898aa06cf5babcd (qt/qtwayland/dev)
-
Wayland Project - Backlog task
Description
QWaylandWindow::handleUpdate could create thousands of pending frame callbacks, causing compositor to terminate client connection. Reproducible with gnome, weston, sway and possibly other wlroots-based compositors.
See swaywm/sway#4506 for original report and wayland debug logs.
Conditions:
- Compositor does not process frame callbacks for off-screen applications. Instead, it fires and deletes all the callbacks once the app is visible again. This seems to be matching the expected behavior from wayland protocol spec, so I can't say that sway is in the wrong.
- Application forces updates while off-screen and a certain code path (which I wasn't able to figure out) ends up in a call of QWaylandWindow::handleUpdate outside of frame callback. About every 10ms, if I'm reading the log from WAYLAND_DEBUG=client correctly.
- Every time it's invoked, QWaylandWindow::handleUpdate attempts to destroy a pending wl_callback and schedule a new one. As explained in 1, even if the callback is destroyed on client side, it still remains pending in a compositor.
- Once a certain critical mass of pending callbacks has been reached and the app regains focus, compositor starts firing and deleting all pending callbacks at once. Apparently this causes overflow of a fixed-size wayland connection buffer and termination of a client.
KWin avoids this crash by processing damage buffers and frame callbacks even for offscreen apps, which by itself is questionable.
Steps to reproduce:
- Start "GNOME (Wayland)" session (also reproducible with: Sway, Weston).
- Compile Qt5 example application from qt5/examples/svg/opengl/framebufferobject/
- Run in terminal env QT_QPA_PLATFORM=wayland-egl WAYLAND_DEBUG=client ./framebufferobject
- Move application window to another workspace, go back to the workspace with the terminal (so that the application stays on an inactive workspace).
- Observe how Qt keeps creating new wl_callback objects with constantly increasing id
- Once callback id reaches ~10000, switch to the workspace with the application
- Observe how application dies with 'The wayland connection broke. Did the Wayland compositor die?'