Deploying Linux app - undefined symbol
-
Hi!
I'm migrating a qt-based windows app to Linux (more precisely, Linux 20.3 Cinnamon). The Qt version I'm using is 5.15.2. It is the distribution obtained when using the universal installer (shared libraries). The compiler is gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
The migration of the code is finished. Surprisingly, I had to do a few changes, but these were minor ones. The app works flawlessly when launched from QtCreator 6.0.2.
Then, I started to prepare the deployment of the app. This is my first time doing somethink like this, so after searching a bit, I found this article
Doing what this article says, I found where the required Qt libraries were using the ldd command (see ldd.txt at the end of this post). I copied the qt shared libraries exactly from the path reported by the ldd command. Then, and again according to the said article above, I copied the plugins directory to my package's one. Note that I copied the plugins from the corresponding directory in my Qt installation path. In short, everything (libraries, plugins) were copied from there.
Then, I prepared the .sh file to run the app as explained in the article. This is file dump_csv_header.sh, which you may find at the end of this post. The problem was then that the loader didn't find the plugin directory.
Googling a bit I found a post stating that setting QT_PLUGIN_PATH would solve the problem and indeed it did it. And yes, no more complains about missing plugins appeared. But then, the problem I'm experiencing now showed up:
loaded library "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqxcb.so" /home/pep/Desarrollo/ADAtools/installer/deployment/bin/./dump_csv_header: symbol lookup error: /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5: undefined symbol: _ZN22QWindowSystemInterface24setPlatformFiltersEve ntsEb, version Qt_5_PRIVATE_API
I understand that, in spite of copying the shared libraries (and plugins) from the paths stated by the ldd command, these are not the ones I should be using; otherwise, no undefined symbol should appear.
Googling again I found a post where the user was requested to activate the variable QT_DEBUG_PLUGINS to produce a better trace of what was happening. Setting it to 1, I ran the app and the log it produced is stored in run_dump.txt (see below).
What's wrong, can you help me?
Thanks!
File ldd.txt - The result of running ldd on my application.
linux-vdso.so.1 (0x00007ffc5b1e8000) libQt5Widgets.so.5 => /home/pep/Qt/5.15.2/gcc_64/lib/libQt5Widgets.so.5 (0x00007f24f1f64000) libQt5Gui.so.5 => /home/pep/Qt/5.15.2/gcc_64/lib/libQt5Gui.so.5 (0x00007f24f1633000) libQt5Core.so.5 => /home/pep/Qt/5.15.2/gcc_64/lib/libQt5Core.so.5 (0x00007f24f0e3d000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f24f0e00000) libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f24f0c1e000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f24f0acf000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f24f0ab2000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f24f08c0000) libGL.so.1 => /lib/x86_64-linux-gnu/libGL.so.1 (0x00007f24f0838000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f24f081c000) libicui18n.so.56 => /home/pep/Qt/5.15.2/gcc_64/lib/libicui18n.so.56 (0x00007f24f0383000) libicuuc.so.56 => /home/pep/Qt/5.15.2/gcc_64/lib/libicuuc.so.56 (0x00007f24effcb000) libicudata.so.56 => /home/pep/Qt/5.15.2/gcc_64/lib/libicudata.so.56 (0x00007f24ee5e6000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f24ee5e0000) libgthread-2.0.so.0 => /lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f24ee5db000) libglib-2.0.so.0 => /lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f24ee4b2000) /lib64/ld-linux-x86-64.so.2 (0x00007f24f27e5000) libGLdispatch.so.0 => /lib/x86_64-linux-gnu/libGLdispatch.so.0 (0x00007f24ee3fa000) libGLX.so.0 => /lib/x86_64-linux-gnu/libGLX.so.0 (0x00007f24ee3c4000) libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f24ee351000) libX11.so.6 => /lib/x86_64-linux-gnu/libX11.so.6 (0x00007f24ee214000) libxcb.so.1 => /lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f24ee1ea000) libXau.so.6 => /lib/x86_64-linux-gnu/libXau.so.6 (0x00007f24ee1e4000) libXdmcp.so.6 => /lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f24ee1da000) libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f24ee1c0000)
File dump_csv_header.sh - The script recommended by the article, slightly modified to set the QT_PLUGIN_PATH and QT_DEBUG_PLUGINS environment variables.
#!/bin/sh appname=`basename $0 | sed s,\.sh$,,` dirname=`dirname $0` tmp="${dirname#?}" if [ "${dirname%$tmp}" != "/" ]; then dirname=$PWD/$dirname fi LD_LIBRARY_PATH=$dirname export LD_LIBRARY_PATH QT_PLUGIN_PATH=/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins export QT_PLUGIN_PATH QT_DEBUG_PLUGINS=1 export QT_DEBUG_PLUGINS $dirname/$appname "$@"
File run_dump.txt - The trace obtained when executing my app using the script above. The undefined symbol error shows up at the end.
QFactoryLoader::QFactoryLoader() checking directory path "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms" ... QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqeglfs.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqeglfs.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "eglfs" ] }, "archreq": 0, "className": "QEglFSIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("eglfs") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqeglfs.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqlinuxfb.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqlinuxfb.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "linuxfb" ] }, "archreq": 0, "className": "QLinuxFbIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("linuxfb") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqlinuxfb.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimal.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimal.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "minimal" ] }, "archreq": 0, "className": "QMinimalIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("minimal") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimal.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimalegl.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimalegl.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "minimalegl" ] }, "archreq": 0, "className": "QMinimalEglIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("minimalegl") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqminimalegl.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqoffscreen.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqoffscreen.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "offscreen" ] }, "archreq": 0, "className": "QOffscreenIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("offscreen") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqoffscreen.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqvnc.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqvnc.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "vnc" ] }, "archreq": 0, "className": "QVncIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("vnc") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqvnc.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-egl.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-egl.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "wayland-egl" ] }, "archreq": 0, "className": "QWaylandEglPlatformIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("wayland-egl") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-egl.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-generic.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-generic.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "wayland" ] }, "archreq": 0, "className": "QWaylandIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("wayland") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-generic.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-egl.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-egl.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "wayland-xcomposite-egl" ] }, "archreq": 0, "className": "QWaylandXCompositeEglPlatformIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("wayland-xcomposite-egl") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-egl.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-glx.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-glx.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "wayland-xcomposite-glx" ] }, "archreq": 0, "className": "QWaylandXCompositeGlxPlatformIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("wayland-xcomposite-glx") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwayland-xcomposite-glx.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwebgl.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwebgl.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "webgl" ] }, "archreq": 0, "className": "QWebGLIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("webgl") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqwebgl.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqxcb.so" Found metadata in lib /home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqxcb.so, metadata= { "IID": "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.3", "MetaData": { "Keys": [ "xcb" ] }, "archreq": 0, "className": "QXcbIntegrationPlugin", "debug": false, "version": 331520 } Got keys from plugin meta data ("xcb") QFactoryLoader::QFactoryLoader() looking at "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqxcb.so.debug" "The shared library was not found." not a plugin QFactoryLoader::QFactoryLoader() checking directory path "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/platforms" ... loaded library "/home/pep/Desarrollo/ADAtools/installer/deployment/bin/plugins/platforms/libqxcb.so" /home/pep/Desarrollo/ADAtools/installer/deployment/bin/./dump_csv_header: symbol lookup error: /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5: undefined symbol: _ZN22QWindowSystemInterface24setPlatformFiltersEventsEb, version Qt_5_PRIVATE_API
-
@bleriot13 said in Deploying Linux app - undefined symbol:
symbol lookup error: /lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
Looks like it's trying to use the system version of this library instead of the one from the Qt version you installed in /home/pep/Qt/5.15.2/gcc_64. Does this library exist in your local Qt installation's lib folder?
-
Thanks, @mchinand, for your answer.
I have solved the problem for all my apps (in fact, it is a suite of applications, not just one) but one of them.
Googling quite a lot I found this post. There, someone else had the very same problem I had, so I followed the given advise.
I seems that the qt libraries that are packaged with the operating system have been compiled using the option "-std=c++11", while my libraries and applications weren't. Adding the following line to my .pro files:
unix:!macx: QMAKE_CXXFLAGS += "-std=c++11"
and recompiling everyting from scratch did the trick. Well, this an also that I downloaded the precise version of Qt to match that of the libraries present in the target operating system (5.12.8 instead of 5.15.2), so when I recompiled my code, it relied on 5.12.8, the same version supported by the OS.
I created a .deb package with my executable files and installed it in a virtual machine where the Qt development kit wasn't present. This virtual machine ran the same kind of Linux (Mint + Cinnamon) with all updates installed, exactly like my regular computer.
Well, as I said above, all my apps worked very well but one of them, which thrown a diferent exception - a different missing symbol this time. Since both machines (virtual, real) had the very same set of updates but one of them didn't have the Qt development kit installed, I guess that the failing app relies on some kind of library that is provided by Qt in one environment and by the operating system in the other, being these different and thus provoking the missing symbol issue I'm talking about.
Now I can't recall the precise missing symbol. I'll write an extra (short post) when I reproduce the problem to state clearly which one is it.
-
Hi again.
Well, this is not a post as short as I expected, but I think it's worth reading it because the reason for the problem has been identified. Unfortunately I don't have a solution; that's the reason why I explain the whole thing here...
I had to shutdown my (real) Linux box, boot Windows, and then run VirtualBox to boot the "clean" Linux Mint where I'm testing my apps and see the precise exception thrown by the offending one.
It is exactly this one:
./ADAFinder: symbol lookup error: ./ADAFinder: undefined symbol: __cxa_throw_bad_array_new_length, version Qt_5
There seems to be a pretty long discussion about this problem here. The author also sent a question to this forum here.
In short, it looks like symbol __cxa_throw_bad_array_new_length IS included both in libQt5Gui.so.5 (the one installed with the Qt development environment) as well as in libstdc++.so.6. I guess, therefore, that when I link my app, the version of this symbol stored in libQt5Gui.so.5 is used.
When I move to a computer without a Qt development environment, (Linux Mint 20.3 + Cinnamon) the pre-installed version of libQt5Gui.so.5 does not include __cxa_throw_bad_array_new_length; I checked that using the nm command:
nm --with-symbol-versions -D libQt5Gui.so.5 | grep __cxa_throw_bad_array_new_length
and the answer was just nothing, so no symbol like this exists there. If I execute this very same command for the version of the Qt library provided by the operating system in my real computer, the result is exactly the same (the symbol is not present). On the contrary, if I run the command passing the library provided by the Qt development environment, the symbol IS there.
I guess then that my app expects to find __cxa_throw_bad_array_new_length in libQt5Gui.so.5. If I run the app in a box where no Qt development environment, and since the said symbol is not there, the operating system complains about it.
Said that, WHAT CAN I DO? Any helpful ideas?
Thanks.
-
Well, I finally solved the problem.
I proceeded like in the first post of this thread, that is, copying the executable files, shell files and Qt libraries and plugins to some folder.
The main difference with that post is that now all my libraries and applications are compiled using the -std=c++11 option.
-
Oh!
I forgot to mention that the qt libraries and plugins copied were those form Qt's development kit, not the ones provided by the operating system.
In this way, the libraries used when developing / exploiting the software are the same and everything is coherent.