Bug 489072

Summary: Null screen in QtWaylandClient::QWaylandWindow::handleScreensChanged
Product: [Plasma] plasmashell Reporter: Arsen Arsenović <arsen>
Component: generic-crashAssignee: Plasma Bugs List <plasma-bugs>
Status: RESOLVED UPSTREAM    
Severity: crash CC: alexandremichel.eid, alexbaldwin2876, caseydoyle96, danifromecuador, dtombaugh, ernest0x, fabian, firlaevhans.fiete, franmagneto, g56trxg8q, git, gustavogyn, info, jbb, jeroen1602+kdebugs, jlp, jy6x2b32pie9, kde, kode54, larochellenp, limraychee+kde, magnedj, miren_radia, mitchell, nate, ollilein, pavel.urusov, postix, sam, siyanmao.sec, thegu5.disposable, trebicki.jonas
Priority: HI Keywords: drkonqi, wayland
Version: 6.1.0   
Target Milestone: 1.0   
Platform: Gentoo Packages   
OS: Linux   
See Also: https://bugs.kde.org/show_bug.cgi?id=489180
Latest Commit: Version Fixed In: Qt 6.7.3
Sentry Crash Report:
Attachments: New crash information added by DrKonqi
WAYLAND_DEBUG=1 logs from KRunner just before the crash
plasmashell crashes after backport the patch in comment 12

Description Arsen Arsenović 2024-06-23 22:03:34 UTC
Application: plasmashell (6.1.0)
 (Compiled from sources)
Qt Version: 6.7.2
Frameworks Version: 6.3.0
Operating System: Linux 6.8.12-gentoo-dist-hardened x86_64
Windowing System: Wayland
Distribution: "Gentoo Linux"
DrKonqi: 6.1.0 [CoredumpBackend]

-- Information about the crash:
When the screen turns off, then on again, various KDE components crash.  Notably, Plasma, KRunner and Dr Konqi crashed.  They only appear to crash if they have displayed a screen before.  I have a backtrace from KRunner as well, and also WL_DEBUG logs at time it crashed.  Will attach in a comment (sending this through the crash handler assistant on the plasmashell process).

I've posted this in the Wayland goal room on Matrix.  I've done a little digging on the KRunner crash I mentioned above and noticed a few things.  Will post in a backtrace together with what I noticed in a comment under this bug.

The crash can be reproduced every time.

-- Backtrace (Reduced):
#6  QtWaylandClient::QWaylandWindow::waylandScreen (this=this@entry=0x5565147b2410) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandwindow.cpp:956
#7  0x00007fa3685b8893 in QtWaylandClient::QWaylandWindow::devicePixelRatio (this=0x5565147b2410) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandwindow.cpp:1521
#8  QtWaylandClient::QWaylandWindow::scale (this=this@entry=0x5565147b2410) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandwindow.cpp:1516
#9  0x00007fa35bd8bd54 in QtWaylandClient::QWaylandEglWindow::updateSurface (this=0x5565147b2410, create=true) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp:70
#10 0x00007fa35bd8c713 in QtWaylandClient::QWaylandGLContext::makeCurrent (this=this@entry=0x7fa280002210, surface=<optimized out>) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp:318


Reported using DrKonqi
Comment 1 Arsen Arsenović 2024-06-23 22:03:35 UTC
Created attachment 170881 [details]
New crash information added by DrKonqi

DrKonqi auto-attaching complete backtrace.
Comment 2 Arsen Arsenović 2024-06-23 22:10:02 UTC
Created attachment 170882 [details]
WAYLAND_DEBUG=1 logs from KRunner just before the crash

KRunner backtrace:

#0  QPlatformScreen::screen (this=this@entry=0x0) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/gui/kernel/qplatformscreen.cpp:115
#1  0x00007ffff4aca191 in QtWaylandClient::QWaylandWindow::handleScreensChanged (this=0x555556a7b830) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandwindow.cpp:1410
#2  0x00007ffff59e9ab5 in QtPrivate::QSlotObjectBase::call (this=0x555555ae6ed0, r=<optimized out>, a=0x7fffffffc2b8) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobjectdefs_impl.h:469
#3  doActivate<false> (sender=0x555555b08c50, signal_index=3, argv=0x7fffffffc2b8) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobject.cpp:4086
#4  0x00007ffff59e9ab5 in QtPrivate::QSlotObjectBase::call (this=0x555555b037e0, r=<optimized out>, a=0x7fffffffc400) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobjectdefs_impl.h:469
#5  doActivate<false> (sender=0x7fffffffcd70, signal_index=9, argv=0x7fffffffc400) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobject.cpp:4086
#6  0x00007ffff59a1857 in QMetaObject::activate (sender=<optimized out>, m=m@entry=0x7ffff66a1ca0 <QGuiApplication::staticMetaObject>, local_signal_index=local_signal_index@entry=1, argv=argv@entry=0x7fffffffc400) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobject.cpp:4146
#7  0x00007ffff5f351b6 in QGuiApplication::screenAdded (this=<optimized out>, _t1=<optimized out>) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2_build/src/gui/Gui_autogen/include/moc_qguiapplication.cpp:421
#8  0x00007ffff5fabb5e in QWindowSystemInterface::handleScreenAdded (platformScreen=<optimized out>, isPrimary=isPrimary@entry=false) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/gui/kernel/qwindowsysteminterface.cpp:727
#9  0x00007ffff4aeeafd in QtWaylandClient::QWaylandDisplay::handleScreenInitialized (this=0x5555555a4d30, screen=<optimized out>, screen@entry=0x7fffdc005e10) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylanddisplay.cpp:601
#10 0x00007ffff4aeece3 in QtWaylandClient::QWaylandScreen::maybeInitialize (this=0x7fffdc005e10) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandscreen.cpp:74
#11 QtWaylandClient::QWaylandScreen::maybeInitialize (this=0x7fffdc005e10) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylandscreen.cpp:65
#12 0x00007ffff366d38a in ffi_call_unix64 () at /usr/src/debug/dev-libs/libffi-3.4.6/libffi-3.4.6/src/x86/unix64.S:104
#13 0x00007ffff3669481 in ffi_call_int (cif=cif@entry=0x7fffffffc600, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>, closure=closure@entry=0x0) at /usr/src/debug/dev-libs/libffi-3.4.6/libffi-3.4.6/src/x86/ffi64.c:673
#14 0x00007ffff366c746 in ffi_call (cif=cif@entry=0x7fffffffc600, fn=<optimized out>, rvalue=rvalue@entry=0x0, avalue=avalue@entry=0x7fffffffc6d0) at /usr/src/debug/dev-libs/libffi-3.4.6/libffi-3.4.6/src/x86/ffi64.c:710
#15 0x00007ffff518303f in wl_closure_invoke (closure=closure@entry=0x7fffe00025b0, target=target@entry=0x5555555b24b0, opcode=opcode@entry=2, data=<optimized out>, flags=1) at ../wayland-1.23.0/src/connection.c:1228
#16 0x00007ffff5183889 in dispatch_event (display=display@entry=0x5555555a4f60, queue=queue@entry=0x5555555a5058) at ../wayland-1.23.0/src/wayland-client.c:1670
#17 0x00007ffff5183c63 in dispatch_queue (display=0x5555555a4f60, queue=0x5555555a5058) at ../wayland-1.23.0/src/wayland-client.c:1816
#18 wl_display_dispatch_queue_pending (display=0x5555555a4f60, queue=0x5555555a5058) at ../wayland-1.23.0/src/wayland-client.c:2058
#19 0x00007ffff4adefd5 in QtWaylandClient::EventThread::dispatchQueuePending (this=<optimized out>) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylanddisplay.cpp:227
#20 QtWaylandClient::EventThread::readAndDispatchEvents (this=<optimized out>) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylanddisplay.cpp:109
#21 QtWaylandClient::EventThread::readAndDispatchEvents (this=<optimized out>) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylanddisplay.cpp:94
#22 QtWaylandClient::QWaylandDisplay::flushRequests (this=<optimized out>) at /usr/src/debug/dev-qt/qtwayland-6.7.2/qtwayland-everywhere-src-6.7.2/src/client/qwaylanddisplay.cpp:503
#23 0x00007ffff597d6cb in QObject::event (this=0x5555555a4d30, e=0x7fffe00019f0) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qobject.cpp:1452
#24 0x00007ffff6e44535 in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x5555555a4d30, e=0x7fffe00019f0) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/widgets/kernel/qapplication.cpp:3287
#25 0x00007ffff5a02658 in QCoreApplication::notifyInternal2 (receiver=0x5555555a4d30, event=0x7fffe00019f0) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qcoreapplication.cpp:1142
#26 0x00007ffff5a0270d in QCoreApplication::sendEvent (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qcoreapplication.cpp:1583
#27 0x00007ffff5a2d7fd in QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x5555555994c0) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qcoreapplication.cpp:1940
#28 0x00007ffff5a2da6c in QCoreApplication::sendPostedEvents (receiver=<optimized out>, event_type=<optimized out>) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qcoreapplication.cpp:1797
#29 0x00007ffff578b0f7 in postEventSourceDispatch (s=0x5555555a1a70) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qeventdispatcher_glib.cpp:244
#30 0x00007ffff41df335 in g_main_dispatch (context=0x7fffe8000ef0) at ../glib-2.78.6/glib/gmain.c:3476
#31 0x00007ffff424b618 in g_main_context_dispatch_unlocked (context=0x7fffe8000ef0) at ../glib-2.78.6/glib/gmain.c:4284
#32 g_main_context_iterate_unlocked.isra.0 (context=0x7fffe8000ef0, block=<optimized out>, dispatch=1, self=<optimized out>) at ../glib-2.78.6/glib/gmain.c:4349
#33 0x00007ffff41de650 in g_main_context_iteration (context=0x7fffe8000ef0, may_block=1) at ../glib-2.78.6/glib/gmain.c:4414
#34 0x00007ffff5788ee3 in QEventDispatcherGlib::processEvents (this=0x5555555b5a70, flags=...) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/kernel/qeventdispatcher_glib.cpp:394
#35 0x00007ffff5a3411a in QEventLoop::exec (this=this@entry=0x7fffffffcc40, flags=..., flags@entry=...) at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/global/qflags.h:34
#36 0x00007ffff5a34538 in QCoreApplication::exec () at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/corelib/global/qflags.h:74
#37 0x00007ffff5f36590 in QGuiApplication::exec () at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/gui/kernel/qguiapplication.cpp:1926
#38 0x00007ffff6d9f309 in QApplication::exec () at /usr/src/debug/dev-qt/qtbase-6.7.2/qtbase-everywhere-src-6.7.2/src/widgets/kernel/qapplication.cpp:2555
#39 0x000055555555def3 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kde-plasma/plasma-workspace-6.1.0/plasma-workspace-6.1.0/krunner/main.cpp:147

In the handleScreensChanged function, newScreen is a null pointer at this point:

     1406 void QWaylandWindow::handleScreensChanged()
     1407 {
     1408     QPlatformScreen *newScreen = calculateScreenFromSurfaceEvents();
     1409
  >  1410     if (newScreen->screen() == window()->screen())
     1411         return;
     1412
     1413     QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->QPlatformScreen::screen());
     1414
     1415     if (fixedToplevelPositions && !QPlatformWindow::parent() && window()->type() != Qt::Popup
     1416         && window()->type() != Qt::ToolTip
     1417         && geometry().topLeft() != newScreen->geometry().topLeft()) {
     1418         auto geometry = this->geometry();
     1419         geometry.moveTo(newScreen->geometry().topLeft());
     1420         setGeometry(geometry);
     1421     }
     1422
     1423     updateScale();
     1424     updateBufferTransform();
     1425 }

... as mSurface->oldestEnteredScreen and QPlatformWindow::screen are both null pointers at that point.  Also, 

(gdb) p mSurface.d->m_screens.d.size
$33 = 0
(gdb) 

... where mSurface is the member in QWaylandWindow (checked during the execution of QWaylandWindow::calculateScreenFromSurfaceEvents)

I re-ran this with WAYLAND_DEBUG=1.  Log attached.  There might be a long pause in it due to a breakpoint.
Comment 3 Arsen Arsenović 2024-06-23 22:11:23 UTC
I also forgot to state precise, high level, reproduction steps.  Here they are:

1. Lock the screen.
2. Hit Esc
3. Wait for ten seconds (for all screens to turn off fully, presumably)
4. Wake the screens up.  The locker will have crashed at this point.  I've used loginctl unlock-session via KRunner to unlock
5. Observe that there is no desktop or KRunner
Comment 4 Nate Graham 2024-06-25 22:58:22 UTC

*** This bug has been marked as a duplicate of bug 473020 ***
Comment 5 David Edmundson 2024-06-27 21:13:25 UTC
>... as mSurface->oldestEnteredScreen being null is allowed and fine

 QPlatformWindow::screen being null is a big surprise. I want to understand that rather than just lazily add a guard.

The wayland backend always ensures there's a screen as far as Qt is concerned. If there's no screen added we'll make a placeholder screen. 
QGuiApplication:;primaryScreen() should always be valid.

QWindow caches the screen pointer. When a window is added it starts on a primary screen. Whenever a screen is removed (QWindowSystemInterface::handleScreenRemoved) we loop through all windows and assign any windows now not on a screen to the primary screen. If application code calls QWindow::setScreen(null) it gets put on the primary screen.
Comment 6 David Edmundson 2024-06-27 21:20:21 UTC
Reading the wayland log:
 - we start with two screens (bound locally to IDs 24 and 26)
 - then screen 26 gets removed
(a delay)
 - screen 24 moves
 - screen 26 gets added again
Comment 7 Nate Graham 2024-06-28 19:25:58 UTC
Ah, I had the duplicate wrong, I'm pretty sure this is actually Bug 489180.

*** This bug has been marked as a duplicate of bug 489180 ***
Comment 8 Nate Graham 2024-07-02 20:50:08 UTC
*** Bug 489635 has been marked as a duplicate of this bug. ***
Comment 9 Nate Graham 2024-07-03 00:17:01 UTC
*** Bug 489414 has been marked as a duplicate of this bug. ***
Comment 10 David Edmundson 2024-07-05 15:50:21 UTC
*** Bug 489769 has been marked as a duplicate of this bug. ***
Comment 11 David Edmundson 2024-07-05 15:50:24 UTC
*** Bug 489720 has been marked as a duplicate of this bug. ***
Comment 12 Nate Graham 2024-07-06 02:55:04 UTC
Fixed by David Edmundson with https://codereview.qt-project.org/c/qt/qtwayland/+/574934 in Qt 6.7.3.
Comment 13 Arsen Arsenović 2024-07-06 18:52:46 UTC
hm, I tried to backport and could still reproduce crashing.  I assume a botched backport (perhaps more patching is needed for 6.7 for instance), so I'll wait for the cherry-pick
Comment 14 Nate Graham 2024-07-06 19:54:55 UTC
Oh, I think I got confused and closed this as being fixed by that Qt patch, but it was for something else. Re-opening.
Comment 15 Kacper Koniuszy 2024-07-09 17:48:39 UTC
*** Bug 489933 has been marked as a duplicate of this bug. ***
Comment 16 Kacper Koniuszy 2024-07-09 17:51:11 UTC
*** Bug 488678 has been marked as a duplicate of this bug. ***
Comment 17 Kacper Koniuszy 2024-07-09 17:51:39 UTC
*** Bug 486972 has been marked as a duplicate of this bug. ***
Comment 18 Kacper Koniuszy 2024-07-09 18:07:57 UTC
(In reply to Nate Graham from comment #14)
> Oh, I think I got confused and closed this as being fixed by that Qt patch,
> but it was for something else. Re-opening.

Isn't this actually a duplicate of the bug 473020 that you mentioned earlier? That one also mentions a crash in handleScreensChanged. 

The upstream patch for that one is https://invent.kde.org/qt/qt/qtwayland/-/commit/bbb989df5ece25d2ed8e25750aee60a7b67492e4 but it doesn't seem to fix it for me.
Comment 19 Kacper Koniuszy 2024-07-09 18:27:30 UTC
Arsen, you mentioned under bug 473020 that this might have started happening with a Qt upgrade to 6.7.2.

This is interesting because 6.7.2 introduced a commit which changed this statement in handleScreensChanged:

    if (newScreen == mLastReportedScreen)

to this:

    if (newScreen->screen() == window()->screen())

https://invent.kde.org/qt/qt/qtwayland/-/commit/9838bf42fe28311d7de96f74ae99d014e943b8e0 


Could this have caused a regression? Before this change, the method would return early if both newScreen and mLastReportedScreen were null (but only one of them being null would cause issues).  After this change, the method will fail if newScreen is null. 

I'll try to test it with this commit reverted.
Comment 20 Arsen Arsenović 2024-07-09 19:07:03 UTC
I already reverted and tested - reverting it "fixes" it.
Comment 21 Kacper Koniuszy 2024-07-09 20:05:06 UTC
I "fixed" it without reverting 9838bf42 by making handleScreensChanged use nullptr as the new QScreen* if newScreen is null: https://raw.githubusercontent.com/kkoniuszy/nixpkgs/0f91836f88521c39b0fa71faf416fccfbbd270b9/pkgs/development/libraries/qt-6/patches/qtwayland-handlescreenschanged-workaround.patch

This is just a workaround though. It seems to make it behave similar in this edge case to how it did before that commit, but dereferencing a null newScreen later on would still cause a crash. If it worked for me right now, that's only because window()->screen() was also null in my test case. It's weird that we get a null newScreen, shouldn't a placeholder screen exist already?
Comment 22 Kacper Koniuszy 2024-07-09 20:12:18 UTC
For anyone on a source-based distro looking for a quick workaround, these are the patches I had to apply to qtwayland 6.7.2 to stop plasmashell from crashing when the monitors go into power saving or lose power:

1. https://invent.kde.org/qt/qt/qtwayland/-/commit/fe29b73c34c3c854df28b3c574df022080cefba3 – irrelevant but it makes the next one apply without conflicts
2. https://invent.kde.org/qt/qt/qtwayland/-/commit/83da29c62f8fb918df8d91826d16b5d5ceb2c704 – patch for bug 489180 which is also involved in these crashes
3. https://raw.githubusercontent.com/kkoniuszy/nixpkgs/0f91836f88521c39b0fa71faf416fccfbbd270b9/pkgs/development/libraries/qt-6/patches/qtwayland-handlescreenschanged-workaround.patch – a lazy workaround for this bug
Comment 23 Akseli Lahtinen 2024-07-11 10:52:17 UTC
*** Bug 490094 has been marked as a duplicate of this bug. ***
Comment 24 Siyanmao 2024-07-11 15:01:21 UTC
(In reply to Nate Graham from comment #12)
> Fixed by David Edmundson with
> https://codereview.qt-project.org/c/qt/qtwayland/+/574934 in Qt 6.7.3.

Seems not works for me.  I have 2 monitors, one is connected to the HDMI port in motherboard and the other one connected to the Displayport in motherboard with a DP-to-HDMI converter.  After backport this patch manually, plasmashell crashes after monitors enter into powersaving mode. 

Part of backtrace  message is shown below, and seems crash in QtWaylandClient::QWaylandWindow::handleScreensChanged with NULL QPlatformScreen::screen

----- Backtrace -------
Thread 1 (Thread 0x72359f8e6200 (LWP 22616)):
[KCrash Handler]
#5  QScopedPointer<QPlatformScreenPrivate, QScopedPointerDeleter<QPlatformScreenPrivate> >::get (this=0x8) at /usr/src/debug/qt6-base/qtbase/src/corelib/tools/qscopedpointer.h:110
#6  qGetPtrHelper<QScopedPointer<QPlatformScreenPrivate, QScopedPointerDeleter<QPlatformScreenPrivate> > const> (ptr=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qtclasshelpermacros.h:79
#7  QPlatformScreen::d_func (this=0x0) at /usr/src/debug/qt6-base/qtbase/src/gui/kernel/qplatformscreen.h:45
#8  QPlatformScreen::screen (this=this@entry=0x0) at /usr/src/debug/qt6-base/qtbase/src/gui/kernel/qplatformscreen.cpp:115
#9  0x00007235a69ab2d4 in QtWaylandClient::QWaylandWindow::handleScreensChanged (this=0x63558139dd50) at /usr/src/debug/qt6-wayland/qtwayland/src/client/qwaylandwindow.cpp:1408
#10 0x00007235a5ba16f7 in QtPrivate::QSlotObjectBase::call (this=<optimized out>, r=<optimized out>, a=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobjectdefs_impl.h:469
#11 doActivate<false> (sender=<optimized out>, signal_index=<optimized out>, argv=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:4086
#12 0x00007235a5ba16f7 in QtPrivate::QSlotObjectBase::call (this=<optimized out>, r=<optimized out>, a=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobjectdefs_impl.h:469
#13 doActivate<false> (sender=<optimized out>, signal_index=<optimized out>, argv=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:4086
#14 0x00007235a61eb0a1 in QGuiApplication::screenAdded (this=<optimized out>, _t1=0x635581233960) at /usr/src/debug/qt6-base/build/src/gui/Gui_autogen/include/moc_qguiapplication.cpp:421
#15 QWindowSystemInterface::handleScreenAdded (platformScreen=<optimized out>, isPrimary=isPrimary@entry=false) at /usr/src/debug/qt6-base/qtbase/src/gui/kernel/qwindowsysteminterface.cpp:727
#16 0x00007235a69797c1 in QtWaylandClient::QWaylandDisplay::ensureScreen (this=this@entry=0x635580842d00) at /usr/src/debug/qt6-wayland/qtwayland/src/client/qwaylanddisplay.cpp:409
#17 0x00007235a697b13b in QtWaylandClient::QWaylandDisplay::ensureScreen (this=0x635580842d00) at /usr/include/qt6/QtCore/qarraydataops.h:621
#18 QtWaylandClient::QWaylandDisplay::registry_global_remove (this=0x635580842d00, id=116) at /usr/src/debug/qt6-wayland/qtwayland/src/client/qwaylanddisplay.cpp:783
#19 0x00007235a6f3e596 in ffi_call_unix64 () at ../src/x86/unix64.S:104
Comment 25 Siyanmao 2024-07-11 15:08:51 UTC
Created attachment 171572 [details]
plasmashell crashes after backport the patch in comment 12

Qt Version: 6.7.2 (with patch backported from https://codereview.qt-project.org/c/qt/qtwayland/+/574934 )
Frameworks Version: 6.1.2
Operating System: Linux 6.9.8-arch1-1
Windowing System: Wayland
Distribution: "Arch Linux"
Comment 26 Kacper Koniuszy 2024-07-11 19:21:17 UTC
(In reply to Siyanmao from comment #25)
> Created attachment 171572 [details]
> plasmashell crashes after backport the patch in comment 12
> 
> Qt Version: 6.7.2 (with patch backported from
> https://codereview.qt-project.org/c/qt/qtwayland/+/574934 )
> Frameworks Version: 6.1.2
> Operating System: Linux 6.9.8-arch1-1
> Windowing System: Wayland
> Distribution: "Arch Linux"

That is expected because that patch was actually for bug 489180 – it fixed a crash in QWaylandWindow::waylandScreen, but not in QWaylandWindow::handleScreensChanged which this bug report is about. Without that patch, it would be somewhat more likely to see a crash in waylandScreen, but I'm pretty sure I saw both of them.

There is no fix for this bug right now and it seems to have appeared after commit 9838bf42 in qtwayland. It's not a regression per se, it's more like a hidden bug that got revealed after fixing something else. 

Until this gets fixed, you can either make a patch that reverts 9838bf42 or apply my patch from comment 22 which approximates pre-9838bf42 behaviour, with its possible failure modes as well. Keep in mind that it's deliberately broken to reveal issues with null handling that could occur in the code that follows. I have been daily driving it with no problems so far though.

Or, for a relatively sane workaround that isn't made to fail if things are seriously wrong, try adding a simple guard for the null newScreen case:

diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index c3725ffc..96690ddb 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -1407,6 +1407,9 @@ void QWaylandWindow::handleScreensChanged()
 {
     QPlatformScreen *newScreen = calculateScreenFromSurfaceEvents();
 
+    if (!newScreen)
+        return;
+
     if (newScreen->screen() == window()->screen())
         return;
Comment 27 cwo 2024-07-12 20:07:29 UTC
*** Bug 490176 has been marked as a duplicate of this bug. ***
Comment 28 postix 2024-07-13 12:46:00 UTC
*** Bug 490200 has been marked as a duplicate of this bug. ***
Comment 29 postix 2024-07-13 12:47:14 UTC
*** Bug 490129 has been marked as a duplicate of this bug. ***
Comment 30 ollilein 2024-07-13 19:47:42 UTC
(In reply to Kacper Koniuszy from comment #22)
> For anyone on a source-based distro looking for a quick workaround, these
> are the patches I had to apply to qtwayland 6.7.2 to stop plasmashell from
> crashing when the monitors go into power saving or lose power:
> 
> 1.
> https://invent.kde.org/qt/qt/qtwayland/-/commit/
> fe29b73c34c3c854df28b3c574df022080cefba3 – irrelevant but it makes the next
> one apply without conflicts
> 2.
> https://invent.kde.org/qt/qt/qtwayland/-/commit/
> 83da29c62f8fb918df8d91826d16b5d5ceb2c704 – patch for bug 489180 which is
> also involved in these crashes
> 3.
> https://raw.githubusercontent.com/kkoniuszy/nixpkgs/
> 0f91836f88521c39b0fa71faf416fccfbbd270b9/pkgs/development/libraries/qt-6/
> patches/qtwayland-handlescreenschanged-workaround.patch – a lazy workaround
> for this bug

Thanks for the patches, actual qtwayland-6.7.2-r2 includes the first two patches, but the third one must be applied through user patches. Since i use the patch i had no crash in plasmashell. So it looks like it is good working.
Comment 31 cwo 2024-07-15 06:56:44 UTC
*** Bug 490280 has been marked as a duplicate of this bug. ***
Comment 32 Fabian Vogt 2024-07-16 09:03:26 UTC
Fix got merged upstream: https://codereview.qt-project.org/c/qt/qtwayland/+/576718
Comment 33 David Edmundson 2024-07-18 13:51:21 UTC
*** Bug 490363 has been marked as a duplicate of this bug. ***
Comment 34 David Edmundson 2024-07-18 13:51:37 UTC
*** Bug 485549 has been marked as a duplicate of this bug. ***
Comment 35 Nicolas Fella 2024-07-19 12:18:07 UTC
*** Bug 490487 has been marked as a duplicate of this bug. ***
Comment 36 Antonio Rojas 2024-07-19 14:23:32 UTC
*** Bug 490497 has been marked as a duplicate of this bug. ***
Comment 37 Antonio Rojas 2024-07-19 19:18:31 UTC
*** Bug 490512 has been marked as a duplicate of this bug. ***
Comment 38 Harald Sitter 2024-07-26 13:23:23 UTC
*** Bug 490815 has been marked as a duplicate of this bug. ***
Comment 39 cwo 2024-07-30 12:54:01 UTC
*** Bug 491023 has been marked as a duplicate of this bug. ***
Comment 40 cwo 2024-07-30 12:56:48 UTC
*** Bug 490973 has been marked as a duplicate of this bug. ***
Comment 41 duha.bugs 2024-08-08 18:17:55 UTC
*** Bug 491335 has been marked as a duplicate of this bug. ***
Comment 42 Nate Graham 2024-08-12 16:50:24 UTC
*** Bug 491557 has been marked as a duplicate of this bug. ***
Comment 43 cwo 2024-09-13 08:36:10 UTC
*** Bug 490656 has been marked as a duplicate of this bug. ***