barsoosayque / libgdx-oboe

🎶 libGDX audio replacement for Android (API 16+) built on top of Oboe.
MIT License
55 stars 11 forks source link

Failed to load natives on older Android versions #17

Open metaphore opened 1 year ago

metaphore commented 1 year ago

We're using libgdx-oboe built from the cb25562 and some of our users on older Android devices experience a fatal crash during app initialization time.

It appears that the libavformat.so native lib is failed to load. And the exception is:

java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libavformat.so" (built with --hash-style=gnu?)

Some googling led me to this StackOverflow thread about a similar issue - https://stackoverflow.com/questions/28638809

Sounds like building the libavformat.so (and possibly some other dependencies) with -Wl,--hash-style=both would fix the issue.

We have crash reports only from Android 5.1 devices. But one of the answers from StackOverflow says that only the devices prior Android 8 are affected.

Now, at this point, I have little experience with Android NDK and I cannot tell:

  1. If the suggested solution is correct and what are the implications of compiling with -Wl,--hash-style=both?
  2. Do we actually have an option to easily build those libraries on our side? Cuz from a quick look at the repo files, it seems like the native dependencies are linked through re-distributable dynamic libs, rather than been built from the sources.

Here's the full exception stack trace:

Fatal Exception: java.lang.UnsatisfiedLinkError: dlopen failed: empty/missing DT_HASH in "libavformat.so" (built with --hash-style=gnu?)
       at java.lang.Runtime.loadLibrary(Runtime.java:372)
       at java.lang.System.loadLibrary(System.java:988)
       at barsoosayque.libgdxoboe.OboeAudio.<init>(OboeAudio.kt:23)
       at com.crashinvaders.magnetter.android.AndroidLauncher.createAudio(AndroidLauncher.java:80)
       at com.badlogic.gdx.backends.android.AndroidApplication.init(AndroidApplication.java:120)
       at com.badlogic.gdx.backends.android.AndroidApplication.initialize(AndroidApplication.java:81)
       at com.crashinvaders.magnetter.android.AndroidLauncher.onCreate(AndroidLauncher.java:62)
       at android.app.Activity.performCreate(Activity.java:6251)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2622)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2766)
       at android.app.ActivityThread.access$1000(ActivityThread.java:197)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1611)
       at android.os.Handler.dispatchMessage(Handler.java:111)
       at android.os.Looper.loop(Looper.java:224)
       at android.app.ActivityThread.main(ActivityThread.java:5958)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1113)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:879)
barsoosayque commented 1 year ago

Thanks for the detailed report. Yeah, seems pretty easy to do, libavformat.so (and every other ffmpeg library) built by me, so I'll read the SO link and definitely try this fix, it seems harmless.

metaphore commented 1 year ago

Thanks for the quick reply! Sounds great! Feel free to ping me when it's available in the repo, I'd love to help you test it.

barsoosayque commented 1 year ago

Alright, I've updated the native libs in 525008c, no difference on my device, hopefully it actually works for those older androids. (I suggest making clean builds). I have no old android devices on my hands so sadly I can't try the fix myself :pensive:

metaphore commented 1 year ago

Thanks! I'll include a fresh libgdx-oboe lib into my next app release and see how it behaves. Will come back to you in a few weeks.

dasisdormax commented 1 year ago

Hey everyone.

I did some testing in the Android Emulator with API 22 and thought I'd add my findings here.

I still got a crash with the build in 525008c, so I tried building the library myself. Fiddling with the compile flags only got me to a different error ( dlopen failed: cannot locate symbol "__register_atfork" )

However I got it to work by lowering TOOLCHAIN_VERSION to 21 (lowest that worked on my end). My guess is, it was just luck for the previous TOOLCHAIN_VERSION of 33 to work on older devices. With that change, the --hash-style option also is not necessary anymore.

You can find my full code (with an older version and a custom build script) over here. Feel free to use of it what you find useful.

metaphore commented 11 months ago

Sorry for the late report, but I can confirm, the crashes are still there at 525008c. Those are specifically on old devices. I've never seen a crash from anything newer than Android 5.1.1

I don't have any ideas at this point, but someone just reported an oddly similar issue for one of my native-based libGDX libs. This thing gets hairy 😞