Bug 513768 - kwin_wayland 100% CPU spinloop in std::_Rb_tree_increment upon screen unlock (triggered by wl_client_destroy)
Summary: kwin_wayland 100% CPU spinloop in std::_Rb_tree_increment upon screen unlock ...
Status: REOPENED
Alias: None
Product: kwin
Classification: Plasma
Component: wayland-generic (other bugs)
Version First Reported In: 6.5.4
Platform: Manjaro Linux
: NOR major
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-12-24 06:03 UTC by logjian
Modified: 2025-12-26 02:28 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments
plasma-kwin_wayland's journal logs last 300 lines (30.98 KB, text/plain)
2025-12-24 06:03 UTC, logjian
Details

Note You need to log in before you can comment on or make changes to this bug.
Description logjian 2025-12-24 06:03:37 UTC
Created attachment 187930 [details]
plasma-kwin_wayland's journal logs last 300 lines

SUMMARY
Overview: After unlocking the screen (Wayland session), the system UI completely froze. kwin_wayland process consumed 100% CPU. I was able to SSH into the machine. strace showed no output (indicating a user-space spinloop), but attaching GDB revealed an infinite loop within std::local_Rb_tree_increment, likely due to container corruption during the cleanup of a Wayland client resource.

STEPS TO REPRODUCE
1. Log in to a Plasma Wayland session.
2. Lock the screen.
3. Wait for a few hours(in my case normally from 18:00 on last day to 10:00 on next day, is 16 hours)
4. Unlock the screen.

OBSERVED RESULT
1. The screen freezes immediately after unlocking, mouse won't move and .
2. kwin_wayland process spikes to 100% CPU usage (observed through ssh session).
3. dmesg shows no kernel panics or OOM errors (observed through ssh session).
4. strace -p <kwin_pid> shows no syscall output (silent spinloop) (observed through ssh session).

EXPECTED RESULT
normally unlock the screen

SOFTWARE/OS VERSIONS
Operating System: Manjaro Linux 
KDE Plasma Version: 6.5.4
KDE Frameworks Version: 6.21.0
Qt Version: 6.10.1
Kernel Version: 6.12.62-1-MANJARO (64-bit)
Graphics Platform: Wayland
Processors: 12 × AMD Ryzen 5 5600G with Radeon Graphics
Memory: 32 GiB of RAM (30.6 GiB usable)
Graphics Processor: AMD Radeon Graphics

ADDITIONAL INFORMATION
some debug logs
1. GDB Backtrace: Attaching GDB to the frozen process shows thread 1 stuck in an infinite loop inside std::_Rb_tree_increment, called during wl_client_destroy. This suggests that ScreenLocker::KSldApp::doUnlock() triggered a resource cleanup that may hit a corrupted std::map or std::set.
thread 1 (Thread 0x7fdc87cd6b80 (LWP 1473) "kwin_wayland"):
#0  0x00007fdc8e8cbca7 in std::local_Rb_tree_increment (__x=0x5559728491b0) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++98/tree.cc:65
#1  std::_Rb_tree_increment (__x=0x555972aa8380) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++98/tree.cc:85
#2  0x00007fdc91c3b54a in ?? () from /usr/lib/libkwin.so.6
#3  0x00007fdc8f2dcba0 in ?? () from /usr/lib/libwayland-server.so.0
#4  0x00007fdc8f2dcdd2 in wl_client_destroy () from /usr/lib/libwayland-server.so.0
#5  0x00007fdc919e8377 in ?? () from /usr/lib/libkwin.so.6
#6  0x00007fdc8edd734f in ?? () from /usr/lib/libQt6Core.so.6
#7  0x00007fdc8e2fdad9 in ScreenLocker::KSldApp::doUnlock() () from /usr/lib/libKScreenLocker.so.6
#8  0x00007fdc8e2fe370 in ?? () from /usr/lib/libKScreenLocker.so.6
#9  0x00007fdc8edd734f in ?? () from /usr/lib/libQt6Core.so.6
#10 0x00007fdc8ef9599f in ?? () from /usr/lib/libQt6Core.so.6
#11 0x00007fdc8ef98d24 in ?? () from /usr/lib/libQt6Core.so.6
#12 0x00007fdc8edd771a in ?? () from /usr/lib/libQt6Core.so.6
#13 0x00007fdc8ede23c0 in QSocketNotifier::event(QEvent*) () from /usr/lib/libQt6Core.so.6
#14 0x00007fdc8ff021c0 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/libQt6Widgets.so.6
#15 0x00007fdc8ed6a958 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/lib/libQt6Core.so.6
#16 0x00007fdc8ef2dcb9 in QEventDispatcherUNIXPrivate::activateSocketNotifiers() () from /usr/lib/libQt6Core.so.6
#17 0x00007fdc8ef2e77c in QEventDispatcherUNIX::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt6Core.so.6
#18 0x00007fdc8fb34b73 in QUnixEventDispatcherQPA::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt6Gui.so.6
#19 0x00007fdc8ed75786 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/libQt6Core.so.6
#20 0x00007fdc8ed6f3f1 in QCoreApplication::exec() () from /usr/lib/libQt6Core.so.6
#21 0x000055595c53aaa4 in ?? ()
#22 0x00007fdc8e427635 in ?? () from /usr/lib/libc.so.6
#23 0x00007fdc8e4276e9 in __libc_start_main () from /usr/lib/libc.so.6
#24 0x000055595c540f75 in ?? ()

2. Journal Logs: Just before and during the freeze, journalctl shows errors regarding unknown popups and DRM permission failures. It seems like the atomic modeset failure might be related to the corrupted state leading to the crash.
blow log got from command `journalctl --user -u plasma-kwin_wayland`
... too many kscreenlocker_greet message
Dec 24 09:36:05 venus kscreenlocker_greet[75683]: Cannot attach popup of unknown type
Dec 24 09:36:05 venus kscreenlocker_greet[75683]: Cannot attach popup of unknown type
Dec 24 09:36:05 venus kscreenlocker_greet[75683]: Cannot attach popup of unknown type
Dec 24 09:36:06 venus kwin_wayland[1473]: atomic commit failed: Permission denied
Dec 24 09:36:06 venus kwin_wayland[1473]: Atomic modeset test failed! Permission denied
Dec 24 09:36:06 venus kwin_wayland[1473]: Applying output configuration failed!
Dec 24 09:36:10 venus kwin_wayland[1473]: Atomic modeset test failed! Permission denied
Dec 24 09:36:10 venus kwin_wayland[1473]: Applying output configuration failed!
I entered the password and try unlock the screen at Dec 24 09:36.
log file is too looooooong so I upload last 300 lines as attachment.
Comment 1 TraceyC 2025-12-24 16:53:41 UTC
Thanks for the bug report, and the detailed logs. Unfortunately, the backtrace is missing debug symbols, as you can see by the ?? in these lines:

#2  0x00007fdc91c3b54a in ?? () from /usr/lib/libkwin.so.6
#3  0x00007fdc8f2dcba0 in ?? () from /usr/lib/libwayland-server.so.0
#6  0x00007fdc8edd734f in ?? () from /usr/lib/libQt6Core.so.6
#8  0x00007fdc8e2fe370 in ?? () from /usr/lib/libKScreenLocker.so.6

Could you please install debug packages and attach a new symbolicated backtrace, when this happens again?

I haven't seen this in Plasma built from git-master on two different systems. There's enough information here for the kwin developers to start investigating, so I'll leave it to them.
Comment 2 logjian 2025-12-25 05:42:07 UTC
(In reply to TraceyC from comment #1)
> Could you please install debug packages and attach a new symbolicated
> backtrace, when this happens again?
I am glad to help. It may take some time. I will comment again when I have a symbolicated backtrace.
Comment 3 David Edmundson 2025-12-25 08:18:45 UTC
Please reopen this ticket when you do
Comment 4 logjian 2025-12-26 02:28:28 UTC
I got the symbolicated backtrace through debuginfod. I hope it's helpful.

#0  0x00007f1ab6ccbca7 in std::local_Rb_tree_increment (__x=0x56524e4ebfa0) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++98/tree.cc:65
#1  std::_Rb_tree_increment (__x=0x56524e1bf600) at /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++98/tree.cc:85
#2  0x00007f1aba03b54a in std::_Rb_tree_iterator<std::pair<wl_client* const, QtWaylandServer::xdg_wm_base::Resource*> >::operator++ (this=<synthetic pointer>) at /usr/include/c++/15.2.1/bits/stl_tree.h:402
#3  QMultiMap<wl_client*, QtWaylandServer::xdg_wm_base::Resource*>::remove (key=<optimized out>, value=<synthetic pointer>: <optimized out>, this=0x565249f32168) at /usr/include/qt6/QtCore/qmap.h:1023
#4  QtWaylandServer::xdg_wm_base::destroy_func (client_resource=<optimized out>) at /usr/src/debug/kwin/build/src/wayland/qwayland-server-xdg-shell.cpp:153
#5  0x00007f1ab7643ba0 in remove_and_destroy_resource (element=0x56524b092b90, data=data@entry=0x0, flags=0) at ../wayland-1.24.0/src/wayland-server.c:796
#6  0x00007f1ab7643dd2 in for_each_helper (entries=0x56524af7cc10, func=0x7f1ab7643b00 <remove_and_destroy_resource>, data=0x0) at ../wayland-1.24.0/src/wayland-util.c:430
#7  wl_map_for_each (map=0x56524af7cc10, func=0x7f1ab7643b00 <remove_and_destroy_resource>, data=0x0) at ../wayland-1.24.0/src/wayland-util.c:444
#8  wl_client_destroy (client=0x56524af7cbe0) at ../wayland-1.24.0/src/wayland-server.c:1014
#9  0x00007f1ab9de8377 in operator() (__closure=0x565249f0ce20) at /usr/src/debug/kwin/kwin-6.5.4/src/wayland_server.cpp:676
#10 operator() (__closure=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:116
#11 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<long unsigned int>, QtPrivate::List<>, void, KWin::WaylandServer::initScreenLocker()::<lambda()> >::call(KWin::WaylandServer::initScreenLocker()::<lambda()>&, void**)::<lambda()> > (args=<optimized out>, fn=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
#12 QtPrivate::FunctorCall<std::integer_sequence<long unsigned int>, QtPrivate::List<>, void, KWin::WaylandServer::initScreenLocker()::<lambda()> >::call (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:115
#13 QtPrivate::FunctorCallable<KWin::WaylandServer::initScreenLocker()::<lambda()> >::call<QtPrivate::List<>, void> (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:337
#14 QtPrivate::QCallableObject<KWin::WaylandServer::initScreenLocker()::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=0x565249f0ce10, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:547
#15 0x00007f1ab71d734f in QtPrivate::QSlotObjectBase::call (this=<optimized out>, r=<optimized out>, a=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobjectdefs_impl.h:461
#16 doActivate<false> (sender=<optimized out>, signal_index=<optimized out>, argv=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:4257
#17 0x00007f1ab6659ad9 in ScreenLocker::KSldApp::doUnlock (this=0x565249d99400) at /usr/src/debug/kscreenlocker/kscreenlocker-6.5.4/ksldapp.cpp:622
#18 0x00007f1ab665a1f1 in ScreenLocker::KSldApp::lockProcessRequestedUnlock (this=<optimized out>) at /usr/src/debug/kscreenlocker/kscreenlocker-6.5.4/ksldapp.cpp:392
#19 0x00007f1ab665a370 in operator() (__closure=<optimized out>) at /usr/src/debug/kscreenlocker/kscreenlocker-6.5.4/ksldapp.cpp:235
#20 operator() (__closure=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:116
#21 QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<long unsigned int>, QtPrivate::List<>, void, ScreenLocker::KSldApp::initialize()::<lambda()> >::call(ScreenLocker::KSldApp::initialize()::<lambda()>&, void**)::<lambda()> > (args=<optimized out>, fn=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65
#22 QtPrivate::FunctorCall<std::integer_sequence<long unsigned int>, QtPrivate::List<>, void, ScreenLocker::KSldApp::initialize()::<lambda()> >::call (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:115
#23 QtPrivate::FunctorCallable<ScreenLocker::KSldApp::initialize()::<lambda()> >::call<QtPrivate::List<>, void> (f=..., arg=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:337
#24 QtPrivate::QCallableObject<ScreenLocker::KSldApp::initialize()::<lambda()>, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase *, QObject *, void **, bool *) (which=<optimized out>, this_=<optimized out>, r=<optimized out>, a=<optimized out>, ret=<optimized out>) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:547
#25 0x00007f1ab71d734f in QtPrivate::QSlotObjectBase::call (this=<optimized out>, r=<optimized out>, a=<optimized out>, this=<optimized out>, r=<optimized out>, a=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobjectdefs_impl.h:461
#26 doActivate<false> (sender=<optimized out>, signal_index=<optimized out>, argv=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:4257
#27 0x00007f1ab739599f in QIODevice::readyRead (this=0x565249f03660) at /usr/src/debug/qt6-base/build/src/corelib/Core_autogen/include/moc_qiodevice.cpp:156
#28 QProcessPrivate::tryReadFromChannel (this=0x565249cd3d30, channel=0x565249cd3ef0) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qprocess.cpp:1181
#29 0x00007f1ab7398d24 in QProcessPrivate::_q_canReadStandardOutput (this=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qprocess.cpp:1197
#30 QProcess::qt_static_metacall (_o=<optimized out>, _c=<optimized out>, _id=<optimized out>, _a=0x7ffd72faac90) at /usr/src/debug/qt6-base/build/src/corelib/Core_autogen/include/moc_qprocess.cpp:198
#31 0x00007f1ab71d771a in doActivate<false> (sender=<optimized out>, signal_index=<optimized out>, argv=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobject.cpp:4269
#32 0x00007f1ab71e23c0 in QMetaObject::activate<void, QSocketDescriptor, QSocketNotifier::Type, QSocketNotifier::QPrivateSignal> (sender=0x56524aa64220, mo=<optimized out>, local_signal_index=0, ret=0x0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qobjectdefs.h:319
#33 QSocketNotifier::activated (this=0x56524aa64220, _t1=..., _t2=<optimized out>, _t3=...) at /usr/src/debug/qt6-base/build/src/corelib/Core_autogen/include/moc_qsocketnotifier.cpp:161
#34 QSocketNotifier::event (this=0x56524aa64220, e=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qsocketnotifier.cpp:324
#35 0x00007f1ab83021c0 in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x56524aa64220, e=0x7ffd72faadb0) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:3305
#36 0x00007f1ab716a958 in QCoreApplication::notifyInternal2 (receiver=0x56524aa64220, event=0x7ffd72faadb0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109
#37 0x00007f1ab732dcb9 in QCoreApplication::sendEvent (receiver=<optimized out>, event=0x7ffd72faadb0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1549
#38 QEventDispatcherUNIXPrivate::activateSocketNotifiers (this=this@entry=0x565249176180) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp:276
#39 0x00007f1ab732e77c in QEventDispatcherUNIX::processEvents (this=<optimized out>, flags=..., flags@entry=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp:498
#40 0x00007f1ab7f34b73 in QUnixEventDispatcherQPA::processEvents (this=<optimized out>, flags=...) at /usr/src/debug/qt6-base/qtbase/src/gui/platform/unix/qunixeventdispatcher.cpp:28
#41 0x00007f1ab7175786 in QEventLoop::processEvents (this=0x7ffd72faaf80, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:104
#42 QEventLoop::exec (this=0x7ffd72faaf80, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:186
#43 0x00007f1ab716f3f1 in QCoreApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1452
#44 0x00007f1ab82fd32a in QApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:2575
#45 0x000056521636eaa4 in main (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/kwin/kwin-6.5.4/src/main_wayland.cpp:635