I have an App that uses a library with native libs and now in Android 11 is crashing due to fdsan.
I have contacted the library providers, but they are not going to deliver a new version of the library with this issue solved, so I need to be able to somehow disable fdsan.
I think the solution would be to call when I am on Android 11 or higher:
if(android_get_device_api_level()>=30)
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
But I am unable to compile because of error:
use of undeclared identifier 'android_fdsan_set_error_level'
Because this was only added in Android 10 (API 29)
So my question is how can I call this function in my project?
I am creating a specific cpp file for this and a specific library for this, so I would need to some how for this library say that it is only for Android 10 or higher.
Is there some definition in the cpp file or in the Android.mk file that I can use to be able to compile this specific library that I will invoke from Java in Android 11 or higher only when my App starts?
According to the documentation here you should do it like this:
if (android_fdsan_set_error_level) {
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
}
You will have to set your target SDK to 10 or above for this to work.
Alternatively, if you are compiling this in to a separate native binary, you can use conditional compilation.
Include this file.
Then do something like this:
#if __ANDROID_API__ >= __ANDROID_API_P__
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
#endif
Just make sure this binary is never loaded on older devices, else the linker will give an error.
Depending on how your whole project is built, you may need to ship a separate APK for this in a bundle.
Finally, if all else fails, you may try using dlopen and dlsym to load the function dynamically at runtime, but you will need to find out which module exactly it is included in.
Related
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
Android already has the PCRE shared library ("/system/lib/libpcre.so"), but it's compiled without Unicode support, so I've built my own version of PCRE for Android. My native code is linked to the PCRE shared library. However, when I run my app, it uses the system's version of PCRE, rather than the one I've built, even though my APK does include my version of PCRE. How do I make it use my version of PCRE rather than the system's? Generally in Linux I use "LD_LIBRARY_PATH" or "RPATH", but on Android I don't know how to use them, if that's at all possible.
You can load("your-path-to-lib") before you load the main library. With this API you can load a native library at arbitrary location. But the easiest way is to rely on the default behavior of build and installer, which will pack the native libraries (named libsomething.so) that it finds in libs/<ABI> folders, into the APK file, and unpack the ABI variant that matches the target into
getContext().getApplicationInfo().nativeLibraryDir
(this was added in API level 9)
If the library is pre-loaded, you cannot have your library side-by-side with the system one, due to a bug that invloved older versions of Android. Still, you may succeed to unload it manually, using dlclose():
handle = dlopen("<libname>", RTLD_NOLOAD);
dlclose(handle);
dlclose(handle); // twice, because dlopen() increments ref count
You will probably do these manipulations in a separate small dlclose_helper.so. Load this helper load before you load the main library, which needs the private version of <libname>.
A fix was introduced for API level 23 that lets us finally load both dir1/libx.so and dir2/libx.so (see the official doc).
Note that for API level 24, new restrictions have also been introduced that limits access to system libraries (you can only load white-listed ones).
I believe the only way is to rename the library (libpcre_myapp, for example).
Note that renaming just the file probably is not sufficient, but changing the SO_NAME ELF property.
I am using "pthread_condattr_setclock" in one of my native shared library. Building is fine, but when I load the native library in android application using System.loadLibrary app is getting terminated throwing exception
failed: dlopen failed: cannot locate symbol "pthread_condattr_setclock" referenced by abcd.so
This exception I am not getting when I run my application in android 5.0, but in other android versions.
Anybody has any idea about this?
Android did use non-standard functions when it came to pthread_condattr functions. Even when the declarations for the standard ones are there in the pthread.h file of my NDK directory, Android complains about them not being defined if I use a version prior to API level 21 too.
Before Android 5.0, one could use other non-standard functions for waiting using the monotonic clock, for example (pthread_cond_timedwait_monotonic_np), but they have been removed in Android 5.0. I do not know why the functions don't work when they are declared and (AFAIK) are not officially unsupported, but it looks like the non-standard methods of the pthread_condattr family need to be used if on an Android version prior to 5.0.
See for example here.
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.
Some mystery is going on with my project :)
I have a shared library that uses libjpeg which is static library. It all worked fine but now when I need to add a few changes to the project it just stopped including libjpeg in my shared module.
So before when it worked, my shared module (.so file) was around 90Kb and now it 4Kb and application can't run saying that it can't find libjpeg.so
And folders structure is following:
/platform/libjpeg - include files for libjpeg
/platform/libraries - contain libjpeg.a and a few other libraries
UPDATE: After playing around with the projects I figured out that the problem appeared after I wanted to add android:installLocation into manifest. Following Google's recommendations for backward compatibility (http://developer.android.com/guide/appendix/install-location.html) I changed project's API level to 8 (so it parses manifest without errors) and left minSdkVersion="7" (so it runs on previous version). However, this particular change in the project affects the NDK build. Probably, libjpeg is included in android-8 and it doesn't want to build it in as a static library?
Anyway, the question is: Is it possible in eclipse to ignore error about installLocation in manifest using API level 7 or is it possible to force ndk-build to use API level 7 while keeping level 8 in the project settings?
In NDK you can find document docs/ANDROID-MK.html. In this document you will find option TARGET_PLATFORM. This should help.