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

Opening multiple modal dialogs can crash the application.

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P1: Critical
    • None
    • 5.4.1, 5.5.0
    • QPA: X11/XCB
    • None

    Description

      When a modal dialog is already opened (e.g., a "please wait" dialog) and the application pops another modal dialog on top (e.g., an informative QMessageBox), the application can crash if the user dismisses the QMessageBox using the keyboard.

      After investigating, it appears Qt is trying to dereference a (freshly-)deleted QXcbWindow, retrieved from QXcbConnection::focusWindow().

      Here is what happens when the QMessageBox gets dismissed:

      • QXcbWindow::~QXcbWindow() will be called and, in turn, call QXcbWindow::destroy()
      • QXcbWindow::destroy() will call QXcbWindow::doFocusOut()
      • QXcbWindow::doFocusOut() will check if the focus is soon to be relayed to another modal window
      • if that is the case, QXcbConnection::m_focusWindow is not reset to 0

      Now, if a keyrelease event is reported by Xcb before focus has indeed been relayed to the other modal dialog, QXcbConnection::m_focusWindow points to a deleted object, and QXcbKeyboard::handleKeyEvent will use that, leading to a crash.

      Although this issue resembles in many ways https://bugreports.qt.io/browse/QTBUG-34612 , I am not certain it is due to exactly the same cause. Apologies in advance if this is indeed a duplicate.

      Here's how to reproduce:

      • compile & run the attached application
      • click on the 'new file' icon. That will cause a dialog to appear, immediately shadowed by a series of QMessageBox calls
      • press & hold 'Enter' to dismiss the QMessageBoxes, and after a few of them, the application will (likely) crash.

      I could reproduce this on a:

      • Ubuntu 10.04
      • Debian 7.8
      • Ubuntu 15.04
        ..but since issue is racy by nature, you might fail reproducing it (e.g., I failed reproducing it on 1 machine: a colleague's Ubuntu 14.04 box.)

      Attached, you'll also find a suggested patch for fixing it. The code is not quite pretty, but the idea is very simple: when calling doFocusOut() from destroy(), force m_focusWindow to be set to 0 (instead of keeping a dangling pointer, that might later be picked up.)

      Attachments

        1. 48391.tar.gz
          0.8 kB
        2. qtbug48391.tar.bz2
          4 kB
        3. qtxcb.patch
          2 kB

        Issue Links

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

          Activity

            People

              paeglis Gatis Paeglis
              aundro Arnaud Diederen
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes