KeepSafe/ReLinker

Exception java.lang.UnsatisfiedLinkError

Dimon4eg opened this issue · 20 comments

Hi,

I'm using ReLinker 1.2.2 with cocos2d 3.15.1.

Here is crash from real device:
Model: Lenovo K50-t5
Android API: 23
Android OS: 6.0

Exception java.lang.UnsatisfiedLinkError: dlopen failed: "/mnt/expand/96334dfa-6d50-4821-9b56-38dcc67f3a70/user/0/xxxxxxxxxxxxxx/app_lib/libcocos2djs.so" is 32-bit instead of 64-bit
java.lang.Runtime.load (Runtime.java:332)
java.lang.System.load (System.java:1069)
com.getkeepsafe.relinker.SystemLibraryLoader.loadPath (SystemLibraryLoader.java:29)
com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal (ReLinkerInstance.java:198)
com.getkeepsafe.relinker.ReLinkerInstance.loadLibrary (ReLinkerInstance.java:136)
com.getkeepsafe.relinker.ReLinker.loadLibrary (ReLinker.java:70)
com.getkeepsafe.relinker.ReLinker.loadLibrary (ReLinker.java:51)
org.cocos2dx.lib.Cocos2dxActivity.onLoadNativeLibraries (Cocos2dxActivity.java:247)
org.cocos2dx.lib.Cocos2dxActivity.onCreate (Cocos2dxActivity.java:265)
org.cocos2dx.javascript.AppActivity.onCreate (AppActivity.java:60)
android.app.Activity.performCreate (Activity.java:6583)
android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1114)
android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2531)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2666)
android.app.ActivityThread.-wrap11 (ActivityThread.java)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1493)
android.os.Handler.dispatchMessage (Handler.java:111)
android.os.Looper.loop (Looper.java:207)
android.app.ActivityThread.main (ActivityThread.java:5769)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:789)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:679)

You load 32- bit so on 64-bit handset. You should load 64-bit so file.

32-bit so should work on 64-bit device. Isn't?

Hi, I got exactly the same issue. Do you think it's caused by the difference between System.loadLibrary() and System.load()?

https://stackoverflow.com/questions/27186243/use-32-bit-jni-libraries-on-64-bit-android

I have similar issue. To be sure that only 32bit elf files are provided I've checked what is in result apk. As @dyhsia0 mentioned it has something to do with System.load(String). It's executed via libraryLoader.loadPath(absolutePath) in ReLinkerInstance#loadLibraryInternal. I wasn't able to reproduce it, most devices in crash report have mediatek MT67xx CPUs.

Two more the same crashes on DOOGEE devices:
Model: DOOGEE X9pro
Android API: 23
Android OS: 6.0

Model: DOOGEE X5max_PRO
Android API: 23
Android OS: 6.0

It seems the crash happens on some devices with Android 6.0

if you want to load 32 .so libs on 64 phone, you should set abiFilters:

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters 'armeabi-v7a', 'x86'
        }
    }
    ...
}

and remove x86_64', 'arm64-v8a' folders from jniLibs!

you can't put 32 libs to 'x86_64', 'arm64-v8a' folders and you can't leave it empty...
if you don't have 64 .so libs then exclude x86_64', 'arm64-v8a' (remove folders and set abiFilters)
64 bit phones will be working with 'armeabi-v7a', 'x86'...

@anonym24 It's not that simple I don't have 64bits libs at all in apk - it's all cleaned out. Problem still exists.

@bholota you didn't read carefully

what you have in the project (not apk) - in jniLibs folder?

did you add abiFilters ?

@anonym24 I don't have jniLibs in my project directly. Some 3rd party libs are providing also native dependencies. I'm using packagingOptions to exclude x64 libs instead abiFilters. After extracting apk there are only armeabi and armeabi-v7a + x86 stuff as expected. There is no trace of arm x64.

My app works on devices like samsung s8, it works on my test mediatek devices like Cubot Dinosaur same one that reports crashes in play store. Somehow those mtk devices instead of loading 32bit in compatibility mode are expecting x64 libs.

it's better to use abiFilters (here you officially specify for which processors you provide libs)

Somehow those mtk devices instead of loading 32bit in compatibility mode are expecting x64 libs.

did you find out this from Google Console logs for that device?

In my case ReLinker helped for one of Google Test Devices: bytedeco/javacv#836

I've such stacktrace:

java.lang.UnsatisfiedLinkError in java.lang.Runtime.load
Exception
java.lang.UnsatisfiedLinkError: dlopen failed: "/mnt/expand/4e07f925-0bf9-43ea-b25e-5c762252655c/user/0/com.secret.package/app_lib/libsqlcipher.so" is 32-bit instead of 64-bit
at java.lang.Runtime.load(Runtime.java:332)
at java.lang.System.load(System.java:1069)
at pc.z(SourceFile:29)

System.load is triggered by ReLinker

I have the same issue, but reversed:

Fatal Exception: java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/<my_package>/app_lib/libexample.so" is 64-bit instead of 32-bit at java.lang.Runtime.load0(Runtime.java:928) at java.lang.System.load(System.java:1621) at com.getkeepsafe.relinker.SystemLibraryLoader.loadPath(SystemLibraryLoader.java:29) at com.getkeepsafe.relinker.ReLinkerInstance.loadLibraryInternal(ReLinkerInstance.java:198) at com.getkeepsafe.relinker.ReLinkerInstance.loadLibrary(ReLinkerInstance.java:136) at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:70) at com.getkeepsafe.relinker.ReLinker.loadLibrary(ReLinker.java:51)...

My code:

try { System.loadLibrary("example"); } catch (UnsatisfiedLinkError e) { ReLinker.loadLibrary(context, "example"); }

I have abifilters abiFilters "armeabi-v7a", "arm64-v8a" and apk have both native libs with libexample.so.
And I see crash only on Sony Xperia XA Android 7+ (mediatek MT67xx CPU).

Is it any solutions?

@ilyamuromets I've seen similar issues with Lenovo phones; we fixed them by implementing ABI splits, such that each APK contained only one architecture.

@benjamin-bader I build apk only with one filter: abiFilters "armeabi-v7a"; and I see on crashlytics the following only on Sony Xperia XA:

Fatal Exception: java.lang.UnsatisfiedLinkError
dlopen failed: "/data/data/<package>/app_lib/libexample.so" is 32-bit instead of 64-bit
com.getkeepsafe.relinker.SystemLibraryLoader.loadPath

Why this device can't use 32-bit libs? Where backwards compatibility was lost?

I don't know the answer here, and I don't have this device myself to check. It certainly appears to be a packaging bug on that device; maybe you will need to ship a 64-bit-only APK to fix it.

I build and publish separate apk for armeabi-v7a and arm64-v8a and it doesn't help.
I see Fatal Exception: java.lang.UnsatisfiedLinkError
dlopen failed: "/data/data/my.package/app_lib/libexample.so" is 64-bit instead of 32-bit

Sony Xperia XA on which I see the error has 64 bit Octa Core processor. Why it requires 32-bit lib?

This sounds like a device bug to me. The most similar bug I've ever had was on that Lenovo phone, where it advertised supported architectures incorrectly and got the wrong APK version from the Play Store. In our case, the solution was to give the correct ABI a higher version number than the incorrect ABI. You wouldn't think that would matter, but it helped for us.

This is very likely not to be your problem, but maybe it gives you a direction for debugging. We can't help you any further here, since this isn't a ReLinker problem. Good luck!

@ilyamuromets I suggest you to build also for x86

This issue has strayed widely from the problem initially reported; I'd vote for the admins to close it (@KeepSafe/relinker-contributors).

Thank you @benjamin-bader for your input here. I'm closing this issue as I agree that it looks like a device specific issue and not a library loading issue.