Bug 406784 - Alt-tab makes KWin crash when the window is destroyed during switch
Summary: Alt-tab makes KWin crash when the window is destroyed during switch
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: general (show other bugs)
Version: 5.15.3
Platform: Gentoo Packages Linux
: NOR crash
Target Milestone: ---
Assignee: KWin default assignee
URL: https://phabricator.kde.org/D20916
Keywords: drkonqi
: 409815 (view as bug list)
Depends on:
Blocks:
 
Reported: 2019-04-22 20:23 UTC by Stefano
Modified: 2019-07-15 14:05 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In: 5.16.0
vlad.zahorodnii: ReviewRequest+


Attachments
screen recording (1.93 MB, video/x-matroska)
2019-04-22 21:37 UTC, Stefano
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stefano 2019-04-22 20:23:23 UTC
Application: kwin_x11 (5.15.3)

Qt Version: 5.11.3
Frameworks Version: 5.56.0
Operating System: Linux 4.19.0-sabayon x86_64
Distribution: "Sabayon Linux amd64 19.01"

-- Information about the crash:
- What I was doing when the application crashed:
I was using Audacity, the main window creates dialog boxes when for example exporting an audio. If I do alt-tab and I select the child dialog in the same moment it is being destroyed, KWin crashes. I repeated multiple times and it always happens the same.

The crash can be reproduced every time.

-- Backtrace:
Application: KWin (kwin_x11), signal: Segmentation fault
[KCrash Handler]
#6  0x0000000000000000 in ?? ()
#7  0x00007f1e620e9e4d in KWin::Workspace::constrainedStackingOrder() () from /usr/lib64/libkwin.so.5
#8  0x00007f1e620ea9a8 in KWin::Workspace::updateStackingOrder(bool) () from /usr/lib64/libkwin.so.5
#9  0x00007f1e620eacc9 in KWin::Workspace::blockStackingUpdates(bool) () from /usr/lib64/libkwin.so.5
#10 0x00007f1e62088fad in KWin::Client::destroyClient() () from /usr/lib64/libkwin.so.5
#11 0x00007f1e620f7f59 in KWin::Client::unmapNotifyEvent(xcb_unmap_notify_event_t*) () from /usr/lib64/libkwin.so.5
#12 0x00007f1e620fbbcb in KWin::Client::windowEvent(xcb_generic_event_t*) () from /usr/lib64/libkwin.so.5
#13 0x00007f1e620fc575 in KWin::Workspace::workspaceEvent(xcb_generic_event_t*) () from /usr/lib64/libkwin.so.5
#14 0x00007f1e5fadba77 in QAbstractEventDispatcher::filterNativeEvent(QByteArray const&, void*, long*) () from /usr/lib64/libQt5Core.so.5
#15 0x00007f1e410f8253 in QXcbConnection::handleXcbEvent(xcb_generic_event_t*) () from /usr/lib64/libQt5XcbQpa.so.5
#16 0x00007f1e410f8f34 in QXcbConnection::processXcbEvents() () from /usr/lib64/libQt5XcbQpa.so.5
#17 0x00007f1e5fb0df2a in QObject::event(QEvent*) () from /usr/lib64/libQt5Core.so.5
#18 0x00007f1e6083d70c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#19 0x00007f1e608456f3 in QApplication::notify(QObject*, QEvent*) () from /usr/lib64/libQt5Widgets.so.5
#20 0x00007f1e5fadeeb7 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib64/libQt5Core.so.5
#21 0x00007f1e5fae2371 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib64/libQt5Core.so.5
#22 0x00007f1e5fb3760a in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#23 0x00007f1e4118e41c in ?? () from /usr/lib64/libQt5XcbQpa.so.5
#24 0x00007f1e5fadd6fa in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib64/libQt5Core.so.5
#25 0x00007f1e5fae6dc0 in QCoreApplication::exec() () from /usr/lib64/libQt5Core.so.5
#26 0x00007f1e62911f6b in kdemain () from /usr/lib64/libkdeinit5_kwin_x11.so
#27 0x00007f1e62552d0a in __libc_start_main () from /lib64/libc.so.6
#28 0x0000563aa4dee82a in _start ()
[Inferior 1 (process 9255) detached]

The reporter indicates this bug may be a duplicate of or related to bug 392412, bug 402546.

Possible duplicates by query: bug 404632, bug 402546, bug 400854, bug 397514, bug 396975.

Reported using DrKonqi
Comment 1 Vlad Zahorodnii 2019-04-22 20:46:19 UTC
Do you think you could provide a screen recording? I wasted hours trying to reproduce this crash, screen recording would help me a lot.
Comment 2 Stefano 2019-04-22 21:37:55 UTC
Created attachment 119573 [details]
screen recording

I am not sure it is clear. I start the export, then I focus on Kate. Then, after pressing Alt+Tab when all the windows are present to select the one that is going to disappear, I am holding only Alt until it is closed, and soon later, when I release the key after it vanished, KWin crashes.
Hope it helps.
Comment 3 Vlad Zahorodnii 2019-04-22 22:00:36 UTC
Thanks, I've managed to reproduce the crash.
Comment 4 Vlad Zahorodnii 2019-04-22 22:03:21 UTC
Hmm, the crash occurs only when compositing is turned off.
Comment 5 Vlad Zahorodnii 2019-04-30 07:34:29 UTC
When compositing is off, unconstrained_stacking_order contains a dangling pointer (added by Workspace::restack()):

Client::destroyClient(this=0x560e5f07d1a0)
Workspace::addDeleted(c=0x560e5f06e3b0, orig=0x560e5f07d1a0)
Workspace::raiseClient(c=0x560e5e6cc830)
Workspace::lowerClient(c=0x560e5e6cc830)
Workspace::lowerClient(c=0x560e5e6cc830)
Workspace::restack(c=0x560e5f07d1a0, under=0x560e5e7a2510)
Workspace::raiseClient(c=0x560e5e6cc830)

Workspace::constrainedStackingOrder()
    unconstrained_stacking_order:
        - 0x560e5e7824a0
        - 0x560e5e795eb0
        - 0x560e5e7bfba0
        - 0x560e5f07d1a0
        - 0x560e5e7a2510
        - 0x560e5e7dcf80
        - 0x560e5f06e3b0
        - 0x560e5e79df70

When compositing is on, KWin doesn't crash. Investigating it further.
Comment 6 Vlad Zahorodnii 2019-04-30 07:38:51 UTC
Hmm when compositing is on, the tabbox doesn't invoke Workspace::restack()
Comment 7 Vlad Zahorodnii 2019-04-30 07:42:20 UTC
    if (q->isKWinCompositing()) {
        if (lastRaisedClient)
            q->elevateClient(lastRaisedClient, w, false);
        lastRaisedClient = currentClient;
        if (currentClient)
            q->elevateClient(currentClient, w, true);
    } else {
        if (lastRaisedClient) {
            q->shadeClient(lastRaisedClient, true);
            if (lastRaisedClientSucc)
                q->restack(lastRaisedClient, lastRaisedClientSucc);
 
Yeah, this explains why.
Comment 8 Vlad Zahorodnii 2019-04-30 10:12:42 UTC
KWin/Wayland may suffer from similar problem.
Comment 9 Vlad Zahorodnii 2019-05-03 18:25:23 UTC
Git commit c438ecbb702e970004e7e97e6734f57caef32ea5 by Vlad Zagorodniy.
Committed on 03/05/2019 at 18:25.
Pushed by vladz into branch 'master'.

Don't crash when highlighted tabbox client is closed

Summary:
The compositor tries to switch to the next tabbox client when currently
highlighted client is closed. Though there is a small issue with that.
Because the switch happens too late, a dangling pointer can be inserted
into the unconstrained stacking order, which can lead to a crash later on.

There are two cases:
- compositing is on;
- compositing is off.

Compositing is on: TabBox will try to un-elevate currently highlighted
client, though by that time the client no longer owns EffectWindow, so
this is basically a no-op (that's why we haven't experienced this bug
before).

Compositing is off: TabBox will try to restack currently hightlighted
client under the next tabbox client. Given that the restack method
doesn't do any sanity checks(see Client::manage why), a client that is
about to be destroyed will be re-inserted back into the unconstrained
stacking order.

This change ensures that the switch happens before currently highlighted
client is removed from the stacking order.

Test Plan:
- Turn off compositing;
- Follow steps to reproduce in the bug report (see comment 2).

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

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

M  +15   -0    client.cpp
M  +1    -6    workspace.cpp

https://commits.kde.org/kwin/c438ecbb702e970004e7e97e6734f57caef32ea5
Comment 10 Vlad Zahorodnii 2019-07-15 14:02:45 UTC
Git commit d948d247fe4371462f2fe6b96b25fd8026abafb5 by Vlad Zagorodniy.
Committed on 15/07/2019 at 13:56.
Pushed by vladz into branch 'Plasma/5.12'.

Don't crash when highlighted tabbox client is closed

Summary:
The compositor tries to switch to the next tabbox client when currently
highlighted client is closed. Though there is a small issue with that.
Because the switch happens too late, a dangling pointer can be inserted
into the unconstrained stacking order, which can lead to a crash later on.

There are two cases:
- compositing is on;
- compositing is off.

Compositing is on: TabBox will try to un-elevate currently highlighted
client, though by that time the client no longer owns EffectWindow, so
this is basically a no-op (that's why we haven't experienced this bug
before).

Compositing is off: TabBox will try to restack currently hightlighted
client under the next tabbox client. Given that the restack method
doesn't do any sanity checks(see Client::manage why), a client that is
about to be destroyed will be re-inserted back into the unconstrained
stacking order.

This change ensures that the switch happens before currently highlighted
client is removed from the stacking order.

Test Plan:
- Turn off compositing;
- Follow steps to reproduce in the bug report (see comment 2).

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: kwin

Tags: #kwin

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

M  +15   -0    client.cpp
M  +1    -6    workspace.cpp

https://commits.kde.org/kwin/d948d247fe4371462f2fe6b96b25fd8026abafb5
Comment 11 Vlad Zahorodnii 2019-07-15 14:05:08 UTC
*** Bug 409815 has been marked as a duplicate of this bug. ***