Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeepassXC hangs for ~30s on screen lock/unlock #8146

Closed
gjm11 opened this issue Jun 13, 2022 · 5 comments
Closed

KeepassXC hangs for ~30s on screen lock/unlock #8146

gjm11 opened this issue Jun 13, 2022 · 5 comments
Labels

Comments

@gjm11
Copy link

gjm11 commented Jun 13, 2022

[Note: I strongly suspect that this is in fact a Qt bug and have filed https://bugreports.qt.io/browse/QTBUG-104222 in their issue tracker. But I don't know for sure, so I'm filing here too.]

Overview

I'm running KeePassXC version 2.6.6 on Ubuntu version 21.10. (2.6.6 is the version in Ubuntu's packages for version 21.10.)

When I lock my computer's screen, KeePassXC begins consuming substantial CPU -- I can hear the computer's fans start up, and toptells me it's using the whole of one core -- and continues doing so for about 20 seconds before apparently stopping. When I unlock the screen (whether or not I've waited for that to finish), as soon as the unlock screen with password prompt appears, again KeePassXC begins consuming substantial CPU, again for about 20 seconds. If I then attempt to interact with KeePassXC, then again it spins for about 20 seconds.

While in that state, it is not responsive to keyboard and mouse input. Once it stops eating CPU, it also becomes responsive to UI events.

This happens whether or not KeePassXC is configured to lock itself when the screen is locked.

I have (see below) suspicions that this may actually be a Qt issue. I haven't tried other Qt apps to see whether they exhibit the same misbehaviour.

Steps to Reproduce

(This assumes you are on my machine. I do not know whether things will go the same for others. There is nothing very strange in my configuration, so far as I know.)

  1. Launch KeePassXC.
  2. Hit Win-L on the keyboard to lock the screen. (At this point, KeePassXC immediately begins using 100% of one CPU core.)
  3. If you like, wait ~20s for this to subside.
  4. Hit any key on the keyboard to bring up the unlock screen. (At this point, KeePassXC again begins using 100% of one core.)
  5. If you like, wait ~20s for this to subside.
  6. Click on the KeePassXC window. Attempt to use the application.

Expected Behavior

Locking the screen should not result in excessive CPU usage. Unlocking the screen should not result in excessive CPU usage. KeePassXC should be responsive to UI events as soon as the screen is unlocked.

Actual Behavior

As described above: locking, starting to unlock, and interacting with the KeePassXC window all trigger excessive CPU usage, and KeePassXC is unresponsive while this happens.

Context

KeePassXC debug info:

KeePassXC - Version 2.6.6
Revision: 9c108b9

Qt 5.15.2
Debugging mode is disabled.

Operating system: Ubuntu 21.10
CPU architecture: x86_64
Kernel: linux 5.13.0-27-generic

Enabled extensions:

  • Auto-Type
  • Browser Integration
  • SSH Agent
  • KeeShare (signed and unsigned sharing)
  • YubiKey
  • Secret Service Integration

Cryptographic libraries:

  • libgcrypt 1.8.8

OS info:

Ubuntu 21.10 on AMD Ryzen; 64GB of RAM; Gnome 40.4.0 on Wayland.

Other notes:

I regret that this is not the latest version of KeePassXC; it's the version distributed by Ubuntu for the version of their OS that I'm running.

I had a look for other possibly-similar bugs already filed but didn't find anything, but I am not very confident that I would have found another instance of the same problem if it were there.

In the periods when KeePassXC is using a lot of CPU, what strace shows it doing is a lot of write syscalls, each on fd 5 (for me, on this occasion; I don't know how consistent it is), each apparently-successfully writing 8 bytes [1,0,0,0,0,0,0,0]. It's doing about 50 of these per second. The last syscall before this happens is futex(, FUTEX_WAKE_PRIVATE, 1) which returns 0 which means nothing was successfully woken up. The same syscall does also get invoked when KeePassXC is not in this state, but it looks to me as if in that case it always returns 1 (one waiter successfully woken).

After the long stream of write operations, the next thing that happens (I think pretty much concurrently with no longer eating a lot of CPU) is a call to poll on fd 5 (the same one as all those writes), followed by a read, an rt_sigprocmask, a clone, another rt_sigprocmask, and then a successful futex call with the same parameters as before. The write calls on fd 5 do continue to happen every now and then, but not 50 of them every second; there are also reads (of 16 bytes) on the same fd, and polls, neither of which seems to be happening while KeePassXC is eating CPU.

For the avoidance of doubt, I am not suggesting that those writes are causing the excessive CPU use; writing 8 bytes 50 times a second is trivial. But they may give some clues to what's going on.

Looking again at the strace output, in the middle of the long stream of writes there are sometimes a few other syscalls. I do not know whether there's any diagnostically useful information in them; if it seems like it might be valuable I can make some more careful observations and report the results.

I also tried attaching a gdb to the process while it was in CPU-eating mode and doing thread apply all backtrace. All but one of the threads were in either __futex_abstimed_wait_common64 or __GI___poll, except for the main keepassxc thread which on both occasions when I tried this had the following stack:

#0  0x00007f8be4b293ab in QPlatformScreen::screen() const () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#1  0x00007f8be4b703a6 in QScreen::virtualSiblings() const () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#2  0x00007f8be4b70498 in QScreen::virtualGeometry() const () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#3  0x00007f8be4b7064f in ?? () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#4  0x00007f8be4b4749a in QGuiApplicationPrivate::processScreenGeometryChange(QWindowSystemInterfacePrivate::ScreenGeometryEvent*) () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#5  0x00007f8be4b1b9bc in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib/x86_64-linux-gnu/libQt5Gui.so.5
#6  0x00007f8be0ae6b9e in ?? () from /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
--Type <RET> for more, q to quit, c to continue without paging--
#7  0x00007f8be32638bb in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#8  0x00007f8be32b6f08 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#9  0x00007f8be3261003 in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#10 0x00007f8be46f1548 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007f8be4696a9b in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#12 0x00007f8be469f024 in QCoreApplication::exec() () from /lib/x86_64-linux-gnu/libQt5Core.so.5
#13 0x000055a2006bb179 in ?? ()
#14 0x00007f8be3c80fd0 in __libc_start_call_main (main=main@entry=0x55a2006ba480, argc=argc@entry=1, argv=argv@entry=0x7fff5f663048) at ../sysdeps/nptl/libc_start_call_main.h:58
#15 0x00007f8be3c8107d in __libc_start_main_impl (main=0x55a2006ba480, argc=1, argv=0x7fff5f663048, init=<optimised out>, fini=<optimised out>, rtld_fini=<optimised out>, stack_end=0x7fff5f663038) at ../csu/libc-start.c:409
#16 0x000055a2006c526e in _start ()

Digging a little further, it seems that in this scenario QGuiApplicationPrivate::processScreenGeometryChange is being called many times per second. However, its caller QWindowSystemInterface::sendWindowSystemEvents is not. That function has a loop while (QWindowSystemInterfacePrivate::windowSystemEventsQueued()) so presumably in this scenario we have a deluge of these events for some reason.

@gjm11 gjm11 added the bug label Jun 13, 2022
@phoerious
Copy link
Member

phoerious commented Jun 13, 2022

If this isn't the lock/unlock process itself (in which case you misconfigured your encryption settings), then it's very likely a Qt or Wayland/Compositor issue. Your stacktrace also points to that. I don't think there is anything we can do here.

@gjm11
Copy link
Author

gjm11 commented Jun 13, 2022

It's definitely not the KeePassXC lock/unlock process; as I said, this happens whether or not KeePassXC is locking itself when the screen is locked. I agree that it is likely a Qt issue, but for all I know there might be e.g. some bit of per-app Qt configuration that would make the problem less severe. But if the opinion of the KeePassXC team is that there's nothing that can be done about it at the application level, I am certainly not going to dispute that.

@gjm11
Copy link
Author

gjm11 commented Jun 13, 2022

(The underlying issue might be in Wayland or the compositor, but I think Qt ought to be able to cope gracefully when it's spammed with large numbers of bogus geometry-changed messages. Especially if in practice it frequently is spammed with large numbers of bogus geometry-changed messages.)

@phoerious
Copy link
Member

I wouldn't know what could be causing this from our side. It's also something we've definitely never heard of before, so it's most likely a configuration issue. I'm closing this, but if you gain more information that indicates that this might indeed be a KeePassXC issue, please reopen.

@gjm11
Copy link
Author

gjm11 commented Jun 13, 2022

Will do. I am not aware of anything unusual in my configuration, for what it's worth, but e.g. maybe it only happens with one specific set of Qt libraries that happens to be in Ubuntu 21.10 and not many people are running 21.10 or something. If I find out anything else that seems like it would be useful to other KeePassXC users encountering this problem, I'll say so here.

(And, not that you need my approval or anything, no objection from me to the issue's being closed.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants