Bug 422460

Summary: kwin_wayland asserts when waking up from suspend
Product: [Plasma] kwin Reporter: Nicolas Fella <nicolas.fella>
Component: wayland-genericAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: normal CC: aleixpol, kde, nate
Priority: NOR    
Version: git master   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 5.20
Sentry Crash Report:

Description Nicolas Fella 2020-06-04 19:50:12 UTC
Laptop is connected to external monitor

When I wake the laptop up from suspend and try to enter my password kwin crashes

KDE stuff from master, Qt from 5.15 branch
Comment 1 Nicolas Fella 2020-06-04 19:50:41 UTC
#0  0x00007f83ed72e355 in raise () at /usr/lib/libc.so.6
#1  0x00007f83ed717853 in abort () at /usr/lib/libc.so.6
#2  0x00007f83eddebc51 in qt_message_fatal (message=<synthetic pointer>..., context=...) at global/qlogging.cpp:1914
#3  QMessageLogger::fatal(char const*, ...) const (this=this@entry=0x7ffd0758faa8, msg=msg@entry=0x7f83ee0e5ee8 "ASSERT: \"%s\" in file %s, line %d") at global/qlogging.cpp:893
#4  0x00007f83eddeb04a in qt_assert(char const*, char const*, int) (assertion=<optimized out>, file=<optimized out>, line=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qlogging.h:90
#5  0x00007f83e872da24 in KWin::DrmOutput::~DrmOutput() (this=0x5574441a3d80, __in_chrg=<optimized out>) at /home/nico/kde/src/kwin/plugins/platforms/drm/drm_output.cpp:61
#6  0x00007f83e872daa0 in KWin::DrmOutput::~DrmOutput() (this=0x5574441a3d80, __in_chrg=<optimized out>) at /home/nico/kde/src/kwin/plugins/platforms/drm/drm_output.cpp:63
#7  0x00007f83e87239d1 in qDeleteAll<KWin::DrmOutput* const*>(KWin::DrmOutput* const*, KWin::DrmOutput* const*) (begin=0x557445553ab8, end=0x557445553ac0) at /home/nico/kde/usr/include/QtCore/qalgorithms.h:320
#8  0x00007f83e8721721 in qDeleteAll<QVector<KWin::DrmOutput*> >(QVector<KWin::DrmOutput*> const&) (c=...) at /home/nico/kde/usr/include/QtCore/qalgorithms.h:328
#9  0x00007f83e871b938 in KWin::DrmBackend::updateOutputs() (this=0x5574441496a0) at /home/nico/kde/src/kwin/plugins/platforms/drm/drm_backend.cpp:522
#10 0x00007f83e8719d01 in operator()() const (__closure=0x55744428ede0) at /home/nico/kde/src/kwin/plugins/platforms/drm/drm_backend.cpp:348
#11 0x00007f83e871e611 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, KWin::DrmBackend::openDrm()::<lambda()> >::call(struct {...} &, void **) (f=..., arg=0x7ffd0758ff40)
    at /home/nico/kde/usr/include/QtCore/qobjectdefs_impl.h:146
#12 0x00007f83e871e297 in QtPrivate::Functor<KWin::DrmBackend::openDrm()::<lambda()>, 0>::call<QtPrivate::List<>, void>(struct {...} &, void *, void **) (f=..., arg=0x7ffd0758ff40) at /home/nico/kde/usr/include/QtCore/qobjectdefs_impl.h:256
#13 0x00007f83e871da14 in QtPrivate::QFunctorSlotObject<KWin::DrmBackend::openDrm()::<lambda()>, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *)
    (which=1, this_=0x55744428edd0, r=0x5574441496a0, a=0x7ffd0758ff40, ret=0x0) at /home/nico/kde/usr/include/QtCore/qobjectdefs_impl.h:443
#14 0x00007f83ee03bc36 in QtPrivate::QSlotObjectBase::call(QObject*, void**) (a=0x7ffd0758ff40, r=0x5574441496a0, this=0x55744428edd0) at ../../include/QtCore/../../src/corelib/kernel/qobjectdefs_impl.h:398
#15 doActivate<false>(QObject*, int, void**) (sender=0x55744428bd10, signal_index=3, argv=argv@entry=0x7ffd0758ff40) at kernel/qobject.cpp:3886
#16 0x00007f83ee034f90 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**)
    (sender=sender@entry=0x55744428bd10, m=m@entry=0x7f83ee2d2a80 <QSocketNotifier::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x7ffd0758ff40) at kernel/qobject.cpp:3946
#17 0x00007f83ee03f06f in QSocketNotifier::activated(QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal) (this=this@entry=0x55744428bd10, _t1=..., _t2=<optimized out>, _t3=...) at .moc/moc_qsocketnotifier.cpp:178
#18 0x00007f83ee03f86b in QSocketNotifier::event(QEvent*) (this=0x55744428bd10, e=0x7ffd07590050) at kernel/qsocketnotifier.cpp:302
#19 0x00007f83eeac80ef in QApplicationPrivate::notify_helper(QObject*, QEvent*) (this=<optimized out>, receiver=0x55744428bd10, e=0x7ffd07590050) at kernel/qapplication.cpp:3671
#20 0x00007f83ee00579a in QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x55744428bd10, event=0x7ffd07590050) at ../../include/QtCore/5.15.0/QtCore/private/../../../../../src/corelib/thread/qthread_p.h:325
#21 0x00007f83ee059f1b in QEventDispatcherUNIXPrivate::activateSocketNotifiers() (this=0x557444115270) at kernel/qeventdispatcher_unix.cpp:304
#22 0x00007f83ee05a37b in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at kernel/qeventdispatcher_unix.cpp:511
#23 0x00007f83e9aed27d in QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at qunixeventdispatcher.cpp:63
#24 0x00007f83ee00415b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7ffd075901e0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:141
#25 0x00007f83ee00c3c0 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:121
#26 0x000055744402833f in main(int, char**) (argc=4, argv=0x7ffd07590608) at /home/nico/kde/src/kwin/main_wayland.cpp:704
Comment 2 Aleix Pol 2020-06-30 13:10:28 UTC
*** Bug 423636 has been marked as a duplicate of this bug. ***
Comment 3 David Edmundson 2020-06-30 13:23:29 UTC
Urgh, crash makes sense.

    Q_ASSERT(!m_pageFlipPending);


#7  0x00007f83e87239d1 in qDeleteAll<KWin::DrmOutput* const*>

that's not got anything to defer until we're done with the pageflip
Comment 4 Andreas H 2020-07-08 12:39:58 UTC
Git commit 6c9026628cdbfd38baeeceb48e672c5458e93f8e by Andreas Haratzis.
Committed on 08/07/2020 at 01:33.
Pushed by apol into branch 'master'.

Fix DrmOutput sometimes being freed with a pending pageflip, often when waking from sleep.

It is possible for updateOutputs to be called when a pageflip is pending.
Freeing a DrmOutput with a pending pageflip is not allowed (see ~DrmOutput assert - the page flip handler will be called on the freed memory, possibly leading to use-after-free).
This works around the problem by delaying the destruction with teardown().

M  +5    -1    plugins/platforms/drm/drm_backend.cpp

https://invent.kde.org/plasma/kwin/commit/6c9026628cdbfd38baeeceb48e672c5458e93f8e