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@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?
--
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to