Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-81504

QWaylandWindow::handleUpdate creates thousands of pending frame callbacks, causing wayland connection termination

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • 6.2.1, 6.3.0 Alpha
    • 5.12.5, 5.13.2
    • QPA: Wayland
    • None

    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:

      1. 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.
      2. 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.
      3. 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.
      4. 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:

      1. Start "GNOME (Wayland)" session (also reproducible with: Sway, Weston).
      2. Compile Qt5 example application from qt5/examples/svg/opengl/framebufferobject/
      3. Run in terminal env QT_QPA_PLATFORM=wayland-egl WAYLAND_DEBUG=client ./framebufferobject
      4. Move application window to another workspace, go back to the workspace with the terminal (so that the application stays on an inactive workspace).
      5. Observe how Qt keeps creating new wl_callback objects with constantly increasing id
      6. Once callback id reaches ~10000, switch to the workspace with the application
      7. Observe how application dies with 'The wayland connection broke. Did the Wayland compositor die?'

      Attachments

        For Gerrit Dashboard: QTBUG-81504
        # Subject Branch Project Status CR V

        Activity

          People

            esabraha Eskil Abrahamsen Blomfeldt
            alebastr Aleksei Bavshin
            Votes:
            3 Vote for this issue
            Watchers:
            14 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There is 1 open Gerrit change