https://bugs.kde.org/show_bug.cgi?id=527846
--- Comment #1 from [email protected] --- Source-level analysis (from reading libplasma master: src/plasmaquick/appletquickitem.cpp). Note first that frames #4 and #5 of the backtrace are inside Qt itself: #4 QQuickWindow::maybeUpdate() libQt6Quick.so.6 #5 QQuickItemPrivate::derefWindow() libQt6Quick.so.6 So libplasma is only the trigger; the use-after-free happens in Qt Quick. But the teardown order in libplasma is what makes it reachable, and I think it is worth recording here. The AppletQuickItem is destroyed from inside applet teardown: QObject::connect(applet, &Plasma::Applet::appletDeleted, item, [item, thisApplet = applet](Plasma::Applet *applet) { if (thisApplet == applet) { delete item; AppletQuickItemPrivate::s_itemsForApplet.remove(applet); } }); and its destructor deletes the representation items: AppletQuickItem::~AppletQuickItem() { AppletQuickItemPrivate::s_itemsForApplet.remove(d->applet); // Here the order is important delete d->compactRepresentationItem; delete d->fullRepresentationItem; delete d->compactRepresentationExpanderItem; delete d; } The crash trace shows this exact nesting: #31 Plasma::Containment::~Containment() #30 QObject::~QObject() / QObjectPrivate::deleteChildren() #27 Plasma::Applet::~Applet() #26 Plasma::Applet::appletDeleted(...) #21 PlasmaQuick::AppletQuickItem::~AppletQuickItem() #7 QQuickItem::~QQuickItem() #6 QQuickItem::setParentItem(nullptr) #5 QQuickItemPrivate::derefWindow() #4 QQuickWindow::maybeUpdate() i.e. ~Containment() deletes its child applets, each one deletes its AppletQuickItem, and that in turn deletes representation items whose QQuickWindow has already been destroyed. ~QQuickItem() calls setParentItem(nullptr) -> derefWindow() -> maybeUpdate() on the dead window, hence SIGSEGV. Why opening the system tray first matters: compactRepresentationExpanderItem is the item that lives inside the applet's popup window. That popup window is torn down before ~Containment() runs, so the expander item is left holding a dangling window reference. If the popup was never opened, that item was never created and the crash does not happen. This is consistent with bug 417552 ("crashes on teardown when system tray was expanded", FIXED in 5.19 by D27401), so this may be a regression of that class rather than a new bug. Relationship to 449981: that report is the setEffectiveVisibleRecur variant and is marked "Version Fixed In: 6.0". This one reproduces on 6.6.6 and is the destructor variant (derefWindow from ~QQuickItem), so I reported it separately. Possible directions, for whoever triages this: 1. Qt side (probably the correct fix): make QQuickItemPrivate::derefWindow() / QQuickWindow::maybeUpdate() tolerate an item whose window is already destroyed, rather than dereferencing a stale pointer. 2. libplasma side: destroy the representation items while the view/window is still alive, or avoid emitting appletDeleted for applets being deleted as part of a Containment that no longer has a view. A purely defensive KDE-side fix is awkward because clearing the item's private windowRef is not possible through public Qt API. Reproduction is 100% here, twice back-to-back with identical frame offsets, so I am happy to test a patch and report back if someone wants to try one. -- You are receiving this mail because: You are watching all bug changes.
