Bug 473963

Summary: kwin_wayland crashes in KWin::DrmPipeline::updateCursor when disabling external screen
Product: [Plasma] kwin Reporter: Nate Graham <nate>
Component: wayland-genericAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: crash Keywords: multiscreen, qt6
Priority: NOR    
Version First Reported In: master   
Target Milestone: ---   
Platform: Other   
OS: Linux   
See Also: https://bugs.kde.org/show_bug.cgi?id=468770
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Nate Graham 2023-08-30 20:34:57 UTC
SUMMARY
Found while trying to reproduce Bug 468770 in Plasma 6.


STEPS TO REPRODUCE
1. Be on Wayland
2. Start with the dual display setup pictured in the attachment. The right screen is primary at 200% scale, and the left is secondary at 100% scale (i.e. unscaled). My only panel is on the primary screen's left edge, essentially right in the middle of the whole arrangement.
3. Disable the secondary/left screen in the KScreen KCM


OBSERVED RESULT
kwin_wayland crashes 100% of the time. Backtrace:

#0  KWin::DrmCrtc::cursorPlane() const (this=0x0)
    at /home/nate/kde/src/kwin/src/backends/drm/drm_crtc.cpp:96
#1  0x00007efe6b031492 in KWin::DrmPipeline::updateCursor() (this=0x1d22350)
    at /home/nate/kde/src/kwin/src/backends/drm/drm_pipeline.cpp:368
#2  0x00007efe6adcf567 in operator()() const (__closure=0xb19e620)
    at /home/nate/kde/src/kwin/src/composite.cpp:435
#3  0x00007efe679de394 in QtPrivate::QSlotObjectBase::call(QObject*, void**)
    (a=0x7fff29433ac8, r=0x69b1b40, this=0xb19e610)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobjectdefs_impl.h:363
#4  doActivate<false>(QObject*, int, void**) (sender=0x1801b430, signal_index=3, argv=0x7fff29433ac8)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobject.cpp:3992
#5  0x00007efe679d4e17 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**)
    (sender=sender@entry=0x1801b430, m=m@entry=0x7efe6b34a9c0, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x0)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobject.cpp:4052
#6  0x00007efe6add9d60 in KWin::Output::geometryChanged() (this=this@entry=0x1801b430)
    at /home/nate/kde/build6/kwin/src/kwin_autogen/include/moc_output.cpp:545
#7  0x00007efe6addc444 in KWin::Output::setState(KWin::Output::State const&)
    (this=<optimized out>, state=...) at /home/nate/kde/src/kwin/src/core/output.cpp:372
#8  0x00007efe6b0291e0 in KWin::DrmOutput::applyQueuedChanges(std::shared_ptr<KWin::OutputChangeSet> const&)
    (this=0x1801b430, props=std::shared_ptr<KWin::OutputChangeSet> (use count 2, weak count 0) = {...}) at /home/nate/kde/src/kwin/src/backends/drm/drm_output.cpp:351
#9  0x00007efe6afffd25 in KWin::DrmBackend::applyOutputChanges(KWin::OutputConfiguration const&)
    (this=0x1a54b90, config=...) at /home/nate/kde/src/kwin/src/backends/drm/drm_backend.cpp:402
#10 0x00007efe6aface34 in KWin::Workspace::applyOutputConfiguration(KWin::OutputConfiguration const&, QList<KWin::Output*> const&) (this=0x1acc8e0, config=..., outputOrder=...)
    at /home/nate/kde/src/kwin/src/workspace.cpp:507
#11 0x00007efe6b0beceb in KWaylandServer::OutputConfigurationV2Interface::kde_output_configuration_v2_apply(QtWaylandServer::kde_output_configuration_v2::Resource*)
    (this=<optimized out>, resource=<optimized out>) at /home/nate/kde/src/kwin/src/workspace.h:840
#12 0x00007efe66df6be6 in ffi_call_unix64 () at ../src/x86/unix64.S:104
#13 0x00007efe66df34bf in ffi_call_int
    (cif=cif@entry=0x7fff294340c0, fn=<optimized out>, rvalue=<optimized out>, avalue=<optimized out>, closure=closure@entry=0x0) at ../src/x86/ffi64.c:673
#14 0x00007efe66df618e in ffi_call
    (cif=cif@entry=0x7fff294340c0, fn=<optimized out>, rvalue=rvalue@entry=0x0, avalue=avalue@entry=0x7fff29434190) at ../src/x86/ffi64.c:710
#15 0x00007efe6b3a3521 in wl_closure_invoke
    (closure=0x5743110, flags=<optimized out>, target=<optimized out>, opcode=5, data=<optimized out>)
    at ../../src/wayland/src/connection.c:1025
#16 0x00007efe6b39ea92 in wl_client_connection_data
    (fd=<optimized out>, mask=<optimized out>, data=0x43d88f0)
    at ../../src/wayland/src/wayland-server.c:438
#17 0x00007efe6b3a1652 in wl_event_loop_dispatch (loop=0x1a67db0, timeout=<optimized out>)
    at ../../src/wayland/src/event-loop.c:1104
#18 0x00007efe6b098b74 in KWaylandServer::Display::dispatchEvents() (this=<optimized out>)
    at /home/nate/kde/src/kwin/src/wayland/display.cpp:113
#19 0x00007efe679de394 in QtPrivate::QSlotObjectBase::call(QObject*, void**)
    (a=0x7fff29434640, r=0x1a97d60, this=0x1df9ec0)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobjectdefs_impl.h:363
#20 doActivate<false>(QObject*, int, void**) (sender=0x2152ca0, signal_index=3, argv=0x7fff29434640)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobject.cpp:3992
#21 0x00007efe679d4e17 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**)
    (sender=sender@entry=0x2152ca0, m=m@entry=0x7efe67e0a0a0, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7fff29434640)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qobject.cpp:4052
#22 0x00007efe679eebfd in QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (this=this@entry=0x2152ca0, _t1=..., _t2=<optimized out>, _t3=...)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/redhat-linux-build/src/corelib/Core_autogen/include/moc_qsocketnotifier.cpp:231
#23 0x00007efe679ef3fb in QSocketNotifier::event(QEvent*) (this=0x2152ca0, e=<optimized out>)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qsocketnotifier.cpp:326
#24 0x00007efe68dc0af8 in QApplicationPrivate::notify_helper(QObject*, QEvent*)
    (this=<optimized out>, receiver=0x2152ca0, e=0x7fff29434790)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/widgets/kernel/qapplication.cpp:3287
#25 0x00007efe6797cdb8 in QCoreApplication::notifyInternal2(QObject*, QEvent*)
    (receiver=0x2152ca0, event=0x7fff29434790)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qcoreapplication.cpp:1118
#26 0x00007efe6797cfbd in QCoreApplication::sendEvent(QObject*, QEvent*)
    (receiver=<optimized out>, event=<optimized out>)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qcoreapplication.cpp:1536
#27 0x00007efe67afe10e in QEventDispatcherUNIXPrivate::activateSocketNotifiers()
    (this=this@entry=0x1ad97a0)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qeventdispatcher_unix.cpp:268
#28 0x00007efe67afea37 in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
    (this=<optimized out>, flags=...)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/kernel/qeventdispatcher_unix.cpp:477
#29 0x00007efe68740092 in QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/gui/platform/unix/qunixeventdispatcher.cpp:27
#30 0x00007efe679899f3 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)
    (this=this@entry=0x7fff29434950, flags=..., flags@entry=...)
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/global/qflags.h:34
#31 0x00007efe6798569d in QCoreApplication::exec() ()
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/corelib/global/qflags.h:74
#32 0x00007efe681f917d in QGuiApplication::exec() ()
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/gui/kernel/qguiapplication.cpp:1908
#33 0x00007efe68dc0a69 in QApplication::exec() ()
    at /usr/src/debug/qt6-qtbase-6.5.2-1.fc38.x86_64/src/widgets/kernel/qapplication.cpp:2566
#34 0x00000000004308e8 in main(int, char**) (argc=<optimized out>, argv=<optimized out>)
    at /home/nate/kde/src/kwin/src/main_wayland.cpp:613
Comment 1 Bug Janitor Service 2023-08-31 07:16:51 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/4373
Comment 2 Nate Graham 2023-08-31 14:27:50 UTC
Git commit b78258e46411103a5a3c9e953ba6dd5c78340e5d by Nate Graham, on behalf of Vlad Zahorodnii.
Committed on 31/08/2023 at 16:19.
Pushed by ngraham into branch 'master'.

backends/drm: Guard against null crtc in DrmPipeline::updateCursor

The null check was lost in fe1d4ffbc593a96df822fb90051ed8d4a14b7fc4.

M  +3    -0    src/backends/drm/drm_pipeline.cpp

https://invent.kde.org/plasma/kwin/-/commit/b78258e46411103a5a3c9e953ba6dd5c78340e5d