After updating the Android NDK to r28+ (e.g., 28.0.13004108), the app crashes on launch when loading libBluetoothStateManager.so from this module. The error is a runtime linking failure for the C++ exception handling symbol __cxa_init_primary_exception. This only reproduces on Android 15+ (API 35) devices/emulators with 16 KB page size enabled, which is now optional for performance but required for Play Store compliance starting Nov 1, 2025.
This seems related to ELF segment misalignment in the prebuilt .so files when using newer NDKs, as the library doesn't explicitly support flexible page sizes (e.g., via -Wl,-z,max-page-size=16384).
To Reproduce:
- Set ndkVersion "28.0.13004108" (or any r28+) in android/app/build.gradle.
- Ensure compileSdk 35 and targetSdk 35.
- Build and install the app (e.g., npx react-native run-android).
- Crash occurs immediately during System.loadLibrary("BluetoothStateManager") in BluetoothStateManagerPackage.().
Expected behavior:
The native library loads successfully without unresolved symbols.
Actual behavior:
Fatal exception with the following log:
E FATAL EXCEPTION: main
Process: com.vipr.app, PID: 19376
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__cxa_init_primary_exception" referenced by "/data/app/~~yf1EFyj1CTVY4WOGvtQLQQ==/com.vipr.app-yOVskuWcmAcbI33GSX1VAQ==/base.apk!/lib/arm64-v8a/libBluetoothStateManager.so"...
at java.lang.Runtime.loadLibrary0(Runtime.java:1090)
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1765)
at com.margelo.nitro.bluetoothstatemanager.BluetoothStateManagerPackage.(BluetoothStateManagerPackage.java:28)
at com.facebook.react.PackageList.getPackages(PackageList.java:114)
at com.vipr.app.MainApplication$reactNativeHost$1.getPackages(MainApplication.kt:23)
at com.facebook.react.ReactNativeHost.getBaseReactInstanceManagerBuilder(ReactNativeHost.java:112)
at com.facebook.react.ReactNativeHost.createReactInstanceManager(ReactNativeHost.java:85)
at com.facebook.react.ReactNativeHost.getReactInstanceManager(ReactNativeHost.java:57)
at com.facebook.react.ReactDelegate.loadApp(ReactDelegate.java:302)
at com.facebook.react.ReactActivityDelegate.loadApp(ReactActivityDelegate.java:156)
at com.facebook.react.ReactActivityDelegate.lambda$onCreate$0(ReactActivityDelegate.java:150)
at com.facebook.react.ReactActivityDelegate.$r8$lambda$HPdXfLmAU1y4Wc1XbwAHziPP2WA(Unknown Source:0)
at com.facebook.react.ReactActivityDelegate$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at com.facebook.systrace.Systrace.traceSection(Systrace.kt:39)
at com.facebook.react.ReactActivityDelegate.onCreate(ReactActivityDelegate.java:118)
at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:47)
at com.vipr.app.MainActivity.onCreate(MainActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:9155)
at android.app.Activity.performCreate(Activity.java:9133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1521)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4262)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4467)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:222)
at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133)
at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loopOnce(Looper.java:248)
at android.os.Looper.loop(Looper.java:338)
at android.app.ActivityThread.main(ActivityThread.java:9067)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)
Environment:
- OS: Android 16 (API 36)
- Device/Emulator: Pixel 9 Pro
- React Native: 0.79.3
- react-native-bluetooth-state-manager: ^2.0.2
- NDK: 28.0.13004108
- Android gradle plugin: 8.8.2
- Gradle: 8.13
After updating the Android NDK to r28+ (e.g., 28.0.13004108), the app crashes on launch when loading libBluetoothStateManager.so from this module. The error is a runtime linking failure for the C++ exception handling symbol __cxa_init_primary_exception. This only reproduces on Android 15+ (API 35) devices/emulators with 16 KB page size enabled, which is now optional for performance but required for Play Store compliance starting Nov 1, 2025.
This seems related to ELF segment misalignment in the prebuilt .so files when using newer NDKs, as the library doesn't explicitly support flexible page sizes (e.g., via -Wl,-z,max-page-size=16384).
To Reproduce:
Expected behavior:
The native library loads successfully without unresolved symbols.
Actual behavior:
Fatal exception with the following log:
E FATAL EXCEPTION: main
Process: com.vipr.app, PID: 19376
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__cxa_init_primary_exception" referenced by "/data/app/~~yf1EFyj1CTVY4WOGvtQLQQ==/com.vipr.app-yOVskuWcmAcbI33GSX1VAQ==/base.apk!/lib/arm64-v8a/libBluetoothStateManager.so"...
at java.lang.Runtime.loadLibrary0(Runtime.java:1090)
at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
at java.lang.System.loadLibrary(System.java:1765)
at com.margelo.nitro.bluetoothstatemanager.BluetoothStateManagerPackage.(BluetoothStateManagerPackage.java:28)
at com.facebook.react.PackageList.getPackages(PackageList.java:114)
at com.vipr.app.MainApplication$reactNativeHost$1.getPackages(MainApplication.kt:23)
at com.facebook.react.ReactNativeHost.getBaseReactInstanceManagerBuilder(ReactNativeHost.java:112)
at com.facebook.react.ReactNativeHost.createReactInstanceManager(ReactNativeHost.java:85)
at com.facebook.react.ReactNativeHost.getReactInstanceManager(ReactNativeHost.java:57)
at com.facebook.react.ReactDelegate.loadApp(ReactDelegate.java:302)
at com.facebook.react.ReactActivityDelegate.loadApp(ReactActivityDelegate.java:156)
at com.facebook.react.ReactActivityDelegate.lambda$onCreate$0(ReactActivityDelegate.java:150)
at com.facebook.react.ReactActivityDelegate.$r8$lambda$HPdXfLmAU1y4Wc1XbwAHziPP2WA(Unknown Source:0)
at com.facebook.react.ReactActivityDelegate$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)
at com.facebook.systrace.Systrace.traceSection(Systrace.kt:39)
at com.facebook.react.ReactActivityDelegate.onCreate(ReactActivityDelegate.java:118)
at com.facebook.react.ReactActivity.onCreate(ReactActivity.java:47)
at com.vipr.app.MainActivity.onCreate(MainActivity.kt:21)
at android.app.Activity.performCreate(Activity.java:9155)
at android.app.Activity.performCreate(Activity.java:9133)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1521)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4262)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4467)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:222)
at android.app.servertransaction.TransactionExecutor.executeNonLifecycleItem(TransactionExecutor.java:133)
at android.app.servertransaction.TransactionExecutor.executeTransactionItems(TransactionExecutor.java:103)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:80)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2823)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loopOnce(Looper.java:248)
at android.os.Looper.loop(Looper.java:338)
at android.app.ActivityThread.main(ActivityThread.java:9067)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:593)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:932)
Environment: