Details
-
Bug
-
Resolution: Done
-
P2: Important
-
4.6.3, 4.7.0
-
None
-
None
-
Mac OS X
-
-
8dd8db250d92521fda619bdcf3e1c859b37b2da0, bfbd1a281 (dev), ea6d467c0 (6.9), ff484b311 (dev), c17da11f5 (6.8)
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.