Gentoo musl Support Expansion for Qt/KDE Week 7

This week has mostly been spent on testing applications and some further fixes to QtWebEngine.

QtWebEngine is now PR:ed to ::gentoo and I’m waiting for comments. It seems to work just fine and all tests for Qutebrowser pass! (https://github.com/gentoo/gentoo/pull/26611). Another thing that has taken a lot of time this week is getting the TerminalInterfaceTest to run on Konsole. I also ran into an issue compiling Emacs, I found out it was because of libexecinfo and I decided to reimplement glibc’s execinfo using libunwind because it’s such a simple interface. It also avoids me using the error prone __builtin_* stuff.

My weekly schedule says that all core apps like Ark, Dolphin and Konsole should pass tests, and except for Konsole and a RAR issue with Ark they do! The RAR issue is because app-arch/rar downloads a binary that depends on glibc.

Starting with Konsole, the FAIL comes when using zsh. This does not happen when running FEATURES=test emerge … . But when I started testing stuff this week I did not know of FEATURES=test at first and instead I manually executed ebuild … clean test and that’s how I even noticed this.

The issue here is that it fails when running:
currentDirectory = QStringLiteral("/tmp");
terminal->sendInput(QStringLiteral("cd ") + currentDirectory + QLatin1Char('\n'));
stateSpy.wait(2000);
QCOMPARE(stateSpy.count(), 1);

It’s pretty straightforward, just sends “cd /tmp” into the terminal and checks if state has changed.

From a lot of testing and messing around I found out that the test acts a lot like there’s some junk input at the beginning, for example

terminal->sendInput(QStringLiteral(";cd ") + currentDirectory + QLatin1Char('\n'));
and
terminal->sendInput(QStringLiteral("\b\b\b\b\b\b\b\b\b\b\b\bcd ") + currentDirectory + QLatin1Char('\n'));

work just fine, wat (?). \b is the escape sequence for backspace, so that would remove junk from the start.
I have opened a bug report for it here https://bugs.gentoo.org/862594.

The second thing I mentioned at the start was libexecinfo implemented with libunwind. I noticed an issue when compiling Emacs, being that temacs segfaulted at build-time. temacs is an Emacs bootstrapper, and when opening it up in GDB I saw that it segfaulted at the __builtin_frame_address stuff in libexecinfo!

I searched for similar issues online and found a bunch of issues regarding this. It has to do with __builtin_frame_address and backtracing further than the program’s main() function. (this thread has more info https://www.openwall.com/lists/musl/2019/08/22/2). There also seemed to regularly be a bunch of replies recommending libunwind instead for self debugging and I then got the idea to just implement execinfo using libunwind, making it more robust than the current “junk” -from the author himself.

My code just replaces the backtrace() function with the equivalent in libunwind. This has two pros. The first being that it does not segfault like before. It also doesn’t require a Python script to generate the source file :). The __builtin_* functions require constant integers to get passed, so the previous libexecinfo just generated a massive switch with case n: __builtin_*(n+1) using a Python script. https://github.com/resslinux/libexecinfo/blob/master/gen.py.

The only issue I have with my implementation is that it doesn’t use the libunwind way of finding symbols from function addresses. The execinfo way of getting symbols is to first get a void*-array of functionpointers with backtrace(), and then use char** backtrace_symbols(void**, …) to resolve names, but libunwind needs to have a cursor to get the symbol. Basically you should resolve names when looping through the backtrace with unw_step(cursorptr) like I do here for the addresses https://github.com/alfredfo/libexecinfo-unw/blob/master/execinfo.c#L43, and not by itself using a void*-array. Currently I just use the function from the old libexecinfo with added Alpine patches to fix it up a bit. I first wanted to also get symbols from the static symbol table as well to resolve even more names, but apparently glibc only uses the dynamic (nm -D) so I guess that would only be incorrect.

My implementation also uses Meson to generate a pkg-config file, something that was missing from the old one. Without it, it can cause a headache when looking up libexecinfo symbols in build systems. Some packages just assume that execinfo symbols will be provided my libc (because it is in glibc) and we have ran into a lot of these issues during the project. With a pkg-config file we can check for libexecinfo easily with almost any build system!

Next week I’ll work on other KDE applications, bye!

This entry was posted in musl KDE, RISC-V Prefix, Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published.