I have an alljoyn library in my project to pair android devices for a voting app. In old devices the app runs properly but in new devices it stops when it is starting to run.
This is the error, I got:
Caused by: java.lang.UnsatisfiedLinkError: dlopen failed: library "libcrypto.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
at java.lang.System.loadLibrary(System.java:1657)
at com.example.nima.voting.alljoyn.peergroupmanager.PeerGroupManager.<clinit>(PeerGroupManager.java:60)
NOTE: I'm not an Android developer.
That said, I found this StackOverflow question, which mentions similar behavior to what you described:
The master Android process is zygote. Its like init in Linux. Zygote
loads OpenSSL when its start, and it loads version 0.9.8. If you link
against OpenSSL 1.0.1, then you will get mysterious runtime crashes.
The crashes are due to the Android loader using the 0.9.8 version of
the library (already mapped from Zygote), and not your version of
OpenSSL.
You can use a shared object, but your shared object must be a wrapper around the static version of libssl and libcrypto.
You mentioned that the app loads properly in old devices but crashes in new devices. If the new devices are linking against OpenSSL v1.0.1 and the old ones against v0.9.8, then this might be the root cause of your problem.
The solution seems to be either to compile against static libraries for libcrypto (and for libssl too, apparently), or to rename these dependencies after the build, then copy them into your precompiled directory (if I interpreted the answer in the link correctly):
The reason is that the system comes with its own (probably different)
version of these shared libraries, and the loader will use
/system/lib/libssl.so and /system/lib/libcrypto.so instead of your
private copies.
Related
I recently built libssh2 for Android using OpenSSL as a crypto backend, I also built libcrypto.so and libssl.so myself using the NDK.
In my build process I generate a final libcustom.so linked with libssh2.a.
Google said "If you tried to use your own copy of OpenSSL but forgot to bundle it with your app's APK, the app may run normally on versions of Android platform that includes libcrypto.so. However, the app could crash on later versions of Android that do not include this library (such as, Android 6.0 and later)." that's why I package libcrypto.so, libssl.so and libcustom.so into my APK.
When running an Android app that loads the libcustom.so, my app crashes with the following error:
failed: dlopen failed: cannot locate symbol "EVP_cast5_cbc" referenced by "libcustom.so"... ONLY ON ANDROID 5.
It works well on Android 6 and above.
The symbol EVP_cast5_cbc is undefined but referenced in libssh2.a, but well defined in libcrypto.so.
I don't understand why it runs correctly on Android 6 and above and not on Android 5.
I thought that on Android 5, the libcrypto.so used was not the one I embed in the APK but the one from /system/lib ; so I tried to rename the libcrypto.so and build libssh2.a using the libcrypto renamed, but I am facing the same issue.
Does anybody have an idea ?
Thank's in advance.
Google has changed the use of private libraries for Marshmallow and above; this may be the case that you are experiencing.
Starting in Android 6.0, the system prevents apps from dynamically linking against non-NDK libraries, which may cause your app to crash.
According to this table: https://developer.android.com/about/versions/nougat/android-7.0-changes.html#ndk. You should be able to see logcat warnings when you are running Lollipop with private libraries. For example:
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120
I tried to build 64bit (arm64) Openssl v1.1.1b and add it to my app as shared library (libcrypto.so and libssl.so).
I built standalone toolchain with --arch arm64 and --api 21 arguments, then I built openssl libraries with it and added them to my app.
All 64bit devices with Android 6.x and higher works great, but I am stuck on the Android 5.0.1 64bit – Lenovo TAB 2 A10-70L tablet.
The problem is, that on this specific Android, when I am loading libssl.so, I get error:
E/art ( 2755): dlopen("/data/app/com.myapp.mypackage-1/lib/arm64/libssl.so", RTLD_LAZY) failed:
dlopen failed: cannot locate symbol "EVP_camellia_128_cbc" referenced by "/data/app/com.myapp.mypackage-1/lib/arm64/libssl.so"...
E/MY_APP( 2755): 2019-06-12 14:22:27,984: [MY_APP][18446744071776944368] ERROR (2117) - Error in loading libraries :
dlopen failed: cannot locate symbol "EVP_camellia_128_cbc" referenced by "/data/app/com.myapp.mypackage-1/lib/arm64/libssl.so"...
So exception will be thrown -> loading of other libraries after libssl.so will be not performed and app crashes during or after splashscreen.
I found on StackOverflow, that it can be caused, if you compile native library (as openssl) against higher android version, then the used tablet is… But I make openssl with api 21, that’s Android 5.0, so there shouldn’t be problem. It seems, that openssl expects this symbol in libraries of the device and this device doesn’t have it.
What I tried:
To use different NDK’s to build openssl -> I used 15-19 NDK’s,
with this version I built an app, but the same error occurred (with
“cannot locate symbol”). I tried 12-14 NDK’s to be close to NDK we
are using in our app for other native libs (which is 12b), but with
this NDK I am not able to make openssl libs at all, it will fail
during build.
To use different NDK’s to build whole app -> I
tried 16 and 19, but there were failures in the build and I don’t
think, it would help.
To use 21 as minsdkversion in
AndroidManifests, project-properties and build.gradle files to have
everything in the same api version, but with no success.
I tried built and implement higher version of openssl – 1.1.1c – but the
same error with Camellia occurred.
I tried to add that missing
symbol as a macro to evp.h, but with no success (maybe I should add
it in the different way).
I tried to exclude camellia cipher from
build of openssl by editing makefile, but whole build ended with
error
Why might this be happening, and how can I fix it to run my app on Android 5.x 64bit?
Self solution:)
After all I tried as I mentioned above I found the only solution that worked - build openssl as static library (so libssl.a and libcrypto.a) and add this files to app.
It seems, that dynamic openssl libraries (*.so) does not work for my app, which uses older NDK, but to be honest, I still don't know why.
Once the APK launches, I get this error:
E AndroidRuntime: java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.engine001.test/android.app.NativeActivity}:
java.lang.IllegalArgumentException: Unable to load native library:
/data/app/com.myapp.test-2/lib/arm/libLauncher.so
Even the most basic NDK app seems to have this issue, even without linking to other .so. Using latest Tegra/NDK/etc... tools.
Entire system worked fine until I upgraded systems and updated tools.
EDIT: I have tried to install the previous version of the tools I had working (ndk r12b). I have also tried literally copying my old NVPACK and setting things back up to no avail.
I am not sure what to include. This is a very large project currently in use.
I cannot include actual Java code as I modify the APK after and this cannot be done if a DEX file is produced, which is what Java entails. So to be clear, using a pure NativeActivity.
Unable to load native library: /data/app/com.myapp.test-2/lib/arm/libLauncher.so
Newer NDK does not support this path anymore. You need to ensure that your ABIs are x86, x86_64, armeabi-v7a, arm64-v8a. i.e. paths should be something like below:
/data/app/com.myapp.test-2/lib/arm64-v8a/libLauncher.so
I have developed android project using android studio.
It uses android native library which other developer built for speech recognization.
The APK works perfectly when i install on android devices.
I need to put this APK into AOSP because I am going to make android device only for our system. (I have already customized AOSP)
But after adding the APK into AOSP, the APK can not load library.
Error log:
java.lang.UnsatisfiedLinkError: dlopen failed: can't protect segments for "../libsengine.so": Permission denied
Please help me to fix this problem.
If you add your apk into AOSP system/app/ path as a prebuilt app, this might be of help:
Error adding prebuilt apk with shared libraries to AOSP
http://blog.csdn.net/a462533587/article/details/46380795
The problem is the shared library packaged in your apk has never been extracted to /data/app-lib directory, so it can't be linked.
It seems that the library you are using is utilizing some sort of dynamic code loading that is strictly prohibided on Android 26+ (Writable and Executable Segments Enforced for API level >= 26) .
You can read more about the security risk of TEXTREL on the following blog.
I assume that the reason the code works when compiling with Android Studio is because your build.gradle defines a minSdkVersion/targetSdkVersion that does not enforce the TEXTREL check. When compiling via the AOSP make, targetSdkVersion is most probably defined to be the 'current' version where the TEXTREL check is enforced.
These are only assumptions, so I guess you could check or alternatively provide more information such as the platform you are building and the Android.mk + build.gradle files.
I Think This is related to Marshmallow switching from OpenSSL to BoringSSL.
Your exception is occurring in the referenced library code. Contact the vendor for a fix or manually include the OpenSSL libraries to avoid the issue.
You can see this link: https://sourcedna.com/blog/20150806/predicting-app-crashes-on-android-m.html
Should/does NDK9 work with android API19? (though it was released with API18).
Full story:
I was building an Android App using kivy, python-for-android and buildozer.
compiling with MDK9 (ie 9d) and api19 result in error:
E/AndroidRuntime( 1773): java.lang.UnsatisfiedLinkError: Cannot load library: soinfo_relocate(linker.cpp:975): cannot locate symbol "wait4" referenced by "libpython2.7.so"...
compiling with NDK9 (ie 9d) and API18 works. :)
Just in case anyone stumbles across this. I had the same issue, but building python from scratch using the platform tools, and with NDK r10 and r10b.
It's because google removed an inline wait4() declaration in the NDK platform android-19. The original problem was that wait4() was exposed in the headers but not declared anywhere, so if you tried to use wait4 on older NDKs, you'd probably crash (like you do now).
So they went in and added it to libc.so in API 18 I believe, but libc.so is shipped with the O/S, so devices with O/S older than 18 would not have wait4, so they patched it by adding an inlined wait4() method in NDK platforms up through android-18, then took it out in android-19 I'm not fully sure why yet, seems like it could have made more sense to leave it alone at that point, especially since it's considered an obsolete function. I was told I should not build against android-19 if I wanted the app to run on devices older than API 18, but others say to always use the latest NDK to match your build target. Here is a link to the problem.
https://code.google.com/p/android/issues/detail?id=19854
In my case, I went into the cpython Modules/posixmodule.c file, and added:
#if defined(__ANDROID__)
#undef HAVE_WAIT4
#endif
And in my case that's fine, because none of my python modules use wait4. Indeed, Linux deems the wait4 command obsolete (http://linux.die.net/man/2/wait4). You should instead use the waitpid.
So, even if you download some 3rd party python module that does use wait4, you have 2 options. 1) change that module to use waitpid, or 2) update the Modules/posixmodule.c file inside the "ifdef HAVE_WAIT4" section, and replace the wait4 call with waitpid. The downside is you lose the returned resource usage information, which waitpid doesn't provide, so then if your module needs that, you'd have to add something to retrieve resource usage for that pid separately.
Alternatively, you could remove "wait4" from your configure script if you never plan to use it, and any modules you add that needed it would break, at which point the new engineer working on the problem would have to rediscover all of this over again.
Android SDK are released more often that NDK. It happened more than once that if you use a too recent SDK, the NDK will not have the .h for it. Now i'm not sure this would be related to your issue at all.