Bug 493797 - After dragging windows to screen edge, KWin sometimes freezes in an infinite loop (wayland & x11)
Summary: After dragging windows to screen edge, KWin sometimes freezes in an infinite ...
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: general (other bugs)
Version First Reported In: 6.2.4
Platform: Gentoo Packages Linux
: HI crash
Target Milestone: ---
Assignee: fanzhuyifan
URL:
Keywords:
: 498544 498849 499913 500015 500250 500456 501132 (view as bug list)
Depends on:
Blocks:
 
Reported: 2024-09-28 22:09 UTC by acmondor
Modified: 2025-03-07 16:32 UTC (History)
14 users (show)

See Also:
Latest Commit:
Version Fixed In: 6.3.3
Sentry Crash Report:


Attachments
gdb backtrace (10.68 KB, text/plain)
2024-09-28 22:09 UTC, acmondor
Details
qdbus6 org.kde.KWin /KWin supportInformation (6.28 KB, text/plain)
2024-09-28 22:10 UTC, acmondor
Details
qdbus6 org.kde.KWin /KWin supportInformation (wayland) (6.26 KB, text/plain)
2024-12-09 20:21 UTC, acmondor
Details
qdbus6 org.kde.KWin /KWin supportInformation (x11) (6.12 KB, text/plain)
2024-12-09 20:22 UTC, acmondor
Details

Note You need to log in before you can comment on or make changes to this bug.
Description acmondor 2024-09-28 22:09:13 UTC
Created attachment 174180 [details]
gdb backtrace

SUMMARY

Since switching to plasma 6 I observed the entire screen freezing, except for the mouse which can still be moved
around on the screen but it has the hand icon (ie that used for move) and it can't be used to click on anything.
Also, when the screen is frozen, kwin_x11 is running at 100% cpu and attaching a debugger to it shows that it is
stuck in window.cpp in the for(;;) loop in the following method:

  QRectF Window::nextInteractiveMoveGeometry(const QPointF &global) const

This issue initially seemed somewhat random and was observed when opening or moving firefox near the top of the screen, but I since determined it has nothing to do with firefox and can be triggered by moving any application around
the desktop with its title bar at or near the top of the screen. I have reproduced this problem with Konsole, Kate, and KMajongg on two different systems.

The only way to recover is to kill the session via a virtual terminal or a ssh connection. A recovery can also
be done using gdb (see  ADDITIONAL INFORMATION below) to force an exit from the stuck for(;;) loop, but that's only practical if one has built kwin_x11 with debug symbols.

I have not been able to determine if the issue exists with wayland, as I currently cannot run wayland. I just
get a blank black screen when trying to run a wayland session. I also only have single monitor on my machines, so
I do not know if systems with multiple screens are affected.

I build kwin_x11 with debug symbols and attached gdb after a lockup and from what I observed it seems to be
related to a rounding error of floating point math, at least in the check that is intended to avoid such lockups:

            // Move it back
            currentTry.translate(dx, dy);
            nextMoveResizeGeom = currentTry;

            if (std::abs(currentMoveResizeGeom.left() - nextMoveResizeGeom.left()) < 1.0
                && std::abs(currentMoveResizeGeom.right() - nextMoveResizeGeom.right()) < 1.0
                && std::abs(currentMoveResizeGeom.top() - nextMoveResizeGeom.top()) < 1.0
                && std::abs(currentMoveResizeGeom.bottom() - nextMoveResizeGeom.bottom()) < 1.0) {
                break; // Prevent lockup
            }

Note rebuilding kwin_x11 with the " < 1.0" in the above code changed to " =< 1.0" avoids the issue, but has the site effect of allowing one to move an application so its title bar is mostly beyond the top of the screen. Perhaps that's the purpose of the nextInteractiveMoveGeometry (ie keeping the title bar visible)?


STEPS TO REPRODUCE
1. To get the screen to freeze one just needs to quickly move an application (eg Konsole) around the desktop with its title
bar at or near the top of the screen. I can usually create a lockup in less than a minute. I sometimes have to grab and release the title bar of the application mutiple times and time grab the title bar at a different location. Sometimes resizing the window helps too. When the freeze occurs the window will no longer move and the mouse icon won't change when the mouse is released. If the system doesn't seem to want to freeze up, try opening a second instance of the application taking turns moving both of them around at the top of the screen.


OBSERVED RESULT
Desktop freezes

EXPECTED RESULT
Desktop should not freeze, regardless of how/where an application is moved around on the screen.

SOFTWARE/OS VERSIONS
Windows: 
macOS: 
(available in the Info Center app, or by running `kinfo` in a terminal window)
Linux/KDE Plasma: Gentoo
KDE Plasma Version: 6.1.5
KDE Frameworks Version: 6.5.0
Qt Version: 6.7.2
Kernel 6.6.52  x86_64

ADDITIONAL INFORMATION

Steps used to debug the issue:

1) Build kwin with debug symbols and install that on the test system

2) Cause the screen to freeze as mentioned above

3) From another machine ssh to the frozen system and attach gdb to the kwin_x11 process:

    gdb /usr/bin/kwin_x11 $(pidof kwin_x11)


4) Set a break point in Window::nextInteractiveMoveGeometry for "nextMoveResizeGeom = currentTry;" (should be window.cpp:1714), that is the line before the if statement mentioned above (ie one intended to prevent lockups):

    b window.cpp:1714

5) continue until breakpoint hit:

    continue

6) run the following to monitor some key values:
   display currentMoveResizeGeom
   display nextMoveResizeGeom
   display currentTry
   
7) do another loop:

    continue

8) observe the displayed values, will be something like the following:
    1: currentMoveResizeGeom = {xp = 124, yp = 0, w = 1086, h = 749}
    2: nextMoveResizeGeom = {xp = 124, yp = -0.99999999999999822, w = 1086, h = 749}
    3: currentTry = {xp = 124, yp = -0.99999999999999822, w = 1086, h = 749}

9) repeat 7 & 8 as needed and notice the displayed values never change and hence there is no way for the
   code to get out of the for(;;) loop

10) to force an exit from the for(;;) loop and recover from the lockup do the following:

   next                                                     (step over "nextMoveResizeGeom = currentTry;") 
   delete                                                  (remove all breakpoints)
   return nextMoveResizeGeom        (get out of stuck for(;;) loop, ignore the warning about function's return value)
   continue                                             (allow the app to run. one can also exit gdb with 'quit')

11) observe that the screen on the test system is working again
Comment 1 acmondor 2024-09-28 22:10:41 UTC
Created attachment 174181 [details]
qdbus6 org.kde.KWin /KWin supportInformation
Comment 2 acmondor 2024-12-09 20:18:57 UTC
I confirmed to today that this problem does exists on both wayland and x11 and still exists with the following:

Linux/KDE Plasma: Gentoo
KDE Plasma Version: 6.2.4
KDE Frameworks Version: 6.7.0
Qt Version: 6.7.3
Kernel 6.6.62  x86_64

Also, with 6.2.4, the problem seems to be much much easier to reproduce. I was to get kwin to lock up both wayland and x11 on my first attempt doing this:

1) Right after logging in open a konsole window.
2) Grab the title bar of the konsole window and drag the window to the top of the screen.
3) Observe that the screen is completely frozen.

The only way to recover the machine is to login via a virtual terminal or ssh connection and kill off the plasma session.

Like mentioned in the original summary, rebuilding kwin with the change to window.cpp (ie replacing " < 1.0" with " =< 1.0") avoids the issue on both wayland and x11.
Comment 3 acmondor 2024-12-09 20:21:45 UTC
Created attachment 176464 [details]
qdbus6 org.kde.KWin /KWin supportInformation (wayland)
Comment 4 acmondor 2024-12-09 20:22:11 UTC
Created attachment 176465 [details]
qdbus6 org.kde.KWin /KWin supportInformation (x11)
Comment 5 fanzhuyifan 2025-01-16 17:09:28 UTC
*** Bug 498544 has been marked as a duplicate of this bug. ***
Comment 8 Bug Janitor Service 2025-02-18 04:22:11 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/7179
Comment 9 fanzhuyifan 2025-02-20 15:19:38 UTC
*** Bug 500456 has been marked as a duplicate of this bug. ***
Comment 10 fanzhuyifan 2025-02-24 16:26:37 UTC
*** Bug 500015 has been marked as a duplicate of this bug. ***
Comment 11 fanzhuyifan 2025-02-24 16:26:56 UTC
*** Bug 499913 has been marked as a duplicate of this bug. ***
Comment 12 fanzhuyifan 2025-02-24 17:17:03 UTC
*** Bug 500250 has been marked as a duplicate of this bug. ***
Comment 13 antonio 2025-02-24 17:46:57 UTC
Note that the desktop also freezes dragging windows to the bottom of the screen (with the window title going below the panel).
Comment 14 fanzhuyifan 2025-02-24 17:48:37 UTC
(In reply to antonio from comment #13)
> Note that the desktop also freezes dragging windows to the bottom of the
> screen (with the window title going below the panel).

This is expected and will be fixed by the MR
Comment 15 fanzhuyifan 2025-02-24 17:53:38 UTC
Git commit 76516a10c0230e0bc5d3fc65e3998425075a6cda by Yifan Zhu.
Committed on 24/02/2025 at 17:36.
Pushed by fanzhuyifan into branch 'master'.

window: reimplement restriction in moveResize

In restricted moveResize, try to guarantee at least a 100px contiguous
block of the titlebar is visible. Previously this was implemented by
shifting the geometry by 1px increments, trying to find a suitable
position. This is inefficient and error-prone.

Replace this with an efficient algorithm that finds the closest
candidate position. Consolidate the restriction code and add tests.
Related: bug 401271, bug 481610

M  +396  -1    autotests/integration/move_resize_window_test.cpp
M  +3    -3    autotests/integration/x11_window_test.cpp
A  +-    --    doc/moveresizerestriction/moveresizerestriction.pdf
A  +232  -0    doc/moveresizerestriction/moveresizerestriction.tex
M  +266  -172  src/window.cpp
M  +1    -1    src/window.h

https://invent.kde.org/plasma/kwin/-/commit/76516a10c0230e0bc5d3fc65e3998425075a6cda
Comment 16 fanzhuyifan 2025-02-25 13:50:21 UTC
*** Bug 498849 has been marked as a duplicate of this bug. ***
Comment 17 Vlad Zahorodnii 2025-03-06 23:02:04 UTC
Git commit cb0e06d2900add3387e235a62f94cbfb914d0deb by Vlad Zahorodnii, on behalf of Yifan Zhu.
Committed on 06/03/2025 at 22:09.
Pushed by vladz into branch 'Plasma/6.3'.

window: reimplement restriction in moveResize

In restricted moveResize, try to guarantee at least a 100px contiguous
block of the titlebar is visible. Previously this was implemented by
shifting the geometry by 1px increments, trying to find a suitable
position. This is inefficient and error-prone.

Replace this with an efficient algorithm that finds the closest
candidate position. Consolidate the restriction code and add tests.
Related: bug 401271, bug 481610
(cherry picked from commit 76516a10c0230e0bc5d3fc65e3998425075a6cda)

M  +396  -1    autotests/integration/move_resize_window_test.cpp
M  +3    -3    autotests/integration/x11_window_test.cpp
A  +-    --    doc/moveresizerestriction/moveresizerestriction.pdf
A  +232  -0    doc/moveresizerestriction/moveresizerestriction.tex
M  +266  -172  src/window.cpp
M  +1    -1    src/window.h

https://invent.kde.org/plasma/kwin/-/commit/cb0e06d2900add3387e235a62f94cbfb914d0deb
Comment 18 Nate Graham 2025-03-07 16:32:06 UTC
*** Bug 501132 has been marked as a duplicate of this bug. ***