Bug 489072 - Null screen in QtWaylandClient::QWaylandWindow::handleScreensChanged
Summary: Null screen in QtWaylandClient::QWaylandWindow::handleScreensChanged
Status: REOPENED
Alias: None
Product: plasmashell
Classification: Plasma
Component: generic-crash (show other bugs)
Version: 6.1.0
Platform: Gentoo Packages Linux
: HI crash
Target Milestone: 1.0
Assignee: Plasma Bugs List
URL:
Keywords: drkonqi, wayland
: 489414 489635 (view as bug list)
Depends on:
Blocks:
 
Reported: 2024-06-23 22:03 UTC by Arsen Arsenović
Modified: 2024-07-03 00:17 UTC (History)
5 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
New crash information added by DrKonqi (253.28 KB, text/plain)
2024-06-23 22:03 UTC, Arsen Arsenović
Details
WAYLAND_DEBUG=1 logs from KRunner just before the crash (87.20 KB, text/plain)
2024-06-23 22:10 UTC, Arsen Arsenović
Details

Note You need to log in before you can comment on or make changes to this bug.
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. ***