Crash in QMenu::exec() / QMenu::popup()
-
I have got an crash when the mouse hovers over (not click) a submenu for a QOpenGLWidget. It happens occasionally when I right-click the window continually.
I wander if the problem if caused by the QT library.
Environment: QT : 5.12.0 + Visual Studio 2017
Code example:
void tWidget::contextMenuEvent(QContextMenuEvent * event) { QMenu menu; menu.addAction(action0); menu.addAction(action1); QMenu * submenu0 = menu.addMenu("submenu0"); submenu0->addAction(action2); submenu0->addAction(action3); QMenu * submenu1 = menu.addMenu("submenu1"); submenu1->addAction(action4); submenu1->addAction(action5); menu.exec(event->globalPos()); }Crash Infomation in Visual Studio:
Qt5Widgetsd.dll!QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> >::operator->() Line 118 C++ Qt5Widgetsd.dll!qGetPtrHelper<QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > >(const QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > & ptr) Line 1038 C++ Qt5Widgetsd.dll!QAbstractButton::d_func() Line 150 C++ Qt5Widgetsd.dll!QAbstractButton::isCheckable() Line 605 C++ Qt5Widgetsd.dll!QAccessibleButton::role() Line 229 C++ Qt5Widgetsd.dll!QStyleHelper::isInstanceOf(QObject * obj, QAccessible::Role role) Line 98 C++ Qt5Widgetsd.dll!QWindowsStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * opt, const QWidget * widget, QStyleHintReturn * returnData) Line 606 C++ qwindowsvistastyled.dll!QWindowsXPStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * option, const QWidget * widget, QStyleHintReturn * returnData) Line 3756 C++ qwindowsvistastyled.dll!QWindowsVistaStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * option, const QWidget * widget, QStyleHintReturn * returnData) Line 2119 C++ Qt5Widgetsd.dll!QStyleSheetStyle::styleHint(QStyle::StyleHint sh, const QStyleOption * opt, const QWidget * w, QStyleHintReturn * shret) Line 5404 C++ Qt5Widgetsd.dll!QStyleSheetStyle::drawControl(QStyle::ControlElement ce, const QStyleOption * opt, QPainter * p, const QWidget * w) Line 3754 C++ Qt5Widgetsd.dll!QMenu::paintEvent(QPaintEvent * e) Line 2830 C++ Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 9044 C++ Qt5Widgetsd.dll!QMenu::event(QEvent * e) Line 3063 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3703 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5658 C++ Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5599 C++ Qt5Widgetsd.dll!QWidgetBackingStore::doSync() Line 1431 C++ Qt5Widgetsd.dll!QWidgetBackingStore::sync(QWidget * exposedWidget, const QRegion & exposedRegion) Line 1184 C++ Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore(const QRegion & region) Line 1967 C++ Qt5Widgetsd.dll!QWidgetWindow::handleExposeEvent(QExposeEvent * event) Line 986 C++ Qt5Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 329 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3109 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Guid.dll!QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent * e) Line 3067 C++ Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1903 C++ Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1074 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 83 C++ Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 247 C++ [External Code] Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 640 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74 C++ Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 139 C++ Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 225 C++ Qt5Widgetsd.dll!QMenu::exec(const QPoint & p, QAction * action) Line 2674 C++ mp3dd.exe!MappingView::contextMenuEvent(QContextMenuEvent * event) Line 3157 C++ Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 9067 C++ Qt5Widgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1466 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3359 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::forwardEvent(QObject * receiver, QEvent * event, QEvent * originatingEvent) Line 1077 C++ Qt5Widgetsd.dll!QWidgetWindow::handleMouseEvent(QMouseEvent * event) Line 670 C++ Qt5Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 282 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3109 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Guid.dll!QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent * e) Line 2103 C++ Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1838 C++ Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1074 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 83 C++ Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 247 C++ [External Code] Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 640 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74 C++ Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 139 C++ Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 225 C++ Qt5Cored.dll!QCoreApplication::exec() Line 1364 C++ Qt5Guid.dll!QGuiApplication::exec() Line 1780 C++ Qt5Widgetsd.dll!QApplication::exec() Line 2910 C++ mp3dd.exe!main(int argc, char * * argv) Line 123 C++ -
I have got an crash when the mouse hovers over (not click) a submenu for a QOpenGLWidget. It happens occasionally when I right-click the window continually.
I wander if the problem if caused by the QT library.
Environment: QT : 5.12.0 + Visual Studio 2017
Code example:
void tWidget::contextMenuEvent(QContextMenuEvent * event) { QMenu menu; menu.addAction(action0); menu.addAction(action1); QMenu * submenu0 = menu.addMenu("submenu0"); submenu0->addAction(action2); submenu0->addAction(action3); QMenu * submenu1 = menu.addMenu("submenu1"); submenu1->addAction(action4); submenu1->addAction(action5); menu.exec(event->globalPos()); }Crash Infomation in Visual Studio:
Qt5Widgetsd.dll!QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> >::operator->() Line 118 C++ Qt5Widgetsd.dll!qGetPtrHelper<QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > >(const QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > & ptr) Line 1038 C++ Qt5Widgetsd.dll!QAbstractButton::d_func() Line 150 C++ Qt5Widgetsd.dll!QAbstractButton::isCheckable() Line 605 C++ Qt5Widgetsd.dll!QAccessibleButton::role() Line 229 C++ Qt5Widgetsd.dll!QStyleHelper::isInstanceOf(QObject * obj, QAccessible::Role role) Line 98 C++ Qt5Widgetsd.dll!QWindowsStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * opt, const QWidget * widget, QStyleHintReturn * returnData) Line 606 C++ qwindowsvistastyled.dll!QWindowsXPStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * option, const QWidget * widget, QStyleHintReturn * returnData) Line 3756 C++ qwindowsvistastyled.dll!QWindowsVistaStyle::styleHint(QStyle::StyleHint hint, const QStyleOption * option, const QWidget * widget, QStyleHintReturn * returnData) Line 2119 C++ Qt5Widgetsd.dll!QStyleSheetStyle::styleHint(QStyle::StyleHint sh, const QStyleOption * opt, const QWidget * w, QStyleHintReturn * shret) Line 5404 C++ Qt5Widgetsd.dll!QStyleSheetStyle::drawControl(QStyle::ControlElement ce, const QStyleOption * opt, QPainter * p, const QWidget * w) Line 3754 C++ Qt5Widgetsd.dll!QMenu::paintEvent(QPaintEvent * e) Line 2830 C++ Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 9044 C++ Qt5Widgetsd.dll!QMenu::event(QEvent * e) Line 3063 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3703 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Widgetsd.dll!QWidgetPrivate::sendPaintEvent(const QRegion & toBePainted) Line 5658 C++ Qt5Widgetsd.dll!QWidgetPrivate::drawWidget(QPaintDevice * pdev, const QRegion & rgn, const QPoint & offset, int flags, QPainter * sharedPainter, QWidgetBackingStore * backingStore) Line 5599 C++ Qt5Widgetsd.dll!QWidgetBackingStore::doSync() Line 1431 C++ Qt5Widgetsd.dll!QWidgetBackingStore::sync(QWidget * exposedWidget, const QRegion & exposedRegion) Line 1184 C++ Qt5Widgetsd.dll!QWidgetPrivate::syncBackingStore(const QRegion & region) Line 1967 C++ Qt5Widgetsd.dll!QWidgetWindow::handleExposeEvent(QExposeEvent * event) Line 986 C++ Qt5Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 329 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3109 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Guid.dll!QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent * e) Line 3067 C++ Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1903 C++ Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1074 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 83 C++ Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 247 C++ [External Code] Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 640 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74 C++ Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 139 C++ Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 225 C++ Qt5Widgetsd.dll!QMenu::exec(const QPoint & p, QAction * action) Line 2674 C++ mp3dd.exe!MappingView::contextMenuEvent(QContextMenuEvent * event) Line 3157 C++ Qt5Widgetsd.dll!QWidget::event(QEvent * event) Line 9067 C++ Qt5Widgetsd.dll!QOpenGLWidget::event(QEvent * e) Line 1466 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3359 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::forwardEvent(QObject * receiver, QEvent * event, QEvent * originatingEvent) Line 1077 C++ Qt5Widgetsd.dll!QWidgetWindow::handleMouseEvent(QMouseEvent * event) Line 670 C++ Qt5Widgetsd.dll!QWidgetWindow::event(QEvent * event) Line 282 C++ Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3752 C++ Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3109 C++ Qt5Cored.dll!QCoreApplication::notifyInternal2(QObject * receiver, QEvent * event) Line 1061 C++ Qt5Cored.dll!QCoreApplication::sendSpontaneousEvent(QObject * receiver, QEvent * event) Line 1464 C++ Qt5Guid.dll!QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent * e) Line 2103 C++ Qt5Guid.dll!QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent * e) Line 1838 C++ Qt5Guid.dll!QWindowSystemInterface::sendWindowSystemEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 1074 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 83 C++ Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned __int64 wp, __int64 lp) Line 247 C++ [External Code] Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 640 C++ qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 74 C++ Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 139 C++ Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 225 C++ Qt5Cored.dll!QCoreApplication::exec() Line 1364 C++ Qt5Guid.dll!QGuiApplication::exec() Line 1780 C++ Qt5Widgetsd.dll!QApplication::exec() Line 2910 C++ mp3dd.exe!main(int argc, char * * argv) Line 123 C++@NextSaturday
The crash happens at the point whereQAbstractButton::isCheckable()(called by the paint event) establishes the d-pointer, which in that case points to an already deleted instance ofQAbstractButtonPrivate.
The code doesn't show any reference to something inheriting fromQAbstractButton.
All actions added in the code seem like class members, having been instantiated elsewhere.
=> A likely scenario is that these actions are part of a menu bar, in which case they become associated with aQToolButton. Probably one of these buttons or even one of the actions is already deleted whenmenu.exec()is called. -
@NextSaturday
The crash happens at the point whereQAbstractButton::isCheckable()(called by the paint event) establishes the d-pointer, which in that case points to an already deleted instance ofQAbstractButtonPrivate.
The code doesn't show any reference to something inheriting fromQAbstractButton.
All actions added in the code seem like class members, having been instantiated elsewhere.
=> A likely scenario is that these actions are part of a menu bar, in which case they become associated with aQToolButton. Probably one of these buttons or even one of the actions is already deleted whenmenu.exec()is called.@Axel-Spoerl That is an impressive diagnosis from the trace given! :)
-
@Axel-Spoerl That is an impressive diagnosis from the trace given! :)
@JonB Thanks for the compliment, especially honoring that it comes from someone as competent as you!
-
@NextSaturday
The crash happens at the point whereQAbstractButton::isCheckable()(called by the paint event) establishes the d-pointer, which in that case points to an already deleted instance ofQAbstractButtonPrivate.
The code doesn't show any reference to something inheriting fromQAbstractButton.
All actions added in the code seem like class members, having been instantiated elsewhere.
=> A likely scenario is that these actions are part of a menu bar, in which case they become associated with aQToolButton. Probably one of these buttons or even one of the actions is already deleted whenmenu.exec()is called.@Axel-Spoerl
All actions are instantiated in the constructor of the QOpenGLWidget, except for one dynamic submenu implemented by QSignalMapper. The actions will not be deleted until my application exits.The QOpenGLWidget has no button at all. All buttons are placed on other widget.
The crash happens at the moment when the mouse hovers over a recently added submenu (not the dynamic submenu). The submenu' color has changed, but the items of the submenu haven't shown yet.
Also, the crash information includes the following line:
Qt5Widgetsd.dll!QMenu::paintEvent(QPaintEvent * e) Line 2830 C++So I'm wandering if the crash is caused by the painting of the recently added submenu.
PS: The submenu has only two items, whose actions are also instantiated in the constructor of the widget and deleted when the application exits.
-
@Axel-Spoerl
All actions are instantiated in the constructor of the QOpenGLWidget, except for one dynamic submenu implemented by QSignalMapper. The actions will not be deleted until my application exits.The QOpenGLWidget has no button at all. All buttons are placed on other widget.
The crash happens at the moment when the mouse hovers over a recently added submenu (not the dynamic submenu). The submenu' color has changed, but the items of the submenu haven't shown yet.
Also, the crash information includes the following line:
Qt5Widgetsd.dll!QMenu::paintEvent(QPaintEvent * e) Line 2830 C++So I'm wandering if the crash is caused by the painting of the recently added submenu.
PS: The submenu has only two items, whose actions are also instantiated in the constructor of the widget and deleted when the application exits.
@NextSaturday
It's indeed the paint event that ultimately causes the crash. It is consumed by a widget inheriting fromQAbstractButton. That widget has a dangling d-pointer. It's theoretically possible but pretty unlikely, that it's not yet properly constructed. Unlikely because it already receives a mouse event. It's more likely on the way to destruction and still receiving a mouse event. The painting as such is doomed to fail, but it already fails when trying to obtain the d-pointer, so the crash happens before any painting is done.Sharing all the code in question would help to get to the bottom of it.