PDA

View Full Version : QGraphicsProxyWidget usage leads to QApplication destructor crashing



redsoft
25th June 2022, 18:00
Recently I needed to insert several buttons into QGraphicsScene and implemented it as it was described in Qt examples (I use Qt 5.15.2):


QMyWidget* widget;
// ...
// initializing widget, adding layout, adding 3 QPushButton’s to this layout
QMyGraphicsScene* scene;
// initializing some my scene
QGraphicsProxyWidget* proxy = scene->addWidget (widget);

Everything works fine, aside from a mysterious crash happening on the application exit. The crash appears on Linux and Android (not observed on Windows) deep in QApplication destructor.
What is very interesting, the crash happens only in the case, if any of the buttons present in the QGraphicsProxyWidget, was pressed during execution. If the application is started, then closed immediately without any user interaction with the buttons, - there is no crash!

During this problem investigation, I added full cleanup that is performed when just one my QMainWindow inheritor is closed:

proxy->setWidget (nullptr);
scene->removeItem (proxy);
delete proxy;
But this doesn’t help, and when all QWidget’s and QGraphicsScene are already destroyed, the crash still happens in QApplication::~QApplication.
Any help with this issue would be appreciated.

d_stranz
1st July 2022, 16:24
You haven't shown enough code to give any idea what could be wrong, but personally I think you are chasing a red herring (or barking up the wrong tree, or whatever metaphor you want for "looking in the wrong place").

Whenever I have an unexplained crash like this that occurs in some weird place, it is usually something I have done in some totally unrelated place in the program that just happens to corrupt memory in the place where the crash occurs. For example, I recently had a crash in the QDomDocument destructor that occurred only in Release mode builds. It turned out that I was writing past the end of an array (an off-by-one error) and this caused a memory corruption that caused the crash only in Release mode. In Debug mode, the bug was still there, but the array's memory location didn't result in code corruption.

So since you observe this error only when one of the buttons is pressed, start looking there. Start by disconnecting the button's signals from any slots you have connected to them. Problem goes away? OK, reconnect the signals and slots one by one until you see a problem again. Next, comment out all the code in each slot and try again. Eventually you will discover what is wrong.

Look to make sure you are obeying Qt's widget ownership rules. I have had bugs where I manually deleted a QWidget / QObject that was actually owned by another widget, causing a crash at program exit.

Make sure you are not creating multiple instances of the same widget, and saving the pointers into the same variable (thus resulting in a dangling pointer that is not accessible). Make sure that if you do create multiple instances, you call deleteLater() on the unused pointer so it gets disconnected and cleaned up properly.

These kinds of bugs are frustrating and difficult to find, but the last thing to do is to assume it's a Qt bug. It isn't :-)