GNOME Bugzilla – Bug 736189
Very slow startup when locale not set
Last modified: 2018-06-29 23:33:28 UTC
Reporting against GnuCash 2.6.3 rev 4e4a032+ built from source on Debian stable: This may be *the* reason why some users complain about GnuCash startup being slow. I have not found a workaround described elsewhere, so I'm filing this here: When LC_ALL and LANG environment variables are not set, GnuCash 2.6.3 startup takes over a minute. A captured strace contains 29635 registered calls to open("/usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so", O_RDONLY) with return code 15 or 16. This slowness happens before the data file is opened, while the splash screen displays initialization of individual components. There is an easy workaround: with LANG=en_US.UTF-8 or LC_ALL=C set, the startup time is reduced to 20 seconds (or to 10 seconds without strace). Note that this bug does not manifest itself with GnuCash 2.4.10 from Debian stable (wheezy). So the experience for an unaware upgrading user is that GnuCash has become unbearably slower in the newest version (which is not true).
If it's common for Debian to start a shell or a program without the localization variables set I'd think that a Debian bug rather than something that GnuCash should work around. Out of interest, though, and being too lazy^H^H^H^Hbusy to investigate myself, what's trying to open ISO8859-1.so?
I just noticed that I'm wrong - in the failing case only LC_ALL is not set, but LANG is set (incorrectly for GnuCash, it seems). That probably also explains the strace: ~> locale LANG=en_US.ISO-8859-15 LANGUAGE=en_US:en LC_CTYPE="en_US.ISO-8859-15" LC_NUMERIC="en_US.ISO-8859-15" LC_TIME="en_US.ISO-8859-15" LC_COLLATE="en_US.ISO-8859-15" LC_MONETARY="en_US.ISO-8859-15" LC_MESSAGES="en_US.ISO-8859-15" LC_PAPER="en_US.ISO-8859-15" LC_NAME="en_US.ISO-8859-15" LC_ADDRESS="en_US.ISO-8859-15" LC_TELEPHONE="en_US.ISO-8859-15" LC_MEASUREMENT="en_US.ISO-8859-15" LC_IDENTIFICATION="en_US.ISO-8859-15" LC_ALL= I'm going to investigate this further (I also have exactly the same locale settings on two other Debian systems). But I consider it somewhat related to GnuCash still, as it is the first and only application which seems to misbehave.
OK. So what you changed is encoding. You changed from ISO-8859-15 to UTF-8 and none. That makes sense in light of the zillion calls to iso8859.so you reported, as neither UTF-8 nor the C locale would use either. So what's the stack trace for those calls?
(In reply to comment #3) > OK. So what you changed is encoding. You changed from ISO-8859-15 to UTF-8 and > none. That makes sense in light of the zillion calls to iso8859.so you > reported, as neither UTF-8 nor the C locale would use either. > > So what's the stack trace for those calls? Good question... I tried to determine the stack trace by conditionally trapping syscall open("/usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so") as follows: (gdb) catch syscall open Catchpoint 1 (syscall 'open' [2]) (gdb) cond 1 ((char*)$rdi)[38] == '9' && ((char*)$rdi)[39] == '-' && ((char*)$rdi)[40] == '1' (gdb) run But it doesn't seem to hit the breakpoint 30000 times as expected (it only hit it twice) and the execution is slowed down extremely by this catchpoint. For what it's worth, here's the backtrace I managed to capture by the above method:
+ Trace 234066
Here's another trace captured near the end of the startup process. It seems to be representative of the numerous syscalls, as there are now hundreds of hits of the breakpoint. However, given that the breakpoint only started getting hit after the "Loading user data..." stage and when reports started being generated, I'm not convinced that it points to the root cause of the poor startup performance (which as explained earlier is already seen before the data file is opened). So it's more like a diagnostic clue and there's some hidden common cause for it and the poor startup performance:
+ Trace 234067
Maybe open is getting called with a relative path sometimes, try cond 1 strstr($rdi, ISO8859-1.so) != NULL instead. It looks like the fundamental problem is that libgconv is being really stupid and not keeping the encoding library for the locale open so that every call to transcode requires reloading it. That's really expensive. We could just force a UTF-8 locale at startup and so avoid the transcoding. I don't think we send many translated strings to the console anyway, and all of the GUI is UTF8.
(In reply to comment #6) > Maybe open is getting called with a relative path sometimes, try > cond 1 strstr($rdi, ISO8859-1.so) != NULL > instead. Thanks for the tip, but it just displays 'No symbol "strstr" in current context'. > It looks like the fundamental problem is that libgconv is being really stupid > and not keeping the encoding library for the locale open so that every call to > transcode requires reloading it. That's really expensive. > > We could just force a UTF-8 locale at startup and so avoid the transcoding. I > don't think we send many translated strings to the console anyway, and all of > the GUI is UTF8. If you can think of a little patch, I'd be happy to try it out. I think it would be good for unsuspecting users to spare them figuring it out (but only if the patch is side-effect free for others).
(In reply to comment #6) > Maybe open is getting called with a relative path sometimes, try > cond 1 strstr($rdi, ISO8859-1.so) != NULL > instead. > > It looks like the fundamental problem is that libgconv is being really stupid > and not keeping the encoding library for the locale open so that every call to > transcode requires reloading it. That's really expensive. > Perhaps this would also explain the extreme startup slowness several Windows users reported. As far as I know it's fairly common to use non-UTF8 locales. > We could just force a UTF-8 locale at startup and so avoid the transcoding. I > don't think we send many translated strings to the console anyway, and all of > the GUI is UTF8. Would that have any (positive) influence on Windows ?
Dunno. It might blow up on Windows if there aren't *.UTF-8 locales available.
Created attachment 285679 [details] [review] Force a UTF-8 locale Here's a patch to try out. I don't know if this will work on Windows, and I'm pretty sure it won't if the user hasn't installed the corresponding utf-8 locale on Debian.
(In reply to comment #10) > Created an attachment (id=285679) [details] [review] > Force a UTF-8 locale > > Here's a patch to try out. I don't know if this will work on Windows, and I'm > pretty sure it won't if the user hasn't installed the corresponding utf-8 > locale on Debian. I tried the patch - unfortunately, it is not effective. I see that the new code branch is executed (and setlocale called with new_locale = en_US.UTF-8 instead of the initial en_US.ISO-8859-15), however there's no improvement in startup speed, and there's still the same huge number of open syscalls logged by strace. export LC_ALL=en_US.UTF-8 or export LANG=en_US.UTF-8 from the shell still works.
OK. So much for that idea.
Comment on attachment 285679 [details] [review] Force a UTF-8 locale Didn't work per feedback from the OP
GnuCash bug tracking has moved to a new Bugzilla host. The new URL for this bug is https://bugs.gnucash.org/show_bug.cgi?id=736189. Please continue processing the bug there and please update any external references or bookmarks.