Press "Enter" to skip to content

Making Qt Declarative work on 32-bit Arm devices with musl

Note: Spots is on her techie soapbox again! This seems to happen a lot…

I’m trying to work through the backlog of issues for Adélie Linux’s beta7 release. One of them was that KDE’s chart library was crashing on 32-bit Arm devices (think the Raspberry Pi 2/3 or some of the older Tinker Boards). This should have been solved by the update to Mesa that I did, but sadly, that just led to a new crash.

I did some debugging and the crash was actually occurring in LLVM’s MCJIT:

Thread 14 "QSGRenderThread" received signal SIGSEGV, Segmentation fault.
[Switching to LWP 26632]
0xf7fb28f4 in memset () from /lib/ld-musl-armhf.so.1
(gdb) bt
#0  0xf7fb28f4 in memset () from /lib/ld-musl-armhf.so.1
#1  0xeb3f7628 in llvm::TargetLoweringBase::initActions() () from /usr/lib/libLLVM.so.18.1
#2  0xeb3f7d6a in llvm::TargetLoweringBase::TargetLoweringBase(llvm::TargetMachine const&) () from /usr/lib/libLLVM.so.18.1
#3  0xeb698694 in llvm::TargetLowering::TargetLowering(llvm::TargetMachine const&) () from /usr/lib/libLLVM.so.18.1
#4  0xed2726fc in ?? () from /usr/lib/libLLVM.so.18.1
#5  0xed2e333e in ?? () from /usr/lib/libLLVM.so.18.1
#6  0xed1bd47e in ?? () from /usr/lib/libLLVM.so.18.1
#7  0xed1bdafc in ?? () from /usr/lib/libLLVM.so.18.1
#8  0xeb6e4ee0 in llvm::AsmPrinter::doInitialization(llvm::Module&) () from /usr/lib/libLLVM.so.18.1
#9  0xeafa487c in llvm::FPPassManager::doInitialization(llvm::Module&) () from /usr/lib/libLLVM.so.18.1
#10 0xeafac8fa in llvm::legacy::PassManagerImpl::run(llvm::Module&) () from /usr/lib/libLLVM.so.18.1
#11 0xec97558e in llvm::MCJIT::emitObject(llvm::Module*) () from /usr/lib/libLLVM.so.18.1
#12 0xec975a18 in llvm::MCJIT::generateCodeForModule(llvm::Module*) () from /usr/lib/libLLVM.so.18.1
#13 0xec973480 in llvm::MCJIT::finalizeObject() () from /usr/lib/libLLVM.so.18.1
#14 0xec8e5732 in LLVMGetPointerToGlobal () from /usr/lib/libLLVM.so.18.1
#15 0xf0d92748 in gallivm_jit_function (gallivm=0xea188d00, func=0xea1885a4, func_name=<optimized out>)
    at ../src/gallium/auxiliary/gallivm/lp_bld_init.c:502
#16 0xf0e62774 in generate_variant (key=0xe8744488, shader=0x9b05688c, lp=0xe8b297f0)
    at ../src/gallium/drivers/llvmpipe/lp_state_fs.c:4048
#17 llvmpipe_update_fs (lp=lp@entry=0xea1c2130) at ../src/gallium/drivers/llvmpipe/lp_state_fs.c:4842

This is the bit of LLVM that takes a portable description of code and turns it into real code that can be executed on the running system. Quite a cool system, but also a nightmare to debug. I’ve found issues in there in the PowerPC targeting code a few years back. I really, really wasn’t looking forward to digging myself into the Arm targeting code.

But I was thankfully saved from all of that. The actual problem was that Qt’s Scene Graph thread was using too much stack space and running out of memory. The musl libc only gives it 256 KB (yes, as in kilobytes) of memory of stack space by default – you’re meant to request more if you need it, since every OS has a different default setting. And since glibc – the more popular libc for Linux – defaults to 1 MB (and Windows even more), nobody noticed that Qt should be requesting more for its Scene Graph thread. Providing it more memory gave me a pass!

********* Start testing of Charts *********
Config: Using QtTest library 5.15.17, Qt 5.15.17 (arm-little_endian-ilp32-eabi-hardfloat shared (dynamic) release build; by GCC 13.3.0), adelie 1.0-beta6
Totals: 14 passed, 0 failed, 0 skipped, 0 blacklisted, 813ms
********* Finished testing of Charts *********

And with that out of the way, I believe I have finally unblocked all the Arm stuff! And that means I get to work on… *paws at the list of open tickets*… Rust… oh no…

Leave a Reply

Your email address will not be published. Required fields are marked *