Repository navigation
C++ STL Library on Android does not support exception_ptr #48027
Description
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
Activity
react-native-bot commentedon Nov 29, 2024
Warning
Could not parse version: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.
react-native-bot commentedon Nov 29, 2024
Warning
Could not parse version: We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.76.2.
mrousavy commentedon Nov 29, 2024
The
CMakeLists.txtof the project where I added the code toOnLoad.cppto also enables exceptions: https://github.com/facebook/react-native/blob/91e217ff54e3bffb49454a723594d11669783e87/packages/react-native/ReactAndroid/src/main/jni/react/jni/CMakeLists.txt#L11-L14I also added
-frttito those options and rebuilt the app, but it still doesn't work.[-]C++ STL Library used does not support `exception_ptr`[/-][+]C++ STL Library on Android does not support `exception_ptr`[/+]NickGerleman commentedon Nov 30, 2024
Nope. We are using libc++. When we bumped to NDK 26, this got bumped to LLVM 17. IIRC latest beta NDK uses libc++ based on LLVM 19.
All of the build logic we control should also have RTTI enabled I think. I could imagine weirdness happening if a library is using static STL, and RN is using shared STL (so we have different copies of exception types/ODR issues), or if NDK is setting some special flags that XCode isn't. IIRC libc++ had some different ways of being able to implement RTTI, which we do not fuss with ourselves.
mrousavy commentedon Dec 2, 2024
hm, I can't seem to pinpoint it. It's definitely broken in a blank app created with the expo 52 template bootstrapper.
cortinico commentedon Dec 3, 2024
@mrousavy have you tried on a vanilla Android App without React Native?
mrousavy commentedon Dec 3, 2024
@cortinico Yep, in a blank new Android C++ template it works:
cortinico commentedon Dec 3, 2024
We would have to diff the compilation flag you're using for your
native-lib.cppvs the one used for React Native OnLoad.cpp file. The latter are listed here: https://github.com/facebook/react-native/blob/67bff8734f4b92fe399910eecad5b67511a749c1/packages/react-native/ReactAndroid/cmake-utils/ReactNative-application.cmake#L53-L6757 remaining items
Enable RTTI to fix exception pointer issue on React Native
cortinico commentedon Mar 4, 2025
This should now be fixed with today's nightly @mrousavy please check and let me know if the issue is resolved
Enable RTTI to fix exception pointer issue on React Native (react#1791)
mrousavy commentedon Mar 4, 2025
exciting!! I'll try this thank you so much
Ashoat commentedon May 5, 2025
Is there any patch we can apply to get around this issue for current versions of React Native? In our case, our code for catching exceptions in C++ is broken on Android, and it looks like to use the patch we'd need to update our project to build React Native / Yoga from source on Android, or publish and use our own artifacts.
ospfranco commentedon May 5, 2025
@Ashoat You need to catch the generic std::runtime_error and std::exception
https://github.com/OP-Engineering/op-sqlite/blob/main/cpp/DBHostObject.cpp#L313
cortinico commentedon May 6, 2025
Nope that's not easily backportable because of how complex the fix was
cortinico commentedon May 6, 2025
@Ashoat actually, the fix itself is sort of trivial. The problem is that it needs to be applied on top of 0.79 and I suspect it won't work well on other versions of RN
Ashoat commentedon May 6, 2025
If a patch version of 0.79 could be released with this fix, that would be amazing! Or alternately, if there's a simple patch you can share that works with 0.79 (ie. doesn't require building React Native for Android from source) that would be good too.
cortinico commentedon May 6, 2025
Nope there is no patch that won't require building from source, because this has to do to how our native C++ code is precompiled. We'll have to potentially cherry-pick it inside 0.79 but is going to be a stack of several commits so not really easy
Ashoat commentedon Jun 2, 2025
Hey @cortinico, was great seeing your talk at App.js this last week! Wanted to check on this issue, if there's any chance of patching this in React Native 0.79, or alternately if there's a React Native 0.80 coming soon that will be compatible with Expo 53. Ultimately we're blocked on upgrading due to this, so would be great to have a path forward. Hope you're doing well :)
cortinico commentedon Jun 2, 2025
This is coming in 0.80 that will be shipped sometime in the immediate future (trust me :))
As mentioned, it's a bit of a pain to backport in a patch release as it could break compatibilities with codegen libraries (as we're modifying the template here).
Enable RTTI to fix exception pointer issue on React Native
Enable RTTI to fix exception pointer issue on React Native
trcrsired commentedon Sep 6, 2026
just ban C++ EHs. C++EH is a mistake