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

Crash in QWidgetPrivate::init on QApplication::quit() using a modal dialog on Mac

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 4.7.1
    • 4.6.3, 4.7.0
    • None
    • None
    • Mac OS X
    • macOS
    • 8dd8db250d92521fda619bdcf3e1c859b37b2da0

    Description

      Reproduction scenario:
      1) Creates a modal dialog
      2) Try to quit an application via QApplication::quit() slot (which is perfectly legal according to the Qt docs)
      => An application will crash with the following call stack (short version):

      • __kill + 10
      • kill$UNIX2003 + 32
      • raise + 26
      • abort + 93
      • qt_message_output(QtMsgType, char const*) + 263
      • qt_message(QtMsgType, char const*, char*) + 252
      • qFatal(char const*, ...) + 28
      • qt_assert(char const*, char const*, int) + 48
      • QWidgetPrivate::init(QWidget*, QFlags<Qt::WindowType>) + 100
      • QWidget::QWidget(QWidget*, QFlags<Qt::WindowType>) + 206
      • QDesktopWidget::QDesktopWidget() + 59
      • QApplication::desktop() + 91
      • flipYCoordinate(double) + 23
      • flipPoint(_NSPoint const&) + 32
      • QCursor::pos() + 67
      • QApplicationPrivate::leaveModal_sys(QWidget*) + 165
      • QApplicationPrivate::leaveModal(QWidget*) + 185
      • QWidget::destroy(bool, bool) + 485
      • QApplication::~QApplication() + 531
      • main + 133 (main.cpp:10)

      Full version of the crash report is attached to the ticked ("back-trace.txt").

      The problem is in the following code of QApplication::~QApplication():
      <...>
      delete qt_desktopWidget;
      qt_desktopWidget = 0;

      #ifndef QT_NO_CLIPBOARD
      delete qt_clipboard;
      qt_clipboard = 0;
      #endif

      delete QWidgetPrivate::mapper;
      QWidgetPrivate::mapper = 0;

      // delete all widgets
      if (QWidgetPrivate::allWidgets) {
      QWidgetSet *mySet = QWidgetPrivate::allWidgets;
      QWidgetPrivate::allWidgets = 0;
      for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) {
      register QWidget *w = *it;
      if (!w->parent()) // window
      w->destroy(true, true);
      }
      delete mySet;
      }
      <...>

      Here qt_desktopWidget and QWidgetPrivate::allWidgets are 0-ed before remained windows (including dialogs) are destroyed.

      So when a modal dialog gets destroyed, the application ultimately crashes in flipYCoordinate(double) function, where it calls QApplication::desktop(), which in turn tries to recreate a qt_desktopWidget, which crashes in QWidget::init() on access to a NULL QWidgetPrivate::allWidget variable.

      Minimal reproduction example is attached. To reproduce the crash, just unpack, compile, run. Then click "Quit!" button on the appeared dialog.

      Attachments

        1. DialogCrash.tar.gz
          1 kB
          Martin Petersson
        2. qapplication.patch
          0.9 kB
          Martin Petersson
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            cduclos Carlos Duclos (Inactive)
            xcm Martin Petersson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes