[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Crash occurs when catching std::exception in Objective-C++ code comp
From: |
David Chisnall |
Subject: |
Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2 |
Date: |
Wed, 1 Nov 2017 08:25:33 +0000 |
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 <dlobron@akamai.com> 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
> Discuss-gnustep@gnu.org
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2,
David Chisnall <=
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/01
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/16
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, David Chisnall, 2017/11/16
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/16
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/16
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, David Chisnall, 2017/11/17
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/17
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, David Chisnall, 2017/11/17
- Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2, Lobron, David, 2017/11/17