[Development] QT_FEATURE_reduce_relocations breaking executables that mention qApp?

Stephan Bergmann sberg.fun at gmail.com
Wed Dec 3 17:51:53 CET 2025


I wonder what the intended use and implementation of the (apparently 
enabled by default) QT_FEATURE_reduce_relocations is (in Qt 6.10 on 
Linux, at least):

In the comment at 
<https://github.com/CollaboraOnline/online/issues/13683#issuecomment-3600826333> 
"Crash on startup CODA-Q" I have a Linux executable that links against 
libQt6Core.so.6 and some other Qt6 shared libraries, and that in its 
source code mentions the qApp macro (and thus includes a copy of the 
inline function QCoreApplication::instance in the executable, and thus 
exports the symbol _ZN16QCoreApplication4selfE for the 
QCoreApplication::self static data member from the executable).

When I run that executable in the org.kde.Platform/x86_64/6.10 flatpak 
runtime (as distributed on Flathub), it immediately SIGSEGV's.  I 
tracked this down to libQt6Core.so.6 erroneously using its own local 
copy of _ZN16QCoreApplication4selfE, while all the other shared 
libraries and the executable use the copy of _ZN16QCoreApplication4selfE 
from the executable (as intended).  That way, 
QCoreApplicationPrivate::init (in libQt6Core.so.6) assigns to 
_ZN16QCoreApplication4selfE in libQt6Core.so.6, but the content of 
_ZN16QCoreApplication4selfE in the executable will stay null, and as 
soon as code from any of the other Qt6 shared libraries or the 
executable dereferences QCoreApplication::self, a null-pointer SIGSEGV 
ensues.

When I run that executable against qt6-qtbase-6.10.1-1.fc43.x86_64 on 
Fedora 43 (outside of a flatpak), it happens to work.  I tracked this 
difference in behavior down to the Fedora RPM being built with an 
explicit -DQT_FEATURE_reduce_relocations=OFF (which is present ever 
since 
<https://src.fedoraproject.org/rpms/qt6-qtbase/c/2ad9816328732397e68019041b91e857e2fc88b1> 
"Initial package", so the rationale for including it there may be lost 
to history; it got replaced with -DFEATURE_reduce_relocations=OFF in 
<https://src.fedoraproject.org/rpms/qt6-qtbase/c/075288afadb8993e46c1029489b506fbb6885383> 
"Use -DFEATURE instead -DQT_FEATURE for additional compatibility 
checks", for whatever reason), while the flatpak runtime apparently uses 
an implicit QT_FEATURE_reduce_relocations=ON:

In either case, the

>     QCoreApplication::self = q;

in QCoreApplicationPrivate::init (in qtbase's 
src/corelib/kernel/qcoreapplication.cpp) gets compiled to

>         movq    _ZN16QCoreApplication4selfE at GOTPCREL(%rip), %rax
>         movq    %rbx, (%rax)

to correctly access whichever instance of _ZN16QCoreApplication4selfE 
the resulting shared library will bind to at runtime.  However, with the 
implicit QT_FEATURE_reduce_relocations=ON in the flatpak runtime case, 
the linker command line that generates 
lib/x86_64-linux-gnu/libQt6Core.so.6.10.0 contains, among other options,

> -Wl,--dynamic-list=/run/build-runtime/qt6-qtbase/src/corelib/QtCore.dynlist

where the content of that QtCore.dynlist is

> {
>      extern "C" {
>          "qt_startup_hook";
>      };
>      extern "C++" {
>          "QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)";
>      };
> };

Which apparently causes the linker to bind the above use of 
_ZN16QCoreApplication4selfE to the internal instance, thus rewrite those 
instructions in the resulting lib/x86_64-linux-gnu/libQt6Core.so.6.10.0 as

>   1b2aff:       48 8d 05 9a 95 52 00    lea    0x52959a(%rip),%rax        # 6dc0a0 <_ZN16QCoreApplication4selfE@@Qt_6>
>   1b2b06:       48 89 18                mov    %rbx,(%rax)

(While with the explicit -DQT_FEATURE_reduce_relocations=OFF in the 
Fedora RPM case, the linker command line does not contain any 
--dynamic-list option, and the instructions in the resulting shared 
library are the original

>   1022ff:       48 8b 05 7a 1c 5c 00    mov    0x5c1c7a(%rip),%rax        # 6c3f80 <_ZN16QCoreApplication4selfE@@Qt_6-0xa0a0>
>   102306:       48 89 18                mov    %rbx,(%rax)

as intended.)

I wonder what the intended use of that QT_FEATURE_reduce_relocations is, 
given that it apparently leads to broken applications.  Is it "just" 
that the apparent behavior of ld's --dynamic-list option is not as 
anticipated by the Qt developers (and there should be something like a 
"global:*;" fallback section in qtbase's src/corelib/QtCore.dynlist.in)? 
  Or is the recipe for the org.kde.Platform flatpak runtime broken, and 
it should have been built with an explicit 
-DQT_FEATURE_reduce_relocations=OFF?  Or am I missing something else?


More information about the Development mailing list