Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.5.0 Beta1
-
None
-
Linux 5.15.0-52-generic #58~20.04.1-Ubuntu SMP x86_64 GNU/Linux
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
-
-
f088c9707 (108-based), 89d31abd8 (dev)
Description
I was testing the 108 adaptation on Ubuntu 20.04 and ran into this issue.
Most of the examples that use QWebEngineView::load() fails to load any url.
Chromium throws this error:
[ERROR:libc_interceptor.cc(97)] Cannot find getaddrinfo with dlsym.
I have seen this error in some CI logs:
https://testresults.qt.io/coin/api/log/qt/qtwebengine/97d7dea91ff44fca739c26ff617e53c1b2ecfea6/LinuxUbuntu_20_04x86_64LinuxQEMUarm64GCCqtci-linux-Ubuntu-20.04-x86_64-50-a897c8Sccache_UseConfigure/17743184ca921ba3b5fbaab6981076f768660979/test_1681369999/log.txt.gz
I have investigated the issue and there's what I found:
Chromium overrides libc's "getaddrinfo", but in some cases it wants to fall back to the original libc version.
It is done by dlsym's RTLD_NEXT handler, which finds the first occurrence of the desired symbol in the search order after the current object.
#define REAL(func) reinterpret_cast<decltype(&func)>(dlsym(RTLD_NEXT, #func))
see the descrition of 'RTLD_NEXT' in
https://man7.org/linux/man-pages/man3/dlsym.3.html
I will use the minimal-widgets example to explain.
Looking at the order of DSOs that are linked to the binary:
$ ldd minimal-widgets | head -n9 linux-vdso.so.1 libQt6WebEngineWidgets.so.6 libQt6Widgets.so.6 libQt6Core.so.6 libstdc++.so.6 libgcc_s.so.1 libc.so.6 <-------- // libc is here libQt6QuickWidgets.so.6 libQt6WebEngineCore.so.6 <-------- // dlysm is called here
libc is present before libQt6WebEngineCore, so dlsym won't look into it and chromium will throw the error and stops loading.
The runtime loader will load DSOs in breadth-first order.
Direct dependencies first, then dependencies of those dependencies.
Direct dependencies are marked as NEEDED in the elf file's dynamic section:
$ readelf -d minimal-widgets | grep NEEDED 0x0000000000000001 (NEEDED) Shared library [libQt6WebEngineWidgets.so.6] 0x0000000000000001 (NEEDED) Shared library: [libQt6Widgets.so.6] 0x0000000000000001 (NEEDED) Shared library: [libQt6Core.so.6] 0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6] 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
QWebEngineCore is a dependency of QWebEngineWidgets but it is not linked directly to the executable.
Normally the linker will add a NEEDED tag for each DSO mentioned on the command line for linking.
The "--as-needed" option causes a NEEDED tag to only be emitted for a library if it has a non-weak undefined symbol reference in the executablue.
see more in https://linux.die.net/man/1/ld
The "--as-needed" linker option is enabled by default on Ubuntu (might be on other systems) and it causes the problem.
https://wiki.ubuntu.com/NattyNarwhal/ToolchainTransition
To reproduce add the "--as-needed" linker option.
Workarounds:
1, Preload libQt6WebEngineCore.so.6 before execution.
2, Make direct reference to QWebEngineCore in the executable.
3, Create a fallback if dlsym fails.
4, Use the "--no-as-needed" option that restores the default behaviour:
$ readelf -d minimal-widgets | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libQt6WebEngineWidgets.so.6] 0x0000000000000001 (NEEDED) Shared library: [libQt6WebEngineCore.so.6] ... 0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1] 0x0000000000000001 (NEEDED) Shared library: [libpthread.so.0] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ ldd minimal-widgets linux-vdso.so.1 libQt6WebEngineWidgets.so.6 libQt6WebEngineCore.so.6 <-------- ... libgcc_s.so.1 libpthread.so.0 libc.so.6 <--------