https://bugs.kde.org/show_bug.cgi?id=493797

            Bug ID: 493797
           Summary: screen freezes due to kwin_x11 stuck in infinite loop
    Classification: Plasma
           Product: kwin
           Version: 6.1.5
          Platform: Gentoo Packages
                OS: Linux
            Status: REPORTED
          Severity: crash
          Priority: NOR
         Component: X11 Integration
          Assignee: kwin-bugs-n...@kde.org
          Reporter: bugs....@acmondor.ca
  Target Milestone: ---

Created attachment 174180
  --> https://bugs.kde.org/attachment.cgi?id=174180&action=edit
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

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to