Summary: | screen freezes due to kwin_x11 stuck in infinite loop | ||
---|---|---|---|
Product: | [Plasma] kwin | Reporter: | acmondor <bugs.kde> |
Component: | X11 Integration | Assignee: | KWin default assignee <kwin-bugs-null> |
Status: | REPORTED --- | ||
Severity: | crash | ||
Priority: | NOR | ||
Version: | 6.1.5 | ||
Target Milestone: | --- | ||
Platform: | Gentoo Packages | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: |
gdb backtrace
qdbus6 org.kde.KWin /KWin supportInformation |
Created attachment 174181 [details]
qdbus6 org.kde.KWin /KWin supportInformation
|
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