Undefined reference to SSL_CONF_CTX_new on android x86
-
Hello,
I've built Qt for android armeabi-v7a with SSL support, however on x86 it looks like it's not working. If I try to execute my application under x86 emulator I get the following error:
E/art ( 2294): dlopen("/data/data/fr.fetacorp.SaveTheBall/lib/libQt5Network.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "SSL_CONF_CTX_new" referenced by "libQt5Network.so"... E/AndroidRuntime( 2294): FATAL EXCEPTION: qtMainLoopThread E/AndroidRuntime( 2294): Process: fr.fetacorp.SaveTheBall, PID: 2294 E/AndroidRuntime( 2294): java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "SSL_CONF_CTX_new" referenced by "libQt5Network.so"... E/AndroidRuntime( 2294): at java.lang.Runtime.load(Runtime.java:331) E/AndroidRuntime( 2294): at java.lang.System.load(System.java:982) E/AndroidRuntime( 2294): at org.qtproject.qt5.android.QtNative$2.run(QtNative.java:179) E/AndroidRuntime( 2294): at org.qtproject.qt5.android.QtThread$2.run(QtThread.java:87) E/AndroidRuntime( 2294): at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61) E/AndroidRuntime( 2294): at java.lang.Thread.run(Thread.java:818)
I've included libssl.so and libcrypto.so as told in the Qt documentation, for armeabi-v7a it just works.
The symbols are defined correctly though:
markand@x1 ~/android/env/android-21/x86/lib $ nm libssl.so | grep SSL_CONF_CTX_new 000542e0 T SSL_CONF_CTX_new
I've built Qt using
-openssl-linked
option, here the whole configure invocation:./configure \ -opensource \ -release \ -confirm-license \ -xplatform android-g++ --disable-rpath \ -nomake tests \ -nomake examples \ -no-sql-db2 \ -no-sql-ibase \ -no-sql-mysql \ -no-sql-oci \ -no-sql-odbc \ -no-sql-psql \ -no-sql-sqlite2 \ -no-sql-tds \ -android-arch x86 \ -android-ndk-platform android-21 \ -android-ndk /home/markand/android/ndk \ -android-sdk /home/markand/android \ -android-ndk-host linux-x86_64 \ -android-toolchain-version 4.9 \ -ssl -openssl-linked OPENSSL_LIBS="-lssl -lcrypto" \ -I ~/android/env/android-21/x86/include \ -L ~/android/env/android-21/x86/lib \ -skip qtcharts \ -skip qtdatavis3d \ -skip qtdoc \ -skip qtmacextras \ -skip qtscxml \ -skip qtserialbus \ -skip qtserialport \ -skip qtspeech \ -skip qttranslations \ -skip qtvirtualkeyboard \ -skip qtwayland \ -skip qtwebchannel \ -skip qtwebengine \ -skip qtwebglplugin \ -skip qtwebsockets \ -skip qtwebview \ -skip qtwinextras \ -skip qtx11extras \ -skip qtxmlpatterns \ -no-warnings-are-errors \ -prefix ~/android/env/android-21/x86/
Do you have any idea why it does not work only in x86?
-
@David-Demelier said in Undefined reference to SSL_CONF_CTX_new on android x86:
under x86 emulator
So you need to make sure that the OpenSSL shared objects (i.e. libssl.so and libcrypto.so) with the proper symbols you're showing are indeed used/available in the emulator environment
-
@Pablo-J.-Rogina said in Undefined reference to SSL_CONF_CTX_new on android x86:
So you need to make sure that the OpenSSL shared objects (i.e. libssl.so and libcrypto.so) with the proper symbols you're showing are indeed used/available in the emulator environment
Yes, they are copied with QMake:
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android contains(ANDROID_TARGET_ARCH,armeabi-v7a) { ANDROID_EXTRA_LIBS = \ /home/markand/Dev/save-the-ball/../../android/env/android-21/armeabi-v7a/lib/libcrypto.so \ $$PWD/../../android/env/android-21/armeabi-v7a/lib/libssl.so } contains(ANDROID_TARGET_ARCH,x86) { ANDROID_EXTRA_LIBS = \ /home/markand/Dev/save-the-ball/../../android/env/android-21/x86/lib/libcrypto.so \ $$PWD/../../android/env/android-21/x86/lib/libssl.so }
And present in the android-build directory:
$ ls android-build/libs/x86/lib{crypto,ssl}* android-build/libs/x86/libcrypto.so android-build/libs/x86/libssl.so
-
Hi,
Might be a silly question but are you sure you are using your own build of Qt for Android ?
The error message states that it dries to dlopen the .dll which is the default behaviour and not what I'd expect when using a build with the
--openssl-linked
option. -
@SGaist said in Undefined reference to SSL_CONF_CTX_new on android x86:
Might be a silly question but are you sure you are using your own build of Qt for Android ?
The error message states that it dries to dlopen the .dll which is the default behaviour and not what I'd expect when using a build with the
--openssl-linked
option.Yes, that's why I don't understand it tries to dlopen, I've configured using
-openssl-linked
and the configure script definitely says that it's configured as well:[...] Qt Network: getifaddrs() ........................... no IPv6 ifname ............................ no libproxy ............................... no Linux AF_NETLINK ....................... yes OpenSSL ................................ yes Qt directly linked to OpenSSL ........ yes OpenSSL 1.1 ............................ no SCTP ................................... no Use system proxies ..................... yes [...]
The libQt5Network.so also reports requirements on libssl.so and libcrypto.so:
$ readelf -d ~/android/env/android-21/x86/lib/libQt5Network.so | grep NEEDED 0x00000001 (NEEDED) Shared library: [libQt5Core.so] 0x00000001 (NEEDED) Shared library: [libgnustl_shared.so] 0x00000001 (NEEDED) Shared library: [liblog.so] 0x00000001 (NEEDED) Shared library: [libdl.so] 0x00000001 (NEEDED) Shared library: [libz.so] 0x00000001 (NEEDED) Shared library: [libssl.so] 0x00000001 (NEEDED) Shared library: [libcrypto.so] 0x00000001 (NEEDED) Shared library: [libstdc++.so] 0x00000001 (NEEDED) Shared library: [libm.so] 0x00000001 (NEEDED) Shared library: [libc.so]
By the way, we looked at the dlopen wrong, it's the dlopen of libQt5Network.so that triggers the error, not Qt loading openssl.
See:
E/art ( 2294): dlopen("/data/data/fr.fetacorp.SaveTheBall/lib/libQt5Network.so", RTLD_LAZY) failed: dlopen failed: cannot locate symbol "SSL_CONF_CTX_new" referenced by "libQt5Network.so"...
-
Then another silly question, are you sure you are bundling the x86 version of OpenSSL with that build of your application ?
-
@SGaist said in Undefined reference to SSL_CONF_CTX_new on android x86:
Then another silly question, are you sure you are bundling the x86 version of OpenSSL with that build of your application ?
Yes:
$ file android-build/libs/x86/* android-build/libs/x86/gdbserver: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped android-build/libs/x86/libcrypto.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libgdbserver.so: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped android-build/libs/x86/libgnustl_shared.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_bearer_libqandroidbearer.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqgif.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqicns.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqico.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqjpeg.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqtga.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqtiff.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqwbmp.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_imageformats_libqwebp.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_platforms_android_libqtforandroid.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_sensorgestures_libqtsensorgestures_plugin.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_sensorgestures_libqtsensorgestures_shakeplugin.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_sensors_libqtsensors_android.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_sensors_libqtsensors_generic.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libplugins_styles_libqandroidstyle.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libQt5Core.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, for GNU/Linux 2.6.28, stripped android-build/libs/x86/libQt5Gui.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libQt5Network.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libQt5Sensors.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libQt5Widgets.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libsave-the-ball.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped android-build/libs/x86/libssl.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
Note: no questions are silly, anyone is free to make a mistake :-)
-
It is possible that Android loads system OpenSSL first and that one is too old to handle your calls. Try linking OpenSSL statically (or use wrapper like OpenSSL documentation recommends).
-
@sierdzio said in Undefined reference to SSL_CONF_CTX_new on android x86:
It is possible that Android loads system OpenSSL first and that one is too old to handle your calls. Try linking OpenSSL statically (or use wrapper like OpenSSL documentation recommends).
Do you mean building Qt with static linking to OpenSSL?
-
@David-Demelier said in Undefined reference to SSL_CONF_CTX_new on android x86:
Do you mean building Qt with static linking to OpenSSL?
yes
-
Okay it works, I have a warning at runtime but I think it can be safely ignored:
I/ActivityManager( 1486): Start proc fr.test.SaveTheBall for activity fr.fetacorp.SaveTheBall/org.qtproject.qt5.android.bindings.QtActivity: pid=2435 uid=10053 gids={50053, 9997, 3003, 1028, 1015} abi=x86 I/QtCore ( 2435): Start W/linker ( 2435): libQt5Network.so has text relocations. This is wasting memory and prevents security hardening. Please fix.
Thanks for all suggestions!
-
Oh, bad news, starting with android-23 platform it's forbidden to have text relocations so I'll need to find a solution:
https://android-developers.googleblog.com/2016/06/android-changes-for-ndk-developers.html