solving 'KSycoca database corruption!'
Jos van den Oever
jos at vandenoever.info
Wed Apr 27 22:01:08 UTC 2016
Hi all,
A few days back dvratil reported errors in the KDE PIM unit tests. The tests
were writing
QWARN : TestBlogger1::testNetwork() kf5.kservice.sycoca: ERROR: KSycoca
database corruption!
On my laptop, I was seeing the same error when starting KF5 applications. I've
spent some time in the debugger today and I know what is going on in my
laptop.
The KSycoca (KDE System Configuration Cache) database is a file with cached
information. It is created in KBuildSycoca::save. The file currently contains
four types of information: KMimeType, KServiceType, KService and
KServiceGroup. The top of the KSycoca file lists
- the format version
- the offsets for the four different parts
- XDG_DATA_DIRS for which it was created
- timestamp
- locale
- some hash
- paths to the cached directories with their mtimes
The problems is this: the code for reading and writing of strings is not
symmetrical. Strings of any length can be written, but only strings of less
than 8192 bytes may be read. This limit is set in KSycocaUtilsPrivate::read.
The limit is probably there to avoid out-of-memory situations.
On my laptop I have a lot of XDG data dirs. The length of the environment
variable is currently 4092 bytes. KSycocaBuild saves that as UTF-16 which
needs 8184 bytes. KBuildSycoca save that without complaint but complains when
reading it.
Why would i need such a long XDG_DATA_DIRS? That is because on NixOS each
package has its own directory. This leads to this:
XDG_DATA_DIRS=
/nix/store/0qm2gkssnfslm6nwhd3klwm54yhqx5rx-dbus-1.8.20/share
:/nix/store/r6j1sqknviayvqicy8zw049am0q6wywj-kcoreaddons-5.21.0/share
:/nix/store/qiq2vxxxsj0clv209xsv7w7yv2wrsbqb-breeze-icons-5.21.0/share
:/nix/store/l4ggdlcnj3sfky4zjlirf0hmqphzzc3y-kjobwidgets-5.21.0/share
.....
In such a setup a working KSycoca really helps.
The simplest solution here is to simply increase the magic number 8192 to e.g.
65528. This is just a temporary buffer.
Or we just check the size of the whole cache file (e.g. < 100M) and remove all
other limits. That would simplify
KSycocaUtilsPrivate::read(*str, header.prefixes);
to
*str >> header.prefixes;
Increasing the buffer size [1] fixes all but one of the failing unit test of
KService on NixOS.
Cheers,
Jos
[1] https://git.reviewboard.kde.org/r/127770/
More information about the Kde-frameworks-devel
mailing list