cpal icon indicating copy to clipboard operation
cpal copied to clipboard

android example crashes on launch: "dlopen failed: cannot locate symbol __cxa_pure_virtual"

Open nikita-skobov opened this issue 3 years ago • 5 comments

My device:

google pixel 4a (sunfish)
aarch64
ro.build.version.release = 11
ro.build.version.sdk = 30

Steps to reproduce:

First I tried:

git clone https://github.com/RustAudio/cpal
cd cpal
cargo apk build --example android

Then I install the android.apk to my phone, and run it, and it crashes immediately. Looking at the logcat:

Click to expand
03-21 19:08:11.676  6588  6588 W NativeActivity: NativeActivity LoadNativeLibrary("/data/app/~~OUwQhY55D-pFmz47CJ2IbQ==/rust.example.android-wZ5h-IHTeEtI1UPvU4vctg==/lib/arm64/libandroid.so") failed: dlopen failed: cannot locate symbol "__cxa_pure_virtual" referenced by "/data/app/~~OUwQhY55D-pFmz47CJ2IbQ==/rust.example.android-wZ5h-IHTeEtI1UPvU4vctg==/lib/arm64/libandroid.so"...
03-21 19:08:11.676  6588  6588 D AndroidRuntime: Shutting down VM
03-21 19:08:11.670  6588  6588 W example.android: type=1400 audit(0.0:390678): avc: granted { execute } for path="/data/app/~~OUwQhY55D-pFmz47CJ2IbQ==/rust.example.android-wZ5h-IHTeEtI1UPvU4vctg==/lib/arm64/libandroid.so" dev="dm-16" ino=54014 scontext=u:r:untrusted_app_29:s0:c4,c257,c512,c768 tcontext=u:object_r:apk_data_file:s0 tclass=file app=rust.example.android
03-21 19:08:11.677  6588  6588 E AndroidRuntime: FATAL EXCEPTION: main
03-21 19:08:11.677  6588  6588 E AndroidRuntime: Process: rust.example.android, PID: 6588
03-21 19:08:11.677  6588  6588 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/~~OUwQhY55D-pFmz47CJ2IbQ==/rust.example.android-wZ5h-IHTeEtI1UPvU4vctg==/lib/arm64/libandroid.so": dlopen failed: cannot locate symbol "__cxa_pure_virtual" referenced by "/data/app/~~OUwQhY55D-pFmz47CJ2IbQ==/rust.example.android-wZ5h-IHTeEtI1UPvU4vctg==/lib/arm64/libandroid.so"...
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.NativeActivity.onCreate(NativeActivity.java:178)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8000)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7984)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:223)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7660)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-21 19:08:11.677  6588  6588 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

I looked up the issue with __cxz_pure_virtual and some people said you could just stub it out with:

#[no_mangle]
pub unsafe extern "C" fn __cxa_pure_virtual() {
    loop {
         
    }
}

So I tried putting that in examples/android.rs and rebuilding, and then I get:

With the __cxa_pure_virtual stub

Click to expand
03-21 19:06:01.480  6534  6534 W NativeActivity: NativeActivity LoadNativeLibrary("/data/app/~~89rj6sFEJqYLOUzNJvP7SA==/rust.example.android-1Xjx_7TTAqivFzu181VStw==/lib/arm64/libandroid.so") failed: dlopen failed: cannot locate symbol "_ZNKSt13runtime_error4whatEv" referenced by "/data/app/~~89rj6sFEJqYLOUzNJvP7SA==/rust.example.android-1Xjx_7TTAqivFzu181VStw==/lib/arm64/libandroid.so"...
03-21 19:06:01.480  6534  6534 D AndroidRuntime: Shutting down VM
03-21 19:06:01.481  6534  6534 E AndroidRuntime: FATAL EXCEPTION: main
03-21 19:06:01.481  6534  6534 E AndroidRuntime: Process: rust.example.android, PID: 6534
03-21 19:06:01.481  6534  6534 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/~~89rj6sFEJqYLOUzNJvP7SA==/rust.example.android-1Xjx_7TTAqivFzu181VStw==/lib/arm64/libandroid.so": dlopen failed: cannot locate symbol "_ZNKSt13runtime_error4whatEv" referenced by "/data/app/~~89rj6sFEJqYLOUzNJvP7SA==/rust.example.android-1Xjx_7TTAqivFzu181VStw==/lib/arm64/libandroid.so"...
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.NativeActivity.onCreate(NativeActivity.java:178)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8000)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7984)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:223)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7660)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-21 19:06:01.481  6534  6534 E AndroidRuntime: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)

So a similar error, but this time it cant find some other function.

I also found @katyo oboe-rs project, and I see they have oboe-demo.apk in their releases, so I thought I should try running an apk that someone else built (maybe my error was coming from me building it wrong somehow), so I ran that oboe-demo.apk and this time I see:

From the oboe-demo example

Click to expand
03-21 19:10:01.545  6752  6752 W NativeActivity: NativeActivity LoadNativeLibrary("/data/app/~~LpiXmkBDwZU5Vl8-g-5AqQ==/rust.oboe_demo-VFTxoG3fefCxFcnGPQCc0Q==/lib/arm64/liboboe_demo.so") failed: dlopen failed: cannot locate symbol "__cxa_pure_virtual" referenced by "/data/app/~~LpiXmkBDwZU5Vl8-g-5AqQ==/rust.oboe_demo-VFTxoG3fefCxFcnGPQCc0Q==/lib/arm64/liboboe_demo.so"...
03-21 19:10:01.546  6752  6752 D AndroidRuntime: Shutting down VM
03-21 19:10:01.546  6752  6752 E AndroidRuntime: FATAL EXCEPTION: main
03-21 19:10:01.546  6752  6752 E AndroidRuntime: Process: rust.oboe_demo, PID: 6752
03-21 19:10:01.546  6752  6752 E AndroidRuntime: java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/~~LpiXmkBDwZU5Vl8-g-5AqQ==/rust.oboe_demo-VFTxoG3fefCxFcnGPQCc0Q==/lib/arm64/liboboe_demo.so": dlopen failed: cannot locate symbol "__cxa_pure_virtual" referenced by "/data/app/~~LpiXmkBDwZU5Vl8-g-5AqQ==/rust.oboe_demo-VFTxoG3fefCxFcnGPQCc0Q==/lib/arm64/liboboe_demo.so"...
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.NativeActivity.onCreate(NativeActivity.java:178)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:8000)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.Activity.performCreate(Activity.java:7984)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:106)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:223)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at android.app.ActivityThread.main(ActivityThread.java:7660)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at java.lang.reflect.Method.invoke(Native Method)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at com.android.internal.os.ExecInit.main(ExecInit.java:48)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
03-21 19:10:01.546  6752  6752 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: Error reporting crash
03-21 19:10:01.547  6752  6752 E AndroidRuntime: java.lang.RuntimeException: Bad file descriptor
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at android.os.BinderProxy.transactNative(Native Method)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at android.os.BinderProxy.transact(BinderProxy.java:550)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at android.app.IActivityManager$Stub$Proxy.handleApplicationCrash(IActivityManager.java:5208)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at com.android.internal.os.RuntimeInit$KillApplicationHandler.uncaughtException(RuntimeInit.java:158)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1073)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
03-21 19:10:01.547  6752  6752 E AndroidRuntime: 	at java.lang.Thread.dispatchUncaughtException(Thread.java:2203)

So in the oboe-demo, it actually didnt 'crash' right away. it kept running, but it wasnt doing anything. it was just producing this error over and over, and once again the issue is dlopen failed: cannot locate symbol "__cxa_pure_virtual"

Conclusion

Is this an issue with android 11 not having stdc++ or something like that? i think i saw someone comment something like that before.

I debugged this for a few hours today and tried a bunch of different forks and hacks and I couldn't figure it out, so hoping someone with more knowledge about android audio could help me out.

nikita-skobov avatar Mar 22 '21 00:03 nikita-skobov

@nikita-skobov I've also run into this issue, also on a Pixel 4a.

I also tried a bunch of different things over a couple of days (including manually linking the missing C++ runtime symbols from libc++abi.a), with no success.

In the end I've chosen to use AAudio directly instead of using cpal+Oboe when building for Android.

irh avatar Jun 01 '21 15:06 irh

@irh

Could you refer me to a minimal example? I tried AAudio as well but I've must have done it wrong because I couldn't get it to work.

nikita-skobov avatar Jun 02 '21 01:06 nikita-skobov

I can't point you to an example as I'm working on a private project, but I can say that I found it quite straight-forward using @endragor's AAudio bindings.

  • Use an AAudioStreamBuilder to configure a stream, finalising the build with .open_stream().
  • Once the stream's created, use .request_start() to get the stream running.
  • The only slightly tricky thing was figuring out how to make use of the audio buffer in the callback.
    • My approach has been to specify the format to Format::F32 with a fixed channel count. You can then build a [f32] slice with:
let buffer = unsafe {
  std::slice::from_raw_parts_mut(
    buffer.as_ptr() as *mut f32,
    frames as usize * CHANNEL_COUNT,
  )
};
  • If you don't specify the format+channel count then you'll need to inspect the callback's AAudioStreamInfo.

This is my first time looking at AAudio so I might have misunderstood something here, but it seems to be working pretty well so far.

irh avatar Jun 02 '21 07:06 irh

Hi, I saw this same error when using jni-rs (so nothing to do with cpal, sorry, I found this issue through google).

In my lib.rs I had some JNI method implementations (e.g. #[no_mangle] pub extern "system" fn Java_path_to_package_MyClass_helloWorld(...)) and some C implementations (e.g. #[no_mangle] pub extern "C" fn hello_world()). I then compiled this to a cdylib (targeting Android) and tried to load the library in my Android app, and I saw the same error about __cxz_pure_virtual (and when I implemented that with a loop, I got the next error that OP found also).

I found that when I deleted my C functions from lib.rs (I didn't need them anyway, just a relic from some testing I was doing) this error went away.

FWIW my rust library depends on oboe-rs, so I'm in the same ballpark as you two. I'm not using CPAL because I only found out about it today.

Edit: scratch that, it's started showing this error again and I've just added more JNI functions...

Edit edit: it looks like the C functions were a red herring. When I switched between building with debug to building with release mode, it seemed to resolve the issue. I must have tried two things at once - not very scientific of me. Edit edit edit: I'm not even sure it's release mode as it seems to come and go completely randomly. It might be going wrong when I build with this plugin but not when I build via command line, but I'm not 100% sure. Last edit: seems just random whether it decides to fail. I can make any change to the code and next time it might work or might fail.

chriscoomber avatar Sep 17 '21 14:09 chriscoomber

This can be solved by enabling the shared-stdcxx feature for oboe

oboe = { version = "0.4", features = [ "java-interface", "shared-stdcxx" ] }

Then I also had to copy libc++_shared.so into my jniLibs directory (there's likely a way to automate this...)

trobanga avatar Oct 07 '22 14:10 trobanga