Bug 333313

Summary: KWin crashed after removing and adding a screen
Product: [Plasma] kwin Reporter: Aleix Pol <aleixpol>
Component: generalAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: crash Flags: mgraesslin: ReviewRequest+
Priority: NOR    
Version First Reported In: 4.95.0   
Target Milestone: 5   
Platform: Compiled Sources   
OS: Linux   
URL: https://git.reviewboard.kde.org/r/118324/
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Aleix Pol 2014-04-11 10:49:16 UTC
Power dropped for 2 minutes, KScreen reported a screen removed (as the laptop has a battery) and then a screen added when the power came back.

I got a crash then, with the attached backtrace.

Reproducible: Always

Steps to Reproduce:
1. Disconnect the HDMI
2. Connect it back again
3. I always get different problems


Expected Results:  
Same behavior as in KDE4

#6  0x00007fdf3cb19389 in raise () from /usr/lib/libc.so.6
#7  0x00007fdf3cb1a788 in abort () from /usr/lib/libc.so.6
#8  0x00007fdf3ddcea0d in qt_message_fatal (context=..., message=...) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qlogging.cpp:1338
#9  0x00007fdf3ddcc516 in QMessageLogger::fatal (this=0x7fff39035a90, msg=0x7fdf3e0d7ea8 "ASSERT failure in %s: \"%s\", file %s, line %d") at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qlogging.cpp:667
#10 0x00007fdf3ddc6bbd in qt_assert_x (where=0x7fdf47698faa "QVector<T>::operator[]", what=0x7fdf47698e96 "index out of range", file=0x7fdf47698e68 "/home/kde-devel/kde5/include/QtCore/qvector.h", line=381) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/global/qglobal.cpp:2132
#11 0x00007fdf47551c21 in QVector<QMap<KWin::Group*, KWin::Layer> >::operator[] (this=0x7fff39035b70, i=1) at /home/kde-devel/kde5/include/QtCore/qvector.h:381
#12 0x00007fdf4754f9e9 in KWin::Workspace::constrainedStackingOrder (this=0x2420230) at /home/kde-devel/frameworks/kwin/layers.cpp:514
#13 0x00007fdf4754e09e in KWin::Workspace::updateStackingOrder (this=0x2420230, propagate_new_clients=false) at /home/kde-devel/frameworks/kwin/layers.cpp:119
#14 0x00007fdf475a2ba5 in KWin::Client::setGeometry (this=0x13f6edf0, x=0, y=280, w=1280, h=800, force=KWin::Client::NormalGeometrySet) at /home/kde-devel/frameworks/kwin/geometry.cpp:1952
#15 0x00007fdf47531bd8 in KWin::Client::setGeometry (this=0x13f6edf0, r=..., force=KWin::Client::NormalGeometrySet) at /home/kde-devel/frameworks/kwin/client.h:1221
#16 0x00007fdf475a3a48 in KWin::Client::blockGeometryUpdates (this=0x13f6edf0, block=false) at /home/kde-devel/frameworks/kwin/geometry.cpp:2095
#17 0x00007fdf47531a04 in KWin::GeometryUpdatesBlocker::~GeometryUpdatesBlocker (this=0x7fff39035f60, __in_chrg=<optimized out>) at /home/kde-devel/frameworks/kwin/client.h:1031
#18 0x00007fdf475a5245 in KWin::Client::changeMaximize (this=0x13f6edf0, vertical=false, horizontal=false, adjust=true) at /home/kde-devel/frameworks/kwin/geometry.cpp:2357
#19 0x00007fdf4759d1f7 in KWin::Client::checkWorkspacePosition (this=0x13f6edf0, oldGeometry=..., oldDesktop=1) at /home/kde-devel/frameworks/kwin/geometry.cpp:1062
#20 0x00007fdf475984c5 in KWin::Workspace::updateClientArea (this=0x2420230, force=false) at /home/kde-devel/frameworks/kwin/geometry.cpp:239
#21 0x00007fdf4759868f in KWin::Workspace::updateClientArea (this=0x2420230) at /home/kde-devel/frameworks/kwin/geometry.cpp:253
#22 0x00007fdf475978f0 in KWin::Workspace::desktopResized (this=0x2420230) at /home/kde-devel/frameworks/kwin/geometry.cpp:81
#23 0x00007fdf4768f920 in KWin::Workspace::qt_static_metacall (_o=0x2420230, _c=QMetaObject::InvokeMetaMethod, _id=79, _a=0x7fff39036c10) at moc_workspace.cpp:479
#24 0x00007fdf3e042270 in QMetaObject::activate (sender=0x24244d0, signalOffset=3, local_signal_index=1, argv=0x0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3680
#25 0x00007fdf3e041a7e in QMetaObject::activate (sender=0x24244d0, m=0x7fdf47950e60 <KWin::Screens::staticMetaObject>, local_signal_index=1, argv=0x0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3546
#26 0x00007fdf4768452b in KWin::Screens::changed (this=0x24244d0) at moc_screens.cpp:247
#27 0x00007fdf4756b81e in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (KWin::Screens::*)()>::call(void (KWin::Screens::*)(), KWin::Screens*, void**) (f=(void (KWin::Screens::*)(KWin::Screens * const)) 0x7fdf47684502 <KWin::Screens::changed()>, o=0x24244d0, arg=0x7fff39036f80) at /home/kde-devel/kde5/include/QtCore/qobjectdefs_impl.h:508
#28 0x00007fdf4756b7b1 in QtPrivate::FunctionPointer<void (KWin::Screens::*)()>::call<QtPrivate::List<>, void>(void (KWin::Screens::*)(), KWin::Screens*, void**) (f=(void (KWin::Screens::*)(KWin::Screens * const)) 0x7fdf47684502 <KWin::Screens::changed()>, o=0x24244d0, arg=0x7fff39036f80) at /home/kde-devel/kde5/include/QtCore/qobjectdefs_impl.h:527
#29 0x00007fdf4756b66d in QtPrivate::QSlotObject<void (KWin::Screens::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x24261e0, r=0x24244d0, a=0x7fff39036f80, ret=0x0) at /home/kde-devel/kde5/include/QtCore/qobject_impl.h:151
#30 0x00007fdf3e044fa1 in QtPrivate::QSlotObjectBase::call (this=0x24261e0, r=0x24244d0, a=0x7fff39036f80) at ../../include/QtCore/../../../../frameworks/qt5/qtbase/src/corelib/kernel/qobject_impl.h:132
#31 0x00007fdf3e042163 in QMetaObject::activate (sender=0x24244d0, signalOffset=3, local_signal_index=0, argv=0x7fff39036f80) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3666
#32 0x00007fdf3e041a7e in QMetaObject::activate (sender=0x24244d0, m=0x7fdf47950e60 <KWin::Screens::staticMetaObject>, local_signal_index=0, argv=0x7fff39036f80) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3546
#33 0x00007fdf476844ff in KWin::Screens::countChanged (this=0x24244d0, _t1=2, _t2=1) at moc_screens.cpp:241
#34 0x00007fdf47569057 in KWin::Screens::setCount (this=0x24244d0, count=1) at /home/kde-devel/frameworks/kwin/screens.cpp:111
#35 0x00007fdf47569502 in KWin::DesktopWidgetScreens::updateCount (this=0x24244d0) at /home/kde-devel/frameworks/kwin/screens.cpp:208
#36 0x00007fdf476845f6 in KWin::DesktopWidgetScreens::qt_static_metacall (_o=0x24244d0, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fff390370f0) at moc_screens.cpp:314
#37 0x00007fdf3e042270 in QMetaObject::activate (sender=0x24243f0, signalOffset=3, local_signal_index=0, argv=0x0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3680
#38 0x00007fdf3e041a7e in QMetaObject::activate (sender=0x24243f0, m=0x7fdf3e4eb3e0 <QTimer::staticMetaObject>, local_signal_index=0, argv=0x0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:3546
#39 0x00007fdf3e0d2df9 in QTimer::timeout (this=0x24243f0) at .moc/moc_qtimer.cpp:189
#40 0x00007fdf3e04d16b in QTimer::timerEvent (this=0x24243f0, e=0x7fff39037bb0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qtimer.cpp:255
#41 0x00007fdf3e03b82a in QObject::event (this=0x24243f0, e=0x7fff39037bb0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qobject.cpp:1222
#42 0x00007fdf3ee6cf14 in QApplicationPrivate::notify_helper (this=0x235cc40, receiver=0x24243f0, e=0x7fff39037bb0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:3491
#43 0x00007fdf3ee6a6a6 in QApplication::notify (this=0x7fff39037f00, receiver=0x24243f0, e=0x7fff39037bb0) at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2944
#44 0x00007fdf47554bd0 in KWin::Application::notify (this=0x7fff39037f00, o=0x24243f0, e=0x7fff39037bb0) at /home/kde-devel/frameworks/kwin/main.cpp:344
#45 0x00007fdf3e000018 in QCoreApplication::notifyInternal (this=0x7fff39037f00, receiver=0x24243f0, event=0x7fff39037bb0) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:935
#46 0x00007fdf3e003d01 in QCoreApplication::sendEvent (receiver=0x24243f0, event=0x7fff39037bb0) at ../../include/QtCore/../../../../frameworks/qt5/qtbase/src/corelib/kernel/qcoreapplication.h:237
#47 0x00007fdf3e075c0a in QTimerInfoList::activateTimers (this=0x238ff18) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qtimerinfo_unix.cpp:643
#48 0x00007fdf3e073aeb in QEventDispatcherUNIX::activateTimers (this=0x238d870) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp:557
#49 0x00007fdf3e073e5a in QEventDispatcherUNIX::processEvents (this=0x238d870, flags=...) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp:619
#50 0x00007fdf30adb76c in QUnixEventDispatcherQPA::processEvents (this=0x238d870, flags=...) at /home/kde-devel/frameworks/qt5/qtbase/src/platformsupport/eventdispatchers/qunixeventdispatcher.cpp:70
#51 0x00007fdf3dffccce in QEventLoop::processEvents (this=0x7fff39037df0, flags=...) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qeventloop.cpp:136
#52 0x00007fdf3dffcfb1 in QEventLoop::exec (this=0x7fff39037df0, flags=...) at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qeventloop.cpp:212
#53 0x00007fdf3e000701 in QCoreApplication::exec () at /home/kde-devel/frameworks/qt5/qtbase/src/corelib/kernel/qcoreapplication.cpp:1188
#54 0x00007fdf3e5e4c34 in QGuiApplication::exec () at /home/kde-devel/frameworks/qt5/qtbase/src/gui/kernel/qguiapplication.cpp:1436
#55 0x00007fdf3ee69ed3 in QApplication::exec () at /home/kde-devel/frameworks/qt5/qtbase/src/widgets/kernel/qapplication.cpp:2736
#56 0x00007fdf475562cc in kdemain (argc=1, argv=0x7fff39038528) at /home/kde-devel/frameworks/kwin/main.cpp:556kwin --replace &
Comment 1 Thomas Lübking 2014-04-11 14:30:36 UTC
implies client is on screen #1 but screens::count() is still "1" what somehow implies Screens::changed() fires w/o or before Screens::countChanged()

Ahh....

#39  QTimer::timeout (this=0x24243f0) at .moc/moc_qtimer.cpp:189
#35  KWin::DesktopWidgetScreens::updateCount (this=0x24244d0) at /home/kde-devel/frameworks/kwin/screens.cpp:208
#34  KWin::Screens::setCount (this=0x24244d0, count=1) at /home/kde-devel/frameworks/kwin/screens.cpp:111
#33  KWin::Screens::countChanged (this=0x24244d0, _t1=2, _t2=1) at moc_screens.cpp:241
#26  KWin::Screens::changed (this=0x24244d0) at moc_screens.cpp:247

Try screens.cpp:73
- connect(this, &Screens::countChanged, this, &Screens::changed);
+ connect(this, &Screens::countChanged, this, &Screens::changed, Qt::QueudConnection);
Comment 2 Thomas Lübking 2014-04-15 17:29:42 UTC
*** Bug 333471 has been marked as a duplicate of this bug. ***
Comment 3 Aleix Pol 2014-04-16 00:04:34 UTC
I am not getting a crash now, I still get some weird behavior when dis/connecting screens that makes me have to "kwin --replace", but at least I don't get the crash.

+1 for the patch, from my humble point of view :)
Comment 4 Martin Flöser 2014-04-16 07:33:17 UTC
For the record: I plan to replace the DesktopWidget based Screens 
implementation by using XRandR directly. There are only a few problems I need 
to tackle first: getting this into a state that allows to use unit tests. Main 
problem here: Xvfb doesn't support the XRandR extension which means we need to 
start Xephyr in the unit test and open an xcb_connection to this nested X 
server. Which means the QX11Info::connection() in the running unit test will 
be wrong - connected to the Xvfb it had been started in and not the Xephyr we 
started. This means KWin::connection() wraps the wrong connection and as it is 
inline I don't see how I could mock it, but it would be picked by Screens.

I have some ideas on how to tackle it, but it requires further changes overall 
in KWin.
Comment 5 Martin Flöser 2014-05-26 08:58:46 UTC
*** Bug 335356 has been marked as a duplicate of this bug. ***
Comment 6 Martin Flöser 2014-05-26 11:32:21 UTC
Git commit ae1d18779c763b432f3ebbb5b2c66ea5482270ae by Martin Gräßlin.
Committed on 26/05/2014 at 09:06.
Pushed by graesslin into branch 'master'.

Fix crash on screen changes
REVIEW: 118324

M  +1    -1    screens.cpp

http://commits.kde.org/kwin/ae1d18779c763b432f3ebbb5b2c66ea5482270ae