Description
For some reason, std::exception_ptr is broken in react-native.
I have added this code to react-native/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp:
__android_log_print(ANDROID_LOG_ERROR, "EXCEPTION", "Running exception test...");
try {
throw std::runtime_error("Test exception");
} catch (...) {
auto eptr = std::current_exception();
try {
std::rethrow_exception(eptr);
} catch (const std::exception& e) {
__android_log_print(ANDROID_LOG_ERROR, "EXCEPTION", "Caught std::exception: %s", e.what());
} catch (...) {
__android_log_print(ANDROID_LOG_ERROR, "EXCEPTION", "Caught unknown exception!!");
}
}
And it logs
11-29 17:50:54.049 31176 31176 E EXCEPTION: Running exception test...
11-29 17:50:54.054 31176 31176 E EXCEPTION: Caught unknown exception!!
If you run the same code on iOS (replace log with NSLog), it works as expected:
11-29 17:50:54.049 31176 31176 E EXCEPTION: Running exception test...
11-29 17:50:54.054 31176 31176 E EXCEPTION: Caught std::exception: Test exception
So for some reason, the Android C++ lib fails to properly rethrow std::exception_ptr. ❌
iOS uses libc++ since ever.
Android uses libc++ since 2015, and apparently used libstdc++ (from GNU) before 2015 - could it be that libstdc++ is still used today somehow?
From what I'm seeing in RN's build.gradle, it correctly uses libc++: https://github.com/facebook/react-native/blob/91e217ff54e3bffb49454a723594d11669783e87/packages/react-native/ReactAndroid/build.gradle.kts#L535
Anyways... The code above does not work as expected. I think I read somewhere that exception_ptr does not work on ARMv5 since it needs some compare instruction that isn't available there, but afaik my device is ARMv8.
I have confirmed that;
- ✅ It works in a blank Android C++ app
- ✅ It works on iOS
- ❌ It fails in a blank react-native Android app
Steps to reproduce
- Create a clean new app (
npx create-expo-app@latest)
- Run
npx expo prebuild
- Enable "build react-native from source" (by following these instructions)
- Add the above code to
OnLoad.cpp
- Run
npx expo android
- In adb, see exception_ptr not properly being castable
React Native Version
0.76.2
Affected Platforms
Runtime - Android
Output of npx react-native info
info Fetching system and libraries information...
System:
OS: macOS 15.0.1
CPU: (12) arm64 Apple M2 Pro
Memory: 240.17 MB / 32.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.18.0
path: ~/.nvm/versions/node/v18.18.0/bin/node
Yarn:
version: 1.22.19
path: ~/.nvm/versions/node/v18.18.0/bin/yarn
npm:
version: 10.8.1
path: ~/.nvm/versions/node/v18.18.0/bin/npm
Watchman:
version: 2024.11.11.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.1
- iOS 18.1
- macOS 15.1
- tvOS 18.1
- visionOS 2.1
- watchOS 11.1
Android SDK:
API Levels:
- "28"
- "30"
- "31"
- "33"
- "33"
- "34"
- "35"
Build Tools:
- 30.0.3
- 31.0.0
- 33.0.0
- 33.0.1
- 33.0.2
- 34.0.0
- 34.0.0
- 35.0.0
System Images:
- android-33 | Google APIs ARM 64 v8a
- android-34 | Google Play ARM 64 v8a
Android NDK: 25.2.9519653
IDEs:
Android Studio: 2024.2 AI-242.23339.11.2421.12550806
Xcode:
version: 16.1/16B40
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.13
path: /opt/homebrew/opt/openjdk@17/bin/javac
Ruby:
version: 2.7.6
path: /Users/mrousavy/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 15.1.2
wanted: ^15.1.2
react:
installed: 18.3.1
wanted: 18.3.1
react-native:
installed: 0.76.3
wanted: 0.76.3
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
11-29 17:50:54.049 31176 31176 E EXCEPTION: Running exception test...
11-29 17:50:54.054 31176 31176 E EXCEPTION: Caught unknown exception!!
Reproducer
https://github.com/mrousavy/react-native-exception_ptr-bug
Screenshots and Videos
No response
Description
For some reason,
std::exception_ptris broken in react-native.I have added this code to
react-native/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp:And it logs
If you run the same code on iOS (replace log with
NSLog), it works as expected:So for some reason, the Android C++ lib fails to properly rethrow
std::exception_ptr. ❌iOS uses libc++ since ever.
Android uses libc++ since 2015, and apparently used libstdc++ (from GNU) before 2015 - could it be that libstdc++ is still used today somehow?
From what I'm seeing in RN's
build.gradle, it correctly uses libc++: https://github.com/facebook/react-native/blob/91e217ff54e3bffb49454a723594d11669783e87/packages/react-native/ReactAndroid/build.gradle.kts#L535Anyways... The code above does not work as expected. I think I read somewhere that
exception_ptrdoes not work on ARMv5 since it needs some compare instruction that isn't available there, but afaik my device is ARMv8.I have confirmed that;
Steps to reproduce
npx create-expo-app@latest)npx expo prebuildOnLoad.cppnpx expo androidReact Native Version
0.76.2
Affected Platforms
Runtime - Android
Output of
npx react-native infoStacktrace or Logs
Reproducer
https://github.com/mrousavy/react-native-exception_ptr-bug
Screenshots and Videos
No response