Bug 350994 - Crash in KScreen::Output::isEnabled
Summary: Crash in KScreen::Output::isEnabled
Status: RESOLVED FIXED
Alias: None
Product: plasmashell
Classification: Plasma
Component: general (show other bugs)
Version: 5.2.2
Platform: Ubuntu Linux
: NOR crash
Target Milestone: 1.0
Assignee: David Edmundson
URL:
Keywords: drkonqi
: 360641 362119 365024 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-08-05 11:52 UTC by Cristiano
Modified: 2016-07-21 16:30 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Qt sends "screenRemoved" and "screenAdded" when renaming QScreen (2.92 KB, patch)
2016-04-05 14:50 UTC, Evgeny Brazgin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Cristiano 2015-08-05 11:52:13 UTC
Application: plasmashell (5.2.2)

Qt Version: 5.4.1
Operating System: Linux 3.19.0-25-generic x86_64
Distribution: Ubuntu 15.04

-- Information about the crash:
- What I was doing when the application crashed:
I opend trash folder from menu and Plasma crashed. It cannot be recovered even if i reboot the machine

The crash can be reproduced sometimes.

-- Backtrace:
Application: Plasma (plasmashell), signal: Segmentation fault
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Current thread is 1 (Thread 0x7f87723117c0 (LWP 1778))]

Thread 6 (Thread 0x7f875e08f700 (LWP 1783)):
#0  0x00007f876d0c08dd in poll () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007f876f62db72 in ?? () from /usr/lib/x86_64-linux-gnu/libxcb.so.1
#2  0x00007f876f62f64f in xcb_wait_for_event () from /usr/lib/x86_64-linux-gnu/libxcb.so.1
#3  0x00007f87603d6099 in QXcbEventReader::run (this=0x16033e0) at qxcbconnection.cpp:1105
#4  0x00007f876d741b0e in QThreadPrivate::start (arg=0x16033e0) at thread/qthread_unix.cpp:337
#5  0x00007f876c9476aa in start_thread (arg=0x7f875e08f700) at pthread_create.c:333
#6  0x00007f876d0cbeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 5 (Thread 0x7f87575f5700 (LWP 1799)):
#0  0x00007f876d0c08dd in poll () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007f87697ccebc in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f87697ccfcc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f876d9d8c6c in QEventDispatcherGlib::processEvents (this=0x7f87480008c0, flags=...) at kernel/qeventdispatcher_glib.cpp:418
#4  0x00007f876d97d3e2 in QEventLoop::exec (this=this@entry=0x7f87575f4de0, flags=..., flags@entry=...) at kernel/qeventloop.cpp:204
#5  0x00007f876d73cb44 in QThread::exec (this=<optimized out>) at thread/qthread.cpp:503
#6  0x00007f876f4caf65 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#7  0x00007f876d741b0e in QThreadPrivate::start (arg=0x16be070) at thread/qthread_unix.cpp:337
#8  0x00007f876c9476aa in start_thread (arg=0x7f87575f5700) at pthread_create.c:333
#9  0x00007f876d0cbeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 4 (Thread 0x7f8747fff700 (LWP 1831)):
#0  0x00007f87698117a4 in g_mutex_unlock () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#1  0x00007f87697cc3f0 in g_main_context_prepare () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f87697ccde8 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f87697ccfcc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007f876d9d8c6c in QEventDispatcherGlib::processEvents (this=0x7f87400008c0, flags=...) at kernel/qeventdispatcher_glib.cpp:418
#5  0x00007f876d97d3e2 in QEventLoop::exec (this=this@entry=0x7f8747ffede0, flags=..., flags@entry=...) at kernel/qeventloop.cpp:204
#6  0x00007f876d73cb44 in QThread::exec (this=<optimized out>) at thread/qthread.cpp:503
#7  0x00007f876f4caf65 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#8  0x00007f876d741b0e in QThreadPrivate::start (arg=0x2032f20) at thread/qthread_unix.cpp:337
#9  0x00007f876c9476aa in start_thread (arg=0x7f8747fff700) at pthread_create.c:333
#10 0x00007f876d0cbeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 3 (Thread 0x7f87463c1700 (LWP 1845)):
#0  pthread_cond_wait@@GLIBC_2.3.2 () at ../sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x00007f877144b644 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Script.so.5
#2  0x00007f877144b689 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Script.so.5
#3  0x00007f876c9476aa in start_thread (arg=0x7f87463c1700) at pthread_create.c:333
#4  0x00007f876d0cbeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 2 (Thread 0x7f8745bc0700 (LWP 1847)):
#0  0x00007f876d0c08dd in poll () at ../sysdeps/unix/syscall-template.S:81
#1  0x00007f87697ccebc in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#2  0x00007f87697ccfcc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007f876d9d8c6c in QEventDispatcherGlib::processEvents (this=0x7f86b80008c0, flags=...) at kernel/qeventdispatcher_glib.cpp:418
#4  0x00007f876d97d3e2 in QEventLoop::exec (this=this@entry=0x7f8745bbfde0, flags=..., flags@entry=...) at kernel/qeventloop.cpp:204
#5  0x00007f876d73cb44 in QThread::exec (this=<optimized out>) at thread/qthread.cpp:503
#6  0x00007f876f4caf65 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Qml.so.5
#7  0x00007f876d741b0e in QThreadPrivate::start (arg=0x21ba000) at thread/qthread_unix.cpp:337
#8  0x00007f876c9476aa in start_thread (arg=0x7f8745bc0700) at pthread_create.c:333
#9  0x00007f876d0cbeed in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

Thread 1 (Thread 0x7f87723117c0 (LWP 1778)):
[KCrash Handler]
#6  0x00007f876fe84590 in KScreen::Output::isEnabled() const () from /usr/lib/x86_64-linux-gnu/libKF5Screen.so.6
#7  0x000000000044a49f in outputLess (a=..., b=...) at ../../shell/shellcorona.cpp:300
#8  0x0000000000453302 in ShellCorona::addOutput (this=this@entry=0x16806c0, output=...) at ../../shell/shellcorona.cpp:839
#9  0x0000000000453739 in ShellCorona::reconsiderOutputs (this=0x16806c0) at ../../shell/shellcorona.cpp:787
#10 0x00007f876d9b035a in call (a=0x7ffeb04de8b0, r=0x16806c0, this=0x16c7170) at ../../include/QtCore/../../src/corelib/kernel/qobject_impl.h:124
#11 QMetaObject::activate (sender=sender@entry=0x16807a8, signalOffset=<optimized out>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x0) at kernel/qobject.cpp:3702
#12 0x00007f876d9b1057 in QMetaObject::activate (sender=sender@entry=0x16807a8, m=m@entry=0x7f876dbda580 <QTimer::staticMetaObject>, local_signal_index=local_signal_index@entry=0, argv=argv@entry=0x0) at kernel/qobject.cpp:3582
#13 0x00007f876da30610 in QTimer::timeout (this=this@entry=0x16807a8) at .moc/moc_qtimer.cpp:192
#14 0x00007f876d9be918 in QTimer::timerEvent (this=0x16807a8, e=<optimized out>) at kernel/qtimer.cpp:247
#15 0x00007f876d9b16f3 in QObject::event (this=0x16807a8, e=<optimized out>) at kernel/qobject.cpp:1267
#16 0x00007f876e289b2c in QApplicationPrivate::notify_helper (this=0x15ed520, receiver=0x16807a8, e=0x7ffeb04dec20) at kernel/qapplication.cpp:3720
#17 0x00007f876e28f000 in QApplication::notify (this=0x7ffeb04deff0, receiver=0x16807a8, e=0x7ffeb04dec20) at kernel/qapplication.cpp:3503
#18 0x00007f876d97fc2b in QCoreApplication::notifyInternal (this=0x7ffeb04deff0, receiver=0x16807a8, event=event@entry=0x7ffeb04dec20) at kernel/qcoreapplication.cpp:935
#19 0x00007f876d9d7ae5 in sendEvent (event=0x7ffeb04dec20, receiver=<optimized out>) at ../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:228
#20 QTimerInfoList::activateTimers (this=0x161e290) at kernel/qtimerinfo_unix.cpp:635
#21 0x00007f876d9d7f99 in timerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:177
#22 idleTimerSourceDispatch (source=<optimized out>) at kernel/qeventdispatcher_glib.cpp:224
#23 0x00007f87697ccc3d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#24 0x00007f87697ccf20 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#25 0x00007f87697ccfcc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#26 0x00007f876d9d8c57 in QEventDispatcherGlib::processEvents (this=0x161c950, flags=...) at kernel/qeventdispatcher_glib.cpp:418
#27 0x00007f876d97d3e2 in QEventLoop::exec (this=this@entry=0x7ffeb04dee70, flags=..., flags@entry=...) at kernel/qeventloop.cpp:204
#28 0x00007f876d98502c in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1188
#29 0x00007f876dcc431c in QGuiApplication::exec () at kernel/qguiapplication.cpp:1510
#30 0x00007f876e2857a5 in QApplication::exec () at kernel/qapplication.cpp:2956
#31 0x000000000042fd9b in main (argc=2, argv=<optimized out>) at ../../shell/main.cpp:158

Reported using DrKonqi
Comment 1 David Edmundson 2015-08-05 12:06:08 UTC
Had you just plugged in a monitor?
Comment 2 Marco Martin 2016-03-17 14:50:14 UTC
*** Bug 360641 has been marked as a duplicate of this bug. ***
Comment 3 Evgeny Brazgin 2016-04-04 14:25:36 UTC
I just made a little analysis and found that it may be a bug in Qt.
Currently plasmashell (shellcorona.cpp) finds accordance between QScreen and KScreen::Output by property name(). You may see this in methods ShellCorona::outputToScreen or ShellCorona::screenToOutput:
... if (screen->name() == output->name()) ...

Also if I open QScreen.h header, I see that property 'name' is constant:
Q_PROPERTY(QString name READ name CONSTANT)

But if I open the platform-specific implementation of QScreen, which is QXcbScreen, there is a method QXcbScreen::setOutputwhich changes inner property m_outputName and has the following TODO:
// TODO: Send an event to the QScreen instance that the screen changed its name

So in this place the QScreen changes its m_outputName and noone knows about it. This 'm_outputName' is the result which is returned as QScreen name() and it becomes inconsistent with shellcorona's data. After that ShellCorona loses correct names for QScreens and can't find correct KScreen::Output for existing QScreen, then outputForScreen returns empty pointer and the crash occurs while dereferencing it.

I think we should elevate this bug to Qt guys. Maybe the combination of emitting existing signals screenRemoved and screenAdded will be enough to handle the problem.
Comment 4 Evgeny Brazgin 2016-04-04 14:36:27 UTC
Also I made a small proof-of-concept app which prints all available screens with the code:
    qDebug() << "screens";
    foreach (QScreen* screen, QGuiApplication::screens()) {
        qDebug() << "    " << screen << " with name=" << screen->name() << " and platform screen=" << screen->handle();
    }

When I detach and external monitor and attach it again, I have the output (before detaching monitor, detached monitor, after attaching it back):
screens:
     QScreen(0x23fcff0)  with name= "HDMI1"  and platform screen= 0x2401850
screens:
     QScreen(0x23fcff0)  with name= "eDP1"  and platform screen= 0x2401850
screens:
     QScreen(0x23fcff0)  with name= "HDMI1"  and platform screen= 0x2401850

It is evident from the output, that the pointer to QScreen object remains the same, but the name changes.
If necessary, I will upload this app here, just let me know.
Comment 5 Evgeny Brazgin 2016-04-04 16:23:31 UTC
Here is part of backtrace when the screen is renamed inside Qt:

#2  0x00007ffff7f03c83 in QXcbScreen::setOutput (this=0x645290, outputId=outputId@entry=0, outputInfo=outputInfo@entry=0x0) at qxcbscreen.cpp:405                                                                                                                                                                                                                                               
#3  0x00007ffff7ef2c27 in QXcbConnection::destroyScreen (this=this@entry=0x636e40, screen=screen@entry=0x645290) at qxcbconnection.cpp:336                                                                                                                                                                                                                                                      
#4  0x00007ffff7ef3d68 in QXcbConnection::updateScreens (this=this@entry=0x636e40, event=event@entry=0x7fffe4004300) at qxcbconnection.cpp:210                                                                                                                                                                                                                                                  
#5  0x00007ffff7ef48b3 in QXcbConnection::handleXcbEvent (this=this@entry=0x636e40, event=event@entry=0x7fffe4004300) at qxcbconnection.cpp:1160

The screen is converted into "fake screen" and then later reused for another output.
In my case firstly "HDMI1" is renamed to ":0.0" (fake) and then after short time to "eDP1" (real).
Comment 6 Evgeny Brazgin 2016-04-05 14:50:44 UTC
Created attachment 98256 [details]
Qt sends "screenRemoved" and "screenAdded" when renaming QScreen

I modified Qt sources so it sends "screenRemoved" when the screen is converted to "fake" and sends "screenAdded" when the screen is converted to normal. My crash disappeared.

Also I made Ubuntu ppa with patched package for Ubuntu-xenial: https://launchpad.net/~xapienz/+archive/ubuntu/ppa.
If anyone can confirm the fix, you are welcome :)
Meanwhile, I will try to notify Qt team and propose them the solution.
Comment 7 Evgeny Brazgin 2016-04-05 15:55:06 UTC
Hm, I'm sorry, seems I could find the solution only for the bug 360641 (which was marked as duplicate of this bug), but not this one. I looked into the sources of Qt 5.4.1 (which is used by reporter of thig bug) and didn't find the fact that QScreen may be renamed in that version of Qt.

Anyway, I posted results of my analysis to Qt: https://bugreports.qt.io/browse/QTBUG-52375
Comment 8 Marco Martin 2016-05-04 11:06:22 UTC
*** Bug 362119 has been marked as a duplicate of this bug. ***
Comment 9 David Edmundson 2016-07-04 13:48:42 UTC
Good analysis, thanks for the Qt report.

This particular bug should be invalid in Plasma 5.7 as KScreen is no longer used in plasma-workspace
Comment 10 David Edmundson 2016-07-04 13:48:52 UTC
*** Bug 365024 has been marked as a duplicate of this bug. ***
Comment 11 Evgeny Brazgin 2016-07-21 16:30:55 UTC
I can confirm that after updating to Plasma 5.7 this bug no longer appears on my system.