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

        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