Details
-
Bug
-
Resolution: Invalid
-
P1: Critical
-
None
-
5.15.4, 6.3.0
-
None
Description
Well, the issue may be easier to explain with code. Reproducibility of the issue has been consistent, although I haven't created a demo app to demonstrate this.
Code with issue:
void QWidgetPrivate::showChildren(bool spontaneous) { // here! QList<QObject*> childList = children; for (int i = 0; i < childList.size(); ++i) { QWidget *widget = qobject_cast<QWidget*>(childList.at(i)); if (widget && widget->windowHandle() && !widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) widget->setAttribute(Qt::WA_WState_Hidden, false); if (!widget || widget->isWindow() || widget->testAttribute(Qt::WA_WState_Hidden)) continue; if (spontaneous) { widget->setAttribute(Qt::WA_Mapped); widget->d_func()->showChildren(true); QShowEvent e; QApplication::sendSpontaneousEvent(widget, &e); } else { if (widget->testAttribute(Qt::WA_WState_ExplicitShowHide)) widget->d_func()->show_recursive(); else widget->show(); } } }
Here we get the list of children, but we then recursively traverse the list - which leads to code path which ends up destroying the children. But because the reference still exists in childList, this results in a crash.
The text file showing the analysis of the crash: https://gist.githubusercontent.com/sh-zam/1700ea2337817cca638163a69cd4d40d/raw/3276c0b49193603a8f033d88b99abf9d6b6663e5/gdb.log
The widget is setup something like this: a QMainWindow -> QStackedWidget (as central widget) -> QQuickWidget. I think it is the call to qApp->processEvents() that we do during busy wait which leads to this. Is there something that I'm missing or would fixing the reference to the children fix the bug?
Thank you!