https://bugs.kde.org/show_bug.cgi?id=516937
Bug ID: 516937
Summary: plasmashell crashes at startup: dangling pointer in
m_waitingPanels causes SIGSEGV in isScreenUiReady()
Classification: Plasma
Product: plasmashell
Version First master
Reported In:
Platform: NixOS
OS: Linux
Status: REPORTED
Severity: crash
Priority: NOR
Component: Startup process
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected]
Target Milestone: 1.0
Created attachment 190251
--> https://bugs.kde.org/attachment.cgi?id=190251&action=edit
Patch attached.
plasmashell crashes at startup on multi-monitor setups. The crash is
100% reproducible on cold login and affects at least 6.6.0 and 6.6.1.
== Crash trace (Thread 1) ==
#4 Plasma::Containment::lastScreen() const [libPlasma.so.7]
#5 ShellCorona::isScreenUiReady(int)
#6 ShellCorona::checkAllDesktopsUiReady()
#7 void doActivate<false>(QObject*, int, void**) [libQt6Core]
#8 Plasma::Containment::uiReadyChanged(bool)
#9 Plasma::AppletPrivate::setUiReady()
#10 Plasma::Applet::flushPendingConstraintsEvents()
#11 QObject::event(QEvent*)
#12 ... QTimerInfoList::activateTimers() ...
== Root cause ==
m_waitingPanels holds raw Plasma::Containment* pointers. Between
load() populating the list and createWaitingPanels() running (after a
250 ms timer), those pointers have no lifetime guard.
checkAllDesktopsUiReady() can fire before the timer via uiReadyChanged
from a desktop applet. It calls isScreenUiReady(), which iterates
m_waitingPanels and calls cont->lastScreen() on each entry. If any
containment was freed in the meantime, the qobject_cast<Containment*>
(parent()) inside lastScreen() dereferences a corrupted vtable → SIGSEGV
(observed PC = 0x7).
The old early guard (connecting QObject::destroyed in the constructor for
panel-type containments) was removed in commit 086ff5d8, which created
this regression. That commit reasoned that createWaitingPanels() already
connects destroyed — but it does so only after successfully creating a
PanelView, which is too late.
Commit 00bd19ec introduced the vulnerable window; 086ff5d8 removed the
guard that covered it.
== Fix ==
Change m_waitingPanels from QList<Plasma::Containment*> to
QList<QPointer<Plasma::Containment>>. QPointer auto-nulls when the
object is destroyed, eliminating the dangling-pointer window entirely:
- createWaitingPanels() calls removeAll(nullptr) at entry to purge any
freed containments, and no longer needs to connect destroyed.
- panelContainmentDestroyed() no longer needs a m_waitingPanels branch;
it returns early if the containment has no panel view.
- isScreenUiReady() null-checks each QPointer before dereferencing.
Patch attached.
== Environment ==
- KDE Plasma 6.6.1, NixOS, dual-monitor (Wayland)
- Reproducible on every cold login
- GPU: irrelevant (crash is in Qt signal dispatch, not rendering)
--
You are receiving this mail because:
You are watching all bug changes.