Solved Application crashes on exit after any interaction with QMenuBar
-
My Qt application crashes with a segmentation fault when I exit the program, but only if I've interacted with the MenuBar in anyway. The MenuBar is functional, it does what it is supposed to do, but even opening and closing one of the menus without selecting an action is enough to crash the program when it exits.
I made a class to implement the SLOTS for each of the menus actions, and I'm wondering if there's an issue with that class getting deleted before the menu gets deleted. I don't use the
delete
keyword anywhere, which I've read is a problem. I set parent objects appropriately and let Qt handle the cleanup.My mainWindow class contains the pointers to the SLOT classes, as well as handles the creation of the menus. The SLOT classes use the
Q_OBJECT
macro, which I've also read is important.Is having the slots implemented in a different class what's tripping me up here?
-
Hi and welcome to devnet,
Please provide the stack trace you get when your application crashes. Otherwise it's pretty much Crystal Ball Debugging(tm)
-
I'm... not sure how to do that. Any advice for doing it on CLion would be helpful!
-
How's this?
#0 0x00007ffff7e832c2 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 #1 0x00007ffff7e7d743 in QXcbConnection::removeWindowEventListener(unsigned int) () from /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 #2 0x00007ffff7e93d6a in QXcbWindow::destroy() () from /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 #3 0x00007ffff7e93e98 in QXcbWindow::~QXcbWindow() () from /usr/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5 #4 0x00007ffff7fe9ede in ?? () from /usr/lib/x86_64-linux-gnu/qt5/plugins/xcbglintegrations/libqxcb-glx-integration.so #5 0x00007ffff72fbe50 in QWindow::destroy() () from /usr/lib/x86_64-linux-gnu/libQt5Gui.so.5 #6 0x00007ffff78d8aba in QWidgetPrivate::deleteTLSysExtra() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #7 0x00007ffff78dbdd0 in QWidget::destroy(bool, bool) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #8 0x00007ffff78e3724 in QWidget::~QWidget() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #9 0x00007ffff7a24609 in QMenu::~QMenu() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #10 0x00007ffff6fdf28b in QObjectPrivate::deleteChildren() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 #11 0x00007ffff78e3708 in QWidget::~QWidget() () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5 #12 0x0000000000416cfe in MainWindow::~MainWindow() () #13 0x00007ffff6403ff8 in __run_exit_handlers (status=0, listp=0x7ffff678e5f8 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true) at exit.c:82 #14 0x00007ffff6404045 in __GI_exit (status=<optimized out>) at exit.c:104 #15 0x00007ffff63ea837 in __libc_start_main (main=0x414f76 <main>, argc=1, argv=0x7fffffffdcb8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdca8) at ../csu/libc-start.c:325 #16 0x0000000000414ea9 in _start () (gdb)
-
Read the documentation Luke :-)
-
What version of Qt are you using ?
What Linux distribution are you running ? -
I saw that documentation, didn't help me copy/paste the stack trace through.
I'm on Xubuntu 16.04, Qt 5.8.
Source code isn't crazy large yet, my GitHub repo is https://github.com/cr01927/ROSIDE/tree/ROSProjectExplorerDev
The menu stuff is in src/MainWindow.(h|cpp), the Slots classes are in src/Menus/(FileMenuSlots|EditMenuSlots.h|cpp)
-
@WackyWormer I found two problems when testing your program on my system:
- In your
MainWindow
constructor, you are usingfile_menu_
andedit_menu_
before they are actually assigned inInitMenuBar()
...
file_menu_slots_ = new FileMenuSlots(file_menu_, this); edit_menu_slots_ = new EditMenuSlots(edit_menu_, this); InitMenuBar();
void MainWindow::InitMenuBar() { InitFileMenu(); InitEditMenu(); ... } void MainWindow::InitFileMenu() { file_menu_ = menuBar()->addMenu(tr("&File")); ... } void MainWindow::InitEditMenu() { edit_menu_ = menuBar()->addMenu(tr("&Edit")); ... }
So, do this instead:
void MainWindow::InitFileMenu() { file_menu_ = menuBar()->addMenu(tr("&File")); file_menu_slots_ = new FileMenuSlots(file_menu_, this); ... } void MainWindow::InitEditMenu() { edit_menu_ = menuBar()->addMenu(tr("&Edit")); edit_menu_slots_ = new EditMenuSlots(edit_menu_, this); ... }
- When using your
get()
technique inmain()
to keep theMainWindow
constructorprivate
, the app crashes on exit:
MainWindow::get(); return app.exec();
Although it may work on Linux, it doesn't work as is on my Win10 system.
So I tried to replace it by (it requires yourMainWindow
constructor to bepublic
again and removing theshow()
statement in your constructor):MainWindow w; // = MainWindow::get(); w.show(); return app.exec();
With the above 2 changes, your program works and exits without crashing even after using the menu.
- In your
-
Awesome, thanks! I really do want MainWindow to be a singleton class, so I need to figure out what I need to change for that to work.
-
Nevermind, I changed my singleton implementation to return a pointer and its working now! Thanks!
-
@WackyWormer said in Application crashes on exit after any interaction with QMenuBar:
I really do want MainWindow to be a singleton class
Have a look at this for a cross-platform solution:
https://stackoverflow.com/questions/5006547/qt-best-practice-for-a-single-instance-app-protection