Bug 411049

Summary: Kwin crash after turn off "Sync to VBlank"
Product: [Plasma] kwin Reporter: Tony <jodr666>
Component: generalAssignee: KWin default assignee <kwin-bugs-null>
Status: RESOLVED FIXED    
Severity: crash CC: jodr666
Priority: NOR Keywords: drkonqi
Version: unspecified   
Target Milestone: ---   
Platform: openSUSE   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: How to
Better bactrace?
I thought they were installed since i did not get the prompt to do so. Anyways here it is with debug symbols.

Description Tony 2019-08-18 23:33:22 UTC
Application: kwin_x11 (5.16.80)

Qt Version: 5.13.0
Frameworks Version: 5.62.0
Operating System: Linux 5.2.8-1-default x86_64
Distribution: "openSUSE Tumbleweed"

-- Information about the crash:
- What I was doing when the application crashed:

Untick "Sync to VBlank" in nvidia settings tool, ran "kwin_x11 --replace" right after.
It crashes again when you tick it again and run the command, not as consistent though since at that point the compositor is turned off.

The crash can be reproduced every time.

-- Backtrace:
Application: KWin (kwin_x11), signal: Aborted
Using host libthread_db library "/lib64/libthread_db.so.1".
[Current thread is 1 (Thread 0x7f88cc8e5880 (LWP 13933))]

Thread 8 (Thread 0x7f88b79ff700 (LWP 13997)):
#0  0x00007f88cc6a6e05 in futex_wait_cancelable (private=0, expected=0, futex_word=0x7f88ccca2fb8) at ../sysdeps/unix/sysv/linux/futex-internal.h:88
#1  0x00007f88cc6a6e05 in __pthread_cond_wait_common (abstime=0x0, mutex=0x7f88ccca2f68, cond=0x7f88ccca2f90) at pthread_cond_wait.c:502
#2  0x00007f88cc6a6e05 in __pthread_cond_wait (cond=0x7f88ccca2f90, mutex=0x7f88ccca2f68) at pthread_cond_wait.c:655
#3  0x00007f88ccba71fa in  () at /usr/lib64/libQt5Script.so.5
#4  0x00007f88ccba721b in  () at /usr/lib64/libQt5Script.so.5
#5  0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#6  0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 7 (Thread 0x7f88ab72e700 (LWP 13993)):
#0  0x00007f88cc6a716c in futex_reltimed_wait_cancelable (private=0, reltime=0x7f88ab72dba0, expected=0, futex_word=0x55b92c6b7bd0) at ../sysdeps/unix/sysv/linux/futex-internal.h:142
#1  0x00007f88cc6a716c in __pthread_cond_wait_common (abstime=0x7f88ab72dc50, mutex=0x55b92c6b7b80, cond=0x55b92c6b7ba8) at pthread_cond_wait.c:533
#2  0x00007f88cc6a716c in __pthread_cond_timedwait (cond=0x55b92c6b7ba8, mutex=0x55b92c6b7b80, abstime=0x7f88ab72dc50) at pthread_cond_wait.c:667
#3  0x00007f88cd122f68 in QWaitConditionPrivate::wait_relative(QDeadlineTimer) (this=0x55b92c6b7b80, deadline=...) at thread/qwaitcondition_unix.cpp:136
#4  0x00007f88cd122f68 in QWaitConditionPrivate::wait(QDeadlineTimer) (deadline=..., this=0x55b92c6b7b80) at thread/qwaitcondition_unix.cpp:144
#5  0x00007f88cd122f68 in QWaitCondition::wait(QMutex*, QDeadlineTimer) (this=<optimized out>, mutex=0x55b92c44a180, deadline=...) at thread/qwaitcondition_unix.cpp:225
#6  0x00007f88cd1230a7 in QWaitCondition::wait(QMutex*, unsigned long) (this=this@entry=0x55b92c6acf10, mutex=mutex@entry=0x55b92c44a180, time=<optimized out>) at thread/qwaitcondition_unix.cpp:209
#7  0x00007f88cd120621 in QThreadPoolThread::run() (this=0x55b92c6acf00) at ../../include/QtCore/../../src/corelib/thread/qmutex.h:240
#8  0x00007f88cd11d112 in QThreadPrivate::start(void*) (arg=0x55b92c6acf00) at thread/qthread_unix.cpp:360
#9  0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#10 0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 6 (Thread 0x7f88b4faf700 (LWP 13986)):
#0  0x00007f88cc6a71ba in futex_abstimed_wait_cancelable (private=0, abstime=0x7f88b4faec80, expected=0, futex_word=0x7f88a4000d28) at ../sysdeps/unix/sysv/linux/futex-internal.h:205
#1  0x00007f88cc6a71ba in __pthread_cond_wait_common (abstime=0x7f88b4faec80, mutex=0x55b92c473088, cond=0x7f88a4000d00) at pthread_cond_wait.c:539
#2  0x00007f88cc6a71ba in __pthread_cond_timedwait (cond=0x7f88a4000d00, mutex=0x55b92c473088, abstime=0x7f88b4faec80) at pthread_cond_wait.c:667
#3  0x00007f88b5de7f64 in  () at /usr/lib64/libnvidia-glcore.so.435.17
#4  0x00007f88b5b4210c in  () at /usr/lib64/libnvidia-glcore.so.435.17
#5  0x00007f88b5de70ac in  () at /usr/lib64/libnvidia-glcore.so.435.17
#6  0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#7  0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 5 (Thread 0x7f88c4dc7700 (LWP 13974)):
#0  0x00007f88ce802db6 in __GI_ppoll (fds=fds@entry=0x7f88b0000d28, nfds=nfds@entry=1, timeout=<optimized out>, timeout@entry=0x0, sigmask=sigmask@entry=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:39
#1  0x00007f88cd336a39 in ppoll (__ss=<optimized out>, __timeout=<optimized out>, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:77
#2  0x00007f88cd336a39 in qt_ppoll (timeout_ts=0x0, nfds=1, fds=0x7f88b0000d28) at kernel/qcore_unix.cpp:132
#3  0x00007f88cd336a39 in qt_ppoll (timeout_ts=0x0, nfds=1, fds=0x7f88b0000d28) at kernel/qcore_unix.cpp:129
#4  0x00007f88cd336a39 in qt_safe_poll(pollfd*, unsigned long, timespec const*) (fds=0x7f88b0000d28, nfds=1, timeout_ts=timeout_ts@entry=0x0) at kernel/qcore_unix.cpp:153
#5  0x00007f88cd338031 in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at ../../include/QtCore/../../src/corelib/tools/qarraydata.h:211
#6  0x00007f88cd2e323b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7f88c4dc6d00, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:140
#7  0x00007f88cd11bf91 in QThread::exec() (this=this@entry=0x55b92c546350) at ../../include/QtCore/../../src/corelib/global/qflags.h:120
#8  0x00007f88cbe1c485 in QQmlThreadPrivate::run() (this=0x55b92c546350) at /usr/src/debug/libqt5-qtdeclarative-5.13.0-ku.2.1.x86_64/src/qml/qml/ftw/qqmlthread.cpp:152
#9  0x00007f88cd11d112 in QThreadPrivate::start(void*) (arg=0x55b92c546350) at thread/qthread_unix.cpp:360
#10 0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#11 0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 4 (Thread 0x7f88c5757700 (LWP 13951)):
#0  0x00007f88cc6a716c in futex_reltimed_wait_cancelable (private=0, reltime=0x7f88c5756ba0, expected=0, futex_word=0x55b92c428ea4) at ../sysdeps/unix/sysv/linux/futex-internal.h:142
#1  0x00007f88cc6a716c in __pthread_cond_wait_common (abstime=0x7f88c5756c50, mutex=0x55b92c428e50, cond=0x55b92c428e78) at pthread_cond_wait.c:533
#2  0x00007f88cc6a716c in __pthread_cond_timedwait (cond=0x55b92c428e78, mutex=0x55b92c428e50, abstime=0x7f88c5756c50) at pthread_cond_wait.c:667
#3  0x00007f88cd122f68 in QWaitConditionPrivate::wait_relative(QDeadlineTimer) (this=0x55b92c428e50, deadline=...) at thread/qwaitcondition_unix.cpp:136
#4  0x00007f88cd122f68 in QWaitConditionPrivate::wait(QDeadlineTimer) (deadline=..., this=0x55b92c428e50) at thread/qwaitcondition_unix.cpp:144
#5  0x00007f88cd122f68 in QWaitCondition::wait(QMutex*, QDeadlineTimer) (this=<optimized out>, mutex=0x55b92c44a180, deadline=...) at thread/qwaitcondition_unix.cpp:225
#6  0x00007f88cd1230a7 in QWaitCondition::wait(QMutex*, unsigned long) (this=this@entry=0x55b92c4266f0, mutex=mutex@entry=0x55b92c44a180, time=<optimized out>) at thread/qwaitcondition_unix.cpp:209
#7  0x00007f88cd120621 in QThreadPoolThread::run() (this=0x55b92c4266e0) at ../../include/QtCore/../../src/corelib/thread/qmutex.h:240
#8  0x00007f88cd11d112 in QThreadPrivate::start(void*) (arg=0x55b92c4266e0) at thread/qthread_unix.cpp:360
#9  0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#10 0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 3 (Thread 0x7f88c69e7700 (LWP 13946)):
#0  0x00007f88ce802db6 in __GI_ppoll (fds=fds@entry=0x7f88b800bb48, nfds=nfds@entry=1, timeout=<optimized out>, timeout@entry=0x0, sigmask=sigmask@entry=0x0) at ../sysdeps/unix/sysv/linux/ppoll.c:39
#1  0x00007f88cd336a39 in ppoll (__ss=<optimized out>, __timeout=<optimized out>, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/bits/poll2.h:77
#2  0x00007f88cd336a39 in qt_ppoll (timeout_ts=0x0, nfds=1, fds=0x7f88b800bb48) at kernel/qcore_unix.cpp:132
#3  0x00007f88cd336a39 in qt_ppoll (timeout_ts=0x0, nfds=1, fds=0x7f88b800bb48) at kernel/qcore_unix.cpp:129
#4  0x00007f88cd336a39 in qt_safe_poll(pollfd*, unsigned long, timespec const*) (fds=0x7f88b800bb48, nfds=1, timeout_ts=timeout_ts@entry=0x0) at kernel/qcore_unix.cpp:153
#5  0x00007f88cd338031 in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=<optimized out>, flags=...) at ../../include/QtCore/../../src/corelib/tools/qarraydata.h:211
#6  0x00007f88cd2e323b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7f88c69e6cf0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:140
#7  0x00007f88cd11bf91 in QThread::exec() (this=<optimized out>) at ../../include/QtCore/../../src/corelib/global/qflags.h:120
#8  0x00007f88cb7cf4f6 in  () at /usr/lib64/libQt5DBus.so.5
#9  0x00007f88cd11d112 in QThreadPrivate::start(void*) (arg=0x7f88cb851d80) at thread/qthread_unix.cpp:360
#10 0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#11 0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7f88c768f700 (LWP 13944)):
#0  0x00007f88ce802cbf in __GI___poll (fds=0x7f88c768ec28, nfds=1, timeout=-1) at ../sysdeps/unix/sysv/linux/poll.c:29
#1  0x00007f88cd03d742 in  () at /usr/lib64/libxcb.so.1
#2  0x00007f88cd03e3fa in xcb_wait_for_event () at /usr/lib64/libxcb.so.1
#3  0x00007f88c7802f18 in QXcbEventQueue::run() (this=0x55b92c305260) at qxcbeventqueue.cpp:228
#4  0x00007f88cd11d112 in QThreadPrivate::start(void*) (arg=0x55b92c305260) at thread/qthread_unix.cpp:360
#5  0x00007f88cc6a0faa in start_thread (arg=<optimized out>) at pthread_create.c:486
#6  0x00007f88ce80d73f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7f88cc8e5880 (LWP 13933)):
[KCrash Handler]
#5  0x00007f88ce74bdd1 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#6  0x00007f88ce735549 in __GI_abort () at abort.c:79
#7  0x00007f88cced964f in  () at /usr/lib64/libstdc++.so.6
#8  0x00007f88ccee5088 in  () at /usr/lib64/libstdc++.so.6
#9  0x00007f88ccee50d3 in  () at /usr/lib64/libstdc++.so.6
#10 0x00007f88ccee5d41 in  () at /usr/lib64/libstdc++.so.6
#11 0x00007f88ce622593 in KWin::Workspace::removeDeleted(KWin::Deleted*) () at /usr/lib64/libkwin.so.5
#12 0x00007f88ce5648e0 in KWin::Deleted::~Deleted() () at /usr/lib64/libkwin.so.5
#13 0x00007f88ce564b49 in KWin::Deleted::~Deleted() () at /usr/lib64/libkwin.so.5
#14 0x00007f88ce576972 in KWin::Compositor::stop() () at /usr/lib64/libkwin.so.5
#15 0x00007f88ce576f3f in KWin::Compositor::~Compositor() () at /usr/lib64/libkwin.so.5
#16 0x00007f88ce62ca57 in  () at /usr/lib64/libkwin.so.5
#17 0x00007f88ce70864e in  () at /usr/lib64/libkdeinit5_kwin_x11.so
#18 0x00007f88cd30f548 in QMetaObject::activate(QObject*, int, int, void**) (sender=0x55b92c3cc8b0, signalOffset=<optimized out>, local_signal_index=<optimized out>, argv=<optimized out>) at kernel/qobject.cpp:3807
#19 0x00007f88ce27872c in KSelectionOwner::filterEvent(void*) () at /usr/lib64/libKF5WindowSystem.so.5
#20 0x00007f88cd2e2117 in QAbstractEventDispatcher::filterNativeEvent(QByteArray const&, void*, long*) (this=<optimized out>, eventType=..., message=message@entry=0x7f88c000c180, result=result@entry=0x7fffe0b78788) at kernel/qabstracteventdispatcher.cpp:484
#21 0x00007f88c77da981 in QXcbConnection::handleXcbEvent(xcb_generic_event_t*) (this=this@entry=0x55b92c2f21a0, event=event@entry=0x7f88c000c180) at qxcbnativeinterface.h:101
#22 0x00007f88c77db6d6 in QXcbConnection::processXcbEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55b92c2f21a0, flags=...) at qxcbconnection.cpp:1019
#23 0x00007f88c78041dc in QXcbUnixEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (this=0x55b92c39cdb0, flags=...) at qxcbeventdispatcher.cpp:61
#24 0x00007f88cd2e323b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (this=this@entry=0x7fffe0b788d0, flags=..., flags@entry=...) at ../../include/QtCore/../../src/corelib/global/qflags.h:140
#25 0x00007f88cd2eadb2 in QCoreApplication::exec() () at ../../include/QtCore/../../src/corelib/global/qflags.h:120
#26 0x00007f88ce709006 in kdemain () at /usr/lib64/libkdeinit5_kwin_x11.so
#27 0x00007f88ce736bcb in __libc_start_main (main=0x55b92a66d050, argc=1, argv=0x7fffe0b78b68, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffe0b78b58) at ../csu/libc-start.c:308
#28 0x000055b92a66d08a in _start ()
[Inferior 1 (process 13933) detached]

Possible duplicates by query: bug 411017, bug 410978, bug 410935, bug 410884, bug 410869.

Reported using DrKonqi
Comment 1 Tony 2019-08-18 23:35:41 UTC
Created attachment 122236 [details]
How to
Comment 2 Tony 2019-08-19 00:21:15 UTC
Created attachment 122238 [details]
Better bactrace?
Comment 3 Martin Flöser 2019-08-19 06:45:14 UTC
Unfortunately the backtrace is lacking debug symbols. if you are able to reproduce please install debug packages and attach a new backtrace.
Comment 4 Tony 2019-08-19 18:59:19 UTC
Created attachment 122246 [details]
I thought they were installed since i did not get the prompt to do so. Anyways here it is with debug symbols.
Comment 5 Martin Flöser 2019-08-20 06:37:29 UTC
Backtrace is better. What we can see is the previous KWin instance crashing on tear down.
Comment 6 Vlad Zahorodnii 2019-08-20 17:58:54 UTC
@Martin This crash happens because kwin calls a pure virtual method from destructor of a base class. See https://phabricator.kde.org/D23098

The proposed patch works around the problem.
Comment 7 Vlad Zahorodnii 2019-08-20 18:01:41 UTC
(In reply to Martin Flöser from comment #5)
> What we can see is the previous KWin instance crashing on tear down.
kwin crashes starting from this change 1db84a2ba71657a26d2a7971eb0c35e2716742c3
Comment 8 Vlad Zahorodnii 2019-08-31 10:31:46 UTC
Git commit d2bbd2a124846853748e1cb72e0e39f0cd8ae26f by Vlad Zagorodniy.
Committed on 31/08/2019 at 10:31.
Pushed by vladz into branch 'master'.

[x11] Fix crash during tear down

Summary:
Any call made to a virtual method in constructor/destructor of a base
class won't go to a derived class because the base class may access
uninitialized or destroyed resources.

For example, let's consider the following two classes

    class Base {
    public:
        Base() { foo()->bar(); }
        virtual ~Base() { foo()->bar(); }

        virtual Foo* foo() const { return nullptr; }
    };

    class Derived : public Base {
    public:
        Derived() : mFoo(new Foo) {}
        ~Derived() override { delete mFoo; }

        Foo* foo() const override { return mFoo; }

    private:
        Foo* mFoo;
    };

When an instance of Derived class is created, constructors will run in
the following order:

    Base()
    Derived()

It's not safe to dispatch foo() method call to Derived class because
constructor of Derived hasn't initialized yet mFoo.

Same story with destructors, they'll run in the following order:

    ~Derived()
    ~Base()

It's not safe to dispatch foo() method call in the destructor of Base
class to Derived class because mFoo was deleted.

So, what does that weird C++ behavior has something to do with KWin? Well,
recently Compositor class was split into two classes - WaylandCompositor,
and X11Compositor. Some functionality from X11 doesn't make sense on
Wayland. Therefore methods that implement that stuff were "purified," i.e.
they became pure virtual methods. Unfortunately, when Compositor tears
down it may call pure virtual methods on itself. Given that those calls
cannot be dispatched to X11Compositor or WaylandCompositor, the only
choice that C++ runtime has is to throw an exception.

The fix for this very delicate problem is very simple - do not call virtual
methods from constructors and the destructor. Avoid doing that if you can!

This change moves Compositor::updateClientCompositeBlocking to X11Compositor
so it longer has to be a virtual method. Also, it kind of doesn't make sense
to keep it in base Compositor class because compositing can be blocked only
on X11.

Test Plan: KWin no longer crashes when running kwin_x11 --replace command.

Reviewers: #kwin, romangg

Reviewed By: #kwin, romangg

Subscribers: anthonyfieroni, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D23098

M  +5    -16   composite.cpp
M  +3    -9    composite.h
M  +8    -3    workspace.cpp

https://commits.kde.org/kwin/d2bbd2a124846853748e1cb72e0e39f0cd8ae26f