Hi, I’m a bit surprised I missed your LLVM mailing list post, because I am the maintainer of the relevant clang code, as well as of libobjc2. If you had asked me earlier, I could have saved you a lot of time:
This test case works perfectly for me on FreeBSD, where clang defaults to -fobjc-runtime=gnustep. It segfaults if I add -fobjc-runtime=gcc. This is entirely expected, because the GCC ABI for exceptions is makes it impossible to correctly interop with C++ (I spent a few weeks trying and it always fails for at least some of the corner cases). If you specify -fobjc-runtime=gnustep-1.8, then it will work correctly. When using the GNUstep ABI, Objective-C objects are thrown as Objective-C exceptions, C++ objects are thrown as C++ exceptions. The GNUstep ObjC++ personality function is used for catch and @catch blocks in ObjC++ code, the ObjC personality function for @catch blocks in ObjC code, and the C++ personality function in C++ code. The C++ and ObjC personality functions don’t let you catch foreign exceptions (except for cleanups or with catch(…) in C++). The ObjC++ personality function checks whether the thrown exception is from C++ or ObjC. If it’s thrown from C++, it simply forwards it to the C++ personality function. If it’s thrown from ObjC, then it wraps it in a C++ exception first, and provides some special C++ type_info structures that allow the C++ personality function to deliver it to the correct block. This allows us to use a slightly more efficient code path for pure-ObjC exceptions. The Apple implementation simply implements the ObjC exceptions as thin wrappers around C++ exceptions, so ObjC exceptions are always thrown as C++ exceptions. This means that the Apple ObjC runtime has a hard dependency on their C++ runtime, even when not using ObjC++. This doesn’t matter too much for them, because a bunch of their core frameworks are C++ or ObjC++, so there’s likely not to be any code on macOS / iOS that uses ObjC but not C++. Note: We have tests for all of these cases in the libobjc2 test suite. There’s also some logic to allow foreign exceptions to be automatically boxed as ObjC objects. David > On 31 Oct 2017, at 20:13, Lobron, David <[email protected]> wrote: > > Hello GNUstep, > > I opened a bug with clang/llvm a few months ago when I found that > Objective-C++ programs compiled with clang on Linux were crashing with a > segmentation fault when the code attempted to catch a std::exception. The > crash only occurred when the code was compiled as Objective-C++ (i.e., with a > suffix of .mm). When compiled as C++, with a .cc suffix, the code works > correctly. The code to reproduce the bug is very simple and pure C++: > > #include <iostream> > > using namespace std; > > int main(int argc, char *argv[]) { > try { > throw exception(); > } catch (exception &e) { > } > > return 0; > } > > I worked on this with an llvm developer, and he reported the following: > > "I've investigated the issue further and discovered that the problem is with > personality routine. For C++ in my case it was > __cxxabiv1::__gxx_personality_v0. It returned _URC_HANDLER_FOUND and > correctly prepared everything to land in the catch block. > > For ObjC++ it was __gnu_objc_personality_v0 () from > /usr/lib/x86_64-linux-gnu/libobjc.so.4. In my case it returned > _URC_CONTINUE_UNWIND, so the exception wasn't caught in `main` and it caused > SIGABRT as any uncaught exception does. Personality routine is also > responsible for setting exception object for the catch block so it might be > causing NULL exception object you are observing." > > In my own tests, I'm using GNUStep libobjc2, version 1.8.1, which produces a > shared library called libobjc.so.4.6. My C++ binary has a different > personality from the ObjC++ binary: > > C++ (works): __gxx_personality_v0@@CXXABI_1.3 > ObjC++ (crashes): __gnu_objc_personality_v0 > > I checked for the string "personality" in libobjc2.so.4.6 using nm, and found > the following matching symbols: > > 000000000022e590 d DW.ref.__gcc_personality_v0 > 000000000022ff08 d DW.ref.__gnustep_objc_personality_v0 > U __gcc_personality_v0@@GCC_3.3.1 > 00000000000126b0 T __gnu_objc_personality_v0 > 0000000000012d20 T __gnustep_objc_personality_v0 > 0000000000012d60 T __gnustep_objcxx_personality_v0 > w __gxx_personality_v0 > 00000000000126f0 t internal_objc_personality > > I'm a bit suspicious of the "__gcc_personality_v0@@GCC_3.3.1" line, since I'm > compiling with clang rather than gcc. But that might be a red herring. > > The llvm/clang developers suggested I get in touch with GNUstep to see if > this is a known issue. Has anyone seen this behavior before? > > Thanks, > > David > > > > > > _______________________________________________ > Discuss-gnustep mailing list > [email protected] > https://lists.gnu.org/mailman/listinfo/discuss-gnustep _______________________________________________ Discuss-gnustep mailing list [email protected] https://lists.gnu.org/mailman/listinfo/discuss-gnustep
