android example crashes on launch: "dlopen failed: cannot locate symbol __cxa_pure_virtual"
Opened this issue · 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 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.
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.
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:
- My approach has been to specify the format to
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.
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.
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...)