[cfe-dev] Exception handling with RTTI disabled on macOS
Ilia K via cfe-dev
cfe-dev at lists.llvm.org
Tue Jan 26 07:25:39 PST 2021
Hi!
It turned out that I cannot catch `std::bad_alloc&` thrown by the `operator
new` when compiling 1.cpp with -fno-rtti and linking against system's
libc++.1.dylib/libc++abi.dylib on macOS. This scenario works on Linux, and
according to the official libc++ page it is supported ("However linking
against it with -fno-rtti is supported", https://libcxx.llvm.org/), however
the following code is aborted due to an unhandled exception:
```1.cpp
#include <cstdio>
#include <new>
int main() {
try {
::operator new(-1);
} catch (std::bad_alloc& e) {
printf("caught %s\n", e.what());
}
return 0;
}
```
Compile & run:
```
$ clang++ -fno-rtti 1.cpp -o 1_no_rtti
$ ./1_no_rtti
libc++abi.dylib: terminating with uncaught exception of type
std::bad_alloc: std::bad_alloc
Abort trap: 6
```
I know about similar issues with exceptions when -fno-rtti on macOS
(Polymorphically catching an exception in a -fno-rtti shared library on Mac
OS X
https://stackoverflow.com/questions/3638237/polymorphically-catching-an-exception-in-a-fno-rtti-shared-library-on-mac-os-x,
Problems throwing and catching exceptions on OS X with -fno-rtti
https://stackoverflow.com/questions/21737201/problems-throwing-and-catching-exceptions-on-os-x-with-fno-rtti).
There was an issue in Android NDK with exceptions when -flto=thin and it
was said that "The problem is that we have multiple copies of a symbol,
where one of them is strong, and the others are linkonce_odr"
https://github.com/android/ndk/issues/1046#issuecomment-514469559 (fixed
now https://reviews.llvm.org/D61255).
Can anyone shed some light on it? It seems like a bug at the moment, and if
your code uses any of libc++.1.dylib/libc++abi.dylib system libraries on
macOS, you must leave RTTI enabled, except you have turned exceptions off
as well.
FYI, the difference between non-RTTI (./1_no_rtti) and the default
(./1_rtti, with RTTI) Mach-O executables:
```
$ diff <(nm -C 1_no_rtti) <(nm -C 1_rtti)
1c1
< 0000000100003f48 s GCC_except_table0
---
> 0000000100003f68 s GCC_except_table0
4,9c4
< 0000000100004028 S typeinfo for std::bad_alloc
< 0000000100004018 S typeinfo for std::exception
< 0000000100003f74 S typeinfo name for std::bad_alloc
< 0000000100003f81 S typeinfo name for std::exception
< U vtable for __cxxabiv1::__class_type_info
< U vtable for __cxxabiv1::__si_class_type_info
---
> U typeinfo for std::bad_alloc
11c6
< 0000000100003ed0 t ___clang_call_terminate
---
> 0000000100003ef0 t ___clang_call_terminate
17c12
< 0000000100003e20 T _main
---
> 0000000100003e40 T _main
$ diff <(clang++ -fno-rtti 1.cpp -S -o -) <(clang++ 1.cpp -S -o -)
143,169d142
< .section __TEXT,__const
< .globl __ZTSSt9bad_alloc ## @_ZTSSt9bad_alloc
< .weak_definition __ZTSSt9bad_alloc
< __ZTSSt9bad_alloc:
< .asciz "St9bad_alloc"
<
< .globl __ZTSSt9exception ## @_ZTSSt9exception
< .weak_definition __ZTSSt9exception
< __ZTSSt9exception:
< .asciz "St9exception"
<
< .section __DATA,__const
< .globl __ZTISt9exception ## @_ZTISt9exception
< .weak_definition __ZTISt9exception
< .p2align 3
< __ZTISt9exception:
< .quad __ZTVN10__cxxabiv117__class_type_infoE+16
< .quad __ZTSSt9exception
<
< .globl __ZTISt9bad_alloc ## @_ZTISt9bad_alloc
< .weak_definition __ZTISt9bad_alloc
< .p2align 3
< __ZTISt9bad_alloc:
< .quad __ZTVN10__cxxabiv120__si_class_type_infoE+16
< .quad __ZTSSt9bad_alloc
< .quad __ZTISt9exception
<
```
Linked issues: https://reviews.llvm.org/D46665,
https://reviews.llvm.org/D47092,
https://reviews.llvm.org/rG2405bd6898151e0a7ffede78b0d0c7c85c0b66d3,
https://github.com/Amanieu/asyncplusplus/commit/2360c8993951afab67ab0414288dacae1dbd7195
--
- Ilia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210126/132d5b8c/attachment.html>
More information about the cfe-dev
mailing list