-
Notifications
You must be signed in to change notification settings - Fork 257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C++ exceptions are aborting the process, even if caught #289
Comments
I was able to get a stack trace:
|
Removing the link to
|
Haven't been able to look closely at this yet, but hopefully will find some time to this week. |
This is an area where I woefully lack any expertise but from what I've been able to figure out the throw call is somehow generating an encoded pointer that is not supported by libc++abi. I still am not ruling out something that I've set up badly. It troubles me that things are going through hand coded GCC based assembly for throwing exceptions, but maybe that was the point of libc++abi (to be able to have other logics be called and then sent back for analysis?) Let me know if there is other places I can check out, because I'm at an impasse as to what to do further to figure out this odd problem. |
One more thing that might be noteworthy: I have installed logic to log backtraces on Android. Although this path doesn't get called during the test in question, if I remove this logic and the calls to
|
Is there anything I can do to figure this out more? Stuff I should look for? I'd really like to get this sorted out. |
Sorry, I haven't had a chance to look at this yet. |
(saw the email thread pinged, so figured I'd leave another update) Still haven't looked in to this. Just to give people an idea of how things work, I've had to focus on getting r14 out the door for a while now. That's shipping any time now, at which point I need to prioritize getting the feature for r15 (stabilizing libc++ as much as possible) done before I can really look at other bugs. The time between beta 1 and beta 2 is when I usually look in to bugs like this. |
Wouldn't this be considered part of stabilizing libc++? Anyway I thought I'd update that r14 still has this issue for me. |
This needs to be fixed ASAP. I'm having the same problem here... |
@borrrden: readelf on your libraries shows they were built improperly: $ readelf -sW libsqlite3.so | grep _Unwind | grep UND
319: 00000000 0 FUNC WEAK DEFAULT UND __gnu_Unwind_Find_exidx
2841: 00000000 0 FUNC WEAK DEFAULT UND __gnu_Unwind_Find_exidx
$ readelf -sW libLiteCore.so | grep _Unwind | grep UND
6: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume
1437: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Backtrace
1438: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_VRS_Get
2567: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_DeleteException
2568: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_VRS_Set
2571: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_RaiseException
2573: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_GetRegionStart
2574: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_GetLanguageSpecificData
23472: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume
24903: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Backtrace
24904: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_VRS_Get
26033: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_DeleteException
26034: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_VRS_Set
26037: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_RaiseException
26039: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_GetRegionStart
26040: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_GetLanguageSpecificData
$ readelf -sW C4Tests | grep _Unwind | grep UND
7: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume
4344: 00000000 0 FUNC GLOBAL DEFAULT UND _Unwind_Resume No linked binary should ever have undefined references to pieces of the unwinder. When this happens, the two unwinders in play on arm7 (the LLVM unwinder that works for exception handling with libc++ and libgcc) can both end up being half used, and the two are not ABI compatible. I'm guessing this is a cmake issue, but I need to dig a bit deeper and can't do that while my machine is busy running tests. Will get back to it in a bit. |
Adding
It would probably be smart for us to add |
@borrrden: looking at the build files ( |
Do you mean it is required to use the version of CMake that comes with the NDK, or that I should manually specify a build toolchain? The CMake website says differently, it just indicates these instructions. I'm happy to try out a different way of building, though. Here is the exact script from the build server (the one you linked to is similar and what my colleague is experimenting with until we can get a shared cmake build between Xamarin Android and regular Android)
.. Switching this to gnustl_static is what we are doing for our workaround. We've had other issues with it before (incomplete C++ 11 support, etc) but for now it is working enough for our tests to pass. |
Following your build instructions, I still get complaints about it not finding sqlite headers. I assume I'm not actually supposed to apt-get those, because that would be a Linux package and not an Android one...
Not the cmake binary that comes in the NDK (there isn't one), but we only support the CMake toolchain file that we provide. It's in This is the only CMake process that I have control over. CMake started shipping their own incompatible Android support after we shipped ours, and it's beyond our control. Based on this bug, it looks like their support has bugs. I'd recommend giving ours a shot and see if that works. Note that because of CMake's own incompatible solution, you actually need CMake 3.6 and not 3.7 for this to work (see #254). If it turns out that it does work with our toolchain file and you want to go back to the stock CMake support, you'll want to file a bug against CMake. |
Sorry about the difficulty building! That header should be included in a submodule on the repo, but your explanation sounds reasonable so I will give it a shot. I can't imagine it will take more than an hour or two to try it out. |
Installing from apt didn't fix this, so it seems I was right on that.
Yeah, it's definitely there, it's just not being included in the build.
Okay, I'll wait for your response rather than simultaneously hammering on it :) |
FYI, I switched to CMake 3.6 and changed the build invocation to:
But the above unwind stuff is still undefined. |
Same result from the above, unfortunately. |
Hmm. I'm going to need to take a closer look then. (Figured out my build problem. |
Here are some samples of the compiler commands that are getting executed from the Makefile by the way: sqlite3.c
BlobStore.cc
libLiteCoreStatic.a linking
libLiteCore.so linking
C4Tests linking
|
Thanks, that actually helps a lot!
Tough to say if this is the problem, but there's definitely a problem here. Right in the middle: you have libsqlite3.so being linked before some static libraries. Linking needs to happen in the following order or things go wrong:
2 includes the STL and libgcc/libatomic/etc, assuming those are static (as is the case here). As you can see the STL static libraries are actually being linked at the end (can't say where libgcc is being linked since it's not The problem that happens is that sqlite3.so will have libgcc linked into it. When the objects ahead of them are linked, they'll use the re-exported libgcc symbols from libsqlite rather than getting their own copy. Afterwards you get the libc++ stuff linked, which is using a different unwinder. When things are built correctly each linked binary has a full (and hidden!) copy of the unwinder it was built against, so any unwind beginning in that code will use exactly the unwinder it was built against. The next question is whether this incorrect behavior stems from cmake itself or your build files. I don't see anything suspicious in your build files so I'm tempted to say the former, but it will take more experimenting to be sure. One thing you might try: add |
Hey, what do you know...it stopped crashing when I added those, and also the undefined unwind stuff is down to just two things:
|
Oh, and the exclude libunwind.a is added by default by the cmake toolchain (but not libgcc.a) |
I'm facing above problem with current(v.17) NDK. |
Solid bug report 👍 $ readelf -sW android-ndk-r17/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_shared.so | grep _Unw | head
179: 0009bffc 42 FUNC GLOBAL DEFAULT 12 _Unwind_Resume
197: 0009b8d5 2 FUNC GLOBAL DEFAULT 12 _Unwind_Complete
198: 0009b8d7 16 FUNC GLOBAL DEFAULT 12 _Unwind_DeleteException
223: 0009c3c1 6 FUNC GLOBAL DEFAULT 12 _Unwind_GetDataRelBase
224: 0009c3c7 6 FUNC GLOBAL DEFAULT 12 _Unwind_GetTextRelBase
225: 0009c3a5 10 FUNC GLOBAL DEFAULT 12 _Unwind_GetRegionStart
226: 0009b931 52 FUNC GLOBAL DEFAULT 12 _Unwind_VRS_Set
227: 0009c3af 18 FUNC GLOBAL DEFAULT 12 _Unwind_GetLanguageSpecificData
228: 0009b8e7 52 FUNC GLOBAL DEFAULT 12 _Unwind_VRS_Get
255: 0009bfd0 42 FUNC GLOBAL DEFAULT 12 _Unwind_RaiseException So gnustl exposes its unwinder. It's a little odd that that would be causing a problem though unless one of your libraries is also using libc++. The reason the unwind symbols need to be hidden is so that they behave correctly in the event that there is more than one unwinder being used in the application. This is the common case with libc++ on Android ARM because we use LLVM's unwinder for libc++ on ARM, but still use libgcc to provide compiler runtime support. Unfortunately libgcc also includes an unwinder, and the two clash. This shouldn't be an issue so long as gnustl is the only STL in your application, since it only uses libgcc. If your app is using both gnustl and libc++, that's your problem. That's more or less always expected to have bugs. There's one other case that could explain this, especially if you're seeing this on r17 but not r16: if you're using RTTI/exceptions and also using the system STL (i.e. bionic's libstdc++, |
@DanAlbert sorry, I still don't get it. Both prebuilt libraries are mine. And they both compiled with |
please look at my readelf output
So real questions are: Why Unwind* functions records doubled? How to make them hidden and copied in so? |
It shouldn't matter for gnustl, but you can use |
I believe I have the same problem, only in my case I'm linking with c++_shared instead of static The symbols might be coming from libQt5Core.so, which I'm linking against: I tried linking with -Wl,--exclude-libs,libQt5Core.so but no luck. |
|
@cristiterpea @DanAlbert I found some version of NDK will not append
|
I strongly recommend against r11 and r12. r17 is what you should be using, r16 if r17 has a bug you can't work around. |
Why is it only needed on that arch? We build for arm32 and and aarch64 and indeed, it doesn't happen on aarch64. But why? |
I am using ndk-r10e and building the native code. The code is running fine in arm-v7 but it is crashing in arm64 when native tries to throw the exception. |
please try again with r21. we can't fix the past. |
Hello, I have updated the NDK version to r21 but still facing the same issue (as the app is crashing when the .so native library throwing an exception). To simulate the issue I have created a sample app which I am attaching with this comment and below are the steps mentioned to reproduce the issue-
Someone please help to get the issue resolved. |
Your repro case isn't using a valid STL. After fixing the repro script and converting it to bash:
If I fix that, Studio gives:
If you can provide a working sample I'll look more. I strongly recommend migrating your build to https://developer.android.com/studio/projects/gradle-external-native-builds. Using that will cut down on a lot of the "works on my machine" issues. |
Hello DanAlbert, |
updated the NDK version to r26c but still facing the same issue (as the app is crashing when the .so native library throwing an exception). |
We can't help without a repro case. If you upload the new one we might be able to do something. Please file a new bug when you do. This thread now has at least three different reports in it, and any more than one is really hard to follow (not to mention spams a bunch of people that aren't interested in the new reports). |
Description
The setup is slightly complicated but I am using command line CMake (Android Studio not involved) to compile a native library that I need to then test. For simplicity sake, and since CMake already outputs a native test runner executable anyway, I simply upload it to an arbitrary directory and run it via
adb shell
. However, some of the unit tests will try and catch exceptions. On arm and arm64 this causes the process to abort instead of throwing an exception which is then caught. This sounds like exceptions are disabled, but I have confirmed many times that-fexceptions
is present during compilation. Furthermore the__cpp_exceptions
compiler directive is present. This only seems to happen when using clang and libc++ (Which we must use for other reasons). libstdc++ does not exhibit the same behavior, and neither does NDK r11c. The output from the test runner is as follows:vs. on x86
The build is as follows:
Several static libs are linked together into one shared lib, which is linked to libsqlite3.so (which is also built to comply with new Android rules) and then an executable is built which links to both of those
The big shared lib has a C interface which will catch any exceptions before they bubble past it and store the details into an error variable or ignore them and return a generic error state. This is where the exception is thrown (and supposed to be caught) during the crashing test runner.
The source for the shared library being built is here and the unit test runner in question is here. The latest commit as of this writing is
3aeb671
.Here are the build artifacts for armv7 zipped -> C4Tests.zip and the steps to reproduce are:
adb mkdir -p /data/local/tmp/LiteCore
adb push *.so C4Tests /data/local/tmp/LiteCore
adb shell
cd /data/local/tmp/LiteCore
export TMPDIR=/data/local/tmp
export LD_LIBRARY_PATH=/data/local/tmp/LiteCore
./C4Tests "parse invalid blob keys"
Environment Details
Not all of these will be relevant to every bug, but please provide as much
information as you can.
The text was updated successfully, but these errors were encountered: