Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
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
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
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 <[hidden email]> 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
> [hidden email]
> https://lists.gnu.org/mailman/listinfo/discuss-gnustep


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
Thanks very much, David- this is extremely helpful!  As you might expect, my code was running perfectly on the Mac, but crashing on Linux- this explains both.

Just to make sure I understand, can you tell me exactly where to specify -fobjc-runtime=gnustep-1.8?  Would that be an argument when building llvm/clang, or libobjc2, or both?

Thank you,

David

> On Nov 1, 2017, at 4:25 AM, David Chisnall <[hidden email]> wrote:
>
> 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 <[hidden email]> 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
>> [hidden email]
>> https://lists.gnu.org/mailman/listinfo/discuss-gnustep
>

_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 1 Nov 2017, at 14:11, Lobron, David <[hidden email]> wrote:
>
> Thanks very much, David- this is extremely helpful!  As you might expect, my code was running perfectly on the Mac, but crashing on Linux- this explains both.
>
> Just to make sure I understand, can you tell me exactly where to specify -fobjc-runtime=gnustep-1.8?  Would that be an argument when building llvm/clang, or libobjc2, or both?

When building your ObjC++ code (and, ideally, when building GNUstep and all of your ObjC code).  The libobjc2 build system ought to be setting it (it might not, but I think it does if the compiler is clang).

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
In reply to this post by David Chisnall
Hi David and gnustep,

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.

I updated my gnustep-make (version 2.6.0) to include -fobjc-runtime=gnustep-1.8 in ADDITIONAL_FLAGS, with the following change to common.make:

728a729,732
> # Specify the gnustep-1.8 runtime so we pick up the correct exception personalities
> # in ObjCC.
> ADDITIONAL_FLAGS += -fobjc-runtime=gnustep-1.8 

This works as expected, as this sample compilation line that has the -fobjc-runtime=gnustep-1.8 flag:

/home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang++ ResourceAdditions.mm -c \
      -MMD -MP -idirafter /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ext -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1 -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -fPIC -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -fobjc-runtime=gnustep-1.8 -mfpmath=sse -msse2 -fno-strict-aliasing -Wall -Werror -Wno-multichar -DHAVE_CONFIG_H -D_GNU_SOURCE -m64 -march=opteron -mno-3dnow -ggdb -O2 -Wall -fPIC -fPIC -fgnu-runtime -std=c++11 -fconstant-string-class=NSConstantString -I ../common/include -I. -I/home/dlobron/GNUstep/Library/Headers -I/home/dlobron/build/clangport/akamai/common/GNUstep/Local/Library/Headers -I/home/dlobron/build/clangport/akamai/common/GNUstep/System/Library/Headers

However, I'm still getting the same result: C++ exception objects are nil when caught in Objective-C++ code (.mm files).  As I mentioned, I'm using libobjc2 and building with clang.  This error does not occur when I build with gcc, nor with clang on a Mac - only clang on Linux.

Is it possible that some key part of my compilation is missing -fobjc-runtime=gnustep-1.8?  It appears everywhere I can think to look, and ADDITIONAL_FLAGS does seem like the right place to put it.  Please let me know if there is something else I might check.  I did notice that the flag "-fgnu-runtime" appears in my compilation line - could that value be incorrect?

Thank you,

David

_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 16 Nov 2017, at 20:50, Lobron, David <[hidden email]> wrote:

>
> Hi David and gnustep,
>
>> 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.
>
> I updated my gnustep-make (version 2.6.0) to include -fobjc-runtime=gnustep-1.8 in ADDITIONAL_FLAGS, with the following change to common.make:
>
> 728a729,732
> > # Specify the gnustep-1.8 runtime so we pick up the correct exception personalities
> > # in ObjCC.
> > ADDITIONAL_FLAGS += -fobjc-runtime=gnustep-1.8
>
> This works as expected, as this sample compilation line that has the -fobjc-runtime=gnustep-1.8 flag:
>
> /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang++ ResourceAdditions.mm -c \
>       -MMD -MP -idirafter /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/ext -DGNUSTEP -DGNUSTEP_BASE_LIBRARY=1 -DGNU_RUNTIME=1 -DGNUSTEP_BASE_LIBRARY=1 -fno-strict-aliasing -fPIC -Wall -DGSWARN -DGSDIAGNOSE -Wno-import -fobjc-runtime=gnustep-1.8 -mfpmath=sse -msse2 -fno-strict-aliasing -Wall -Werror -Wno-multichar -DHAVE_CONFIG_H -D_GNU_SOURCE -m64 -march=opteron -mno-3dnow -ggdb -O2 -Wall -fPIC -fPIC -fgnu-runtime -std=c++11 -fconstant-string-class=NSConstantString -I ../common/include -I. -I/home/dlobron/GNUstep/Library/Headers -I/home/dlobron/build/clangport/akamai/common/GNUstep/Local/Library/Headers -I/home/dlobron/build/clangport/akamai/common/GNUstep/System/Library/Headers
>
> However, I'm still getting the same result: C++ exception objects are nil when caught in Objective-C++ code (.mm files).  As I mentioned, I'm using libobjc2 and building with clang.  This error does not occur when I build with gcc, nor with clang on a Mac - only clang on Linux.
>
> Is it possible that some key part of my compilation is missing -fobjc-runtime=gnustep-1.8?  It appears everywhere I can think to look, and ADDITIONAL_FLAGS does seem like the right place to put it.  Please let me know if there is something else I might check.  I did notice that the flag "-fgnu-runtime" appears in my compilation line - could that value be incorrect?

-fgnu-runtime is long-deprecated, and I’m not sure what happens if it’s specified *after* -fobjc-runtime=.  It may override it (and default to an earlier runtime target).  It’s probably best to remove it.

Did you run the libobjc2 tests (which include a test for C++ exceptions in Objective-C++), and did they pass?

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David

> -fgnu-runtime is long-deprecated, and I’m not sure what happens if it’s specified *after* -fobjc-runtime=.  It may override it (and default to an earlier runtime target).  It’s probably best to remove it.
>
> Did you run the libobjc2 tests (which include a test for C++ exceptions in Objective-C++), and did they pass?

I had been building libobjc2 with tests disabled.  I removed the disable flag, and tried to compile again.  I'm finding that the compilation now fails, and the errors seem a bit telling, because they concern exception personalities.  The errors are very similar:

make[4]: Entering directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o[ 55%] Building C object Test/CMakeFiles/BlockImpTest.dir/BlockImpTest.m.o
: In function `throw_int':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x13): undefined reference to `__cxa_allocate_exception'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x1b): undefined reference to `typeinfo for int'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x3b): undefined reference to `__cxa_throw'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o: In function `catchall':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x65): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x78): undefined reference to `__cxa_rethrow'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x8b): undefined reference to `__cxa_end_catch'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o: In function `__clang_call_terminate':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x9): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o:(.eh_frame+0x47): undefined reference to `__gxx_personality_v0'
Scanning dependencies of target CXXExceptions_optimised
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

And also:

CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `throw_int':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x7): undefined reference to `__cxa_allocate_exception'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x12): undefined reference to `typeinfo for int'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x1c): undefined reference to `__cxa_throw'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `catchall':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x2c): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x3b): undefined reference to `__cxa_rethrow'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x43): undefined reference to `__cxa_end_catch'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `__clang_call_terminate':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x2): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x7): undefined reference to `std::terminate()'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o:(.eh_frame+0x3f): undefined reference to `__gxx_personality_v0'
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

I enabled messages=yes in my build, but I don't see the compilation commands - I'm trying now to get those.  Do these errors indicate where the problem might lie?

Thank you again for your help here.

--David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
In reply to this post by David Chisnall
I did a verbose build of libobjc2.  The compilation line for CXXException.cc looks like this:

[ 48%] Building CXX object Test/CMakeFiles/CXXExceptions.dir/CXXException.cc.o
cd /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test && /usr/bin/clang  -DGC_DEBUG -DGNUSTEP -DNO_LEGACY -DTYPE_DEPENDENT_DISPATCH -D_BSD_SOURCE=1 -D_XOPEN_SOURCE=700 -D__BSD_VISIBLE=1 -D__OBJC_RUNTIME_INTERNAL__=1 -I/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1  -fobjc-runtime=gnustep-1.7 -fblocks -O0 -o CMakeFiles/CXXExceptions.dir/CXXException.cc.o -c /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc

I noticed that -fobjc-runtime is set to gnustep-1.7 rather than gnustep-1.8.  Could that be the problem?

This line also seemed suspicious:

/home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXExceptions.dir/CXXException.m.o CMakeFiles/CXXExceptions.dir/CXXException.cc.o  -o CXXExceptions -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6

Could the gnu99 or -fexceptions be the problem?

I've copied all the lines leading up to the error below.  CXXException.cc seems to be the source of the error, which seems very suggestive.

Thank you again for the help here!

--David

make -f Test/CMakeFiles/BlockImpTest.dir/build.make Test/CMakeFiles/BlockImpTest.dir/depend
make[4]: Leaving directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
make -f Test/CMakeFiles/Forward_optimised.dir/build.make Test/CMakeFiles/Forward_optimised.dir/build
make[4]: Entering directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
cd /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build && /home/dlobron/build/clangport/akamai/common/bin/cmake -E cmake_depends "Unix Makefiles" /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1 /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/BlockImpTest.dir/DependInfo.cmake --color=
make[4]: Entering directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
make[4]: Entering directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
Dependee "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/NestedExceptions.dir/DependInfo.cmake" is newer than depender "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/NestedExceptions.dir/depend.internal".
Dependee "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/NestedExceptions.dir/depend.internal".
Scanning dependencies of target NestedExceptions
make[4]: Leaving directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
make -f Test/CMakeFiles/NestedExceptions.dir/build.make Test/CMakeFiles/NestedExceptions.dir/build
CMakeFiles/CXXExceptions.dir/CXXException.cc.o: In function `throw_int':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x13): undefined reference to `__cxa_allocate_exception'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x1b): undefined reference to `typeinfo for int'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x3b): undefined reference to `__cxa_throw'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o: In function `catchall':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x65): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x78): undefined reference to `__cxa_rethrow'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x8b): undefined reference to `__cxa_end_catch'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o: In function `__clang_call_terminate':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0xDependee "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/BlockImpTest.dir/DependInfo.cmake" is newer than depender "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/BlockImpTest.dir/depend.internal".
Dependee "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/CMakeDirectoryInformation.cmake" is newer than depender "/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test/CMakeFiles/BlockImpTest.dir/depend.internal".
Scanning dependencies of target BlockImpTest
[ 53%] Building C object Test/CMakeFiles/Forward_optimised.dir/Forward.m.o
make[4]: Entering directory `/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build'
9): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x12): undefined reference to `std::terminate()'
CMakeFiles/CXXExceptions.dir/CXXException.cc.o:(.eh_frame+0x47): undefined reference to `__gxx_personality_v0'
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 16 Nov 2017, at 21:41, Lobron, David <[hidden email]> wrote:
>
> I did a verbose build of libobjc2.  The compilation line for CXXException.cc looks like this:
>
> [ 48%] Building CXX object Test/CMakeFiles/CXXExceptions.dir/CXXException.cc.o
> cd /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test && /usr/bin/clang  -DGC_DEBUG -DGNUSTEP -DNO_LEGACY -DTYPE_DEPENDENT_DISPATCH -D_BSD_SOURCE=1 -D_XOPEN_SOURCE=700 -D__BSD_VISIBLE=1 -D__OBJC_RUNTIME_INTERNAL__=1 -I/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1  -fobjc-runtime=gnustep-1.7 -fblocks -O0 -o CMakeFiles/CXXExceptions.dir/CXXException.cc.o -c /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc
>
> I noticed that -fobjc-runtime is set to gnustep-1.7 rather than gnustep-1.8.  Could that be the problem?

No, that’s fine - there are no compiler changes between 1.7 and 1.8, it’s just good practice to keep the flag and the runtime version in sync.

> This line also seemed suspicious:
>
> /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXExceptions.dir/CXXException.m.o CMakeFiles/CXXExceptions.dir/CXXException.cc.o  -o CXXExceptions -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6
>
> Could the gnu99 or -fexceptions be the problem?

Nope, gnu99 is a perfectly acceptable C dialect (the tests don’t use any C11 features yet) and you definitely want -fexceptions to make sure that exceptions are enabled!

>
> I've copied all the lines leading up to the error below.  CXXException.cc seems to be the source of the error, which seems very suggestive.

It seems to be missing the linker command line for building the CXXException test.  It’s probably worth taking a step back at this point:

On Linux platforms, it’s common to provide libsupc++ (the GNU C++ runtime library) statically linked into libstdc++ (the GNU C++ standard library).  This is somewhat awkward, because this means that the only way to use symbols in libsupc++ is to add a dependency on libstdc++.  I’ve tried to avoid that for libobjc, because libstdc++ is a big library and is completely unused for pure Objective-C programs.

On FreeBSD, we ship libcxxrt (the BSD C++ runtime, which I wrote) as a separate .so and link both libstdc++ and libc++ (the LLVM C++ standard library) to it dynamically, so we can support programs linked to both.  This means that on FreeBSD we ship libobjc.so dynamically linked to libcxxrt.so, and that doesn’t add much to the dependency footprint for any Objective-C project.

By default, the libobjc CMake build looks for libcxxrt.so or libsupc++.so and, if it doesn’t find them, will build a libobjcxx.so that links to libstdc++ and to libobjc.so.  This extra library provides the required functionality for Objective-C++.  If you are seeing this being built, then you will need to link it for Objective-C++ to work.  This configuration isn’t as well tested, because I don’t use any platforms that package things like this on a regular basis.

TL;DR: Can you try adding -lobjcxx and see if that makes things work again for you?

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
Thank you for the help!

> It seems to be missing the linker command line for building the CXXException test.  It’s probably worth taking a step back at this point:
>
> On Linux platforms, it’s common to provide libsupc++ (the GNU C++ runtime library) statically linked into libstdc++ (the GNU C++ standard library).  This is somewhat awkward, because this means that the only way to use symbols in libsupc++ is to add a dependency on libstdc++.  I’ve tried to avoid that for libobjc, because libstdc++ is a big library and is completely unused for pure Objective-C programs.
>
> On FreeBSD, we ship libcxxrt (the BSD C++ runtime, which I wrote) as a separate .so and link both libstdc++ and libc++ (the LLVM C++ standard library) to it dynamically, so we can support programs linked to both.  This means that on FreeBSD we ship libobjc.so dynamically linked to libcxxrt.so, and that doesn’t add much to the dependency footprint for any Objective-C project.
>
> By default, the libobjc CMake build looks for libcxxrt.so or libsupc++.so and, if it doesn’t find them, will build a libobjcxx.so that links to libstdc++ and to libobjc.so.  This extra library provides the required functionality for Objective-C++.  If you are seeing this being built, then you will need to link it for Objective-C++ to work.  This configuration isn’t as well tested, because I don’t use any platforms that package things like this on a regular basis.
>
> TL;DR: Can you try adding -lobjcxx and see if that makes things work again for you?

I tried adding this to Test/CMakeFiles/CXXExceptions.dir/link.txt and Test/CMakeFiles/CXXExceptions_optimised.dir/link.txt, but the linker couldn't find the shared library:

/usr/bin/ld.bfd.real: cannot find -lobjcxx

I located the .so at the root of my build tree:

(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2$ find . -name libobjcxx.so
./libobjc2-1.8.1/build/libobjcxx.so

I added -L.. to the linker command.  The linker was then able to find libobjcxx.so, but unfortunately the exception errors came back, along with some new ones from libobjcxx.so:

(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test$ /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic -lobjcxx  CMakeFiles/CXXExceptions_optimised.dir/CXXException.m.o CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o  -o CXXExceptions_optimised -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -L..            
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `throw_int':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x7): undefined reference to `__cxa_allocate_exception'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x12): undefined reference to `typeinfo for int'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x1c): undefined reference to `__cxa_throw'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `catchall':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x2c): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x3b): undefined reference to `__cxa_rethrow'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x43): undefined reference to `__cxa_end_catch'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `__clang_call_terminate':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x2): undefined reference to `__cxa_begin_catch'
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x7): undefined reference to `std::terminate()'
CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o:(.eh_frame+0x3f): undefined reference to `__gxx_personality_v0'
../libobjcxx.so: undefined reference to `operator delete(void*)'
../libobjcxx.so: undefined reference to `std::type_info::__is_pointer_p() const'
../libobjcxx.so: undefined reference to `typeinfo for std::type_info'
../libobjcxx.so: undefined reference to `std::type_info::__is_function_p() const'
../libobjcxx.so: undefined reference to `__dynamic_cast'
../libobjcxx.so: undefined reference to `std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void**) const'
../libobjcxx.so: undefined reference to `vtable for std::type_info'
../libobjcxx.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
../libobjcxx.so: undefined reference to `std::type_info::~type_info()'
clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)

Drat! :)

Do you know where I might go from here?  BTW, in case I did not note them before, here is a list of the versions I am using- please let me know if I should try upgrading one of these:

libobjc2-1.8.1
gnustep-base-1.24.9
gnustep-make-2.6.0
llvm-5.0.0
Ubuntu Linux with kernel 3.13.0-125-generic

Thanks!

--David





_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 17 Nov 2017, at 15:39, Lobron, David <[hidden email]> wrote:

>
> I tried adding this to Test/CMakeFiles/CXXExceptions.dir/link.txt and Test/CMakeFiles/CXXExceptions_optimised.dir/link.txt, but the linker couldn't find the shared library:
>
> /usr/bin/ld.bfd.real: cannot find -lobjcxx
>
> I located the .so at the root of my build tree:
>
> (ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2$ find . -name libobjcxx.so
> ./libobjc2-1.8.1/build/libobjcxx.so
>
> I added -L.. to the linker command.  The linker was then able to find libobjcxx.so, but unfortunately the exception errors came back, along with some new ones from libobjcxx.so:
>
> (ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test$ /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic -lobjcxx  CMakeFiles/CXXExceptions_optimised.dir/CXXException.m.o CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o  -o CXXExceptions_optimised -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -L..            
> CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `throw_int':
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x7): undefined reference to `__cxa_allocate_exception'
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x12): undefined reference to `typeinfo for int'
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x1c): undefined reference to `__cxa_throw'
> CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `catchall':
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x2c): undefined reference to `__cxa_begin_catch'
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x3b): undefined reference to `__cxa_rethrow'
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text+0x43): undefined reference to `__cxa_end_catch'
> CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o: In function `__clang_call_terminate':
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x2): undefined reference to `__cxa_begin_catch'
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.cc:(.text.__clang_call_terminate[__clang_call_terminate]+0x7): undefined reference to `std::terminate()'
> CMakeFiles/CXXExceptions_optimised.dir/CXXException.cc.o:(.eh_frame+0x3f): undefined reference to `__gxx_personality_v0'
> ../libobjcxx.so: undefined reference to `operator delete(void*)'
> ../libobjcxx.so: undefined reference to `std::type_info::__is_pointer_p() const'
> ../libobjcxx.so: undefined reference to `typeinfo for std::type_info'
> ../libobjcxx.so: undefined reference to `std::type_info::__is_function_p() const'
> ../libobjcxx.so: undefined reference to `__dynamic_cast'
> ../libobjcxx.so: undefined reference to `std::type_info::__do_upcast(__cxxabiv1::__class_type_info const*, void**) const'
> ../libobjcxx.so: undefined reference to `vtable for std::type_info'
> ../libobjcxx.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
> ../libobjcxx.so: undefined reference to `std::type_info::~type_info()'
> clang-6.0: error: linker command failed with exit code 1 (use -v to see invocation)
>
> Drat! :)
>
> Do you know where I might go from here?  BTW, in case I did not note them before, here is a list of the versions I am using- please let me know if I should try upgrading one of these:
>

You’ll need to also link with libstdc++.  Using g++ or clang++ instead of gcc / clang will do the right thing.

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David

> You’ll need to also link with libstdc++.  Using g++ or clang++ instead of gcc / clang will do the right thing.

Thank you!  I added -lobjcxx -lstdc++ and -L.. to the link command.  That fixed the build issues, and I was able to run the tests.  All of the tests pass now, including the exception tests:

44/46 Test #44: MethodArguments_optimised ..............   Passed    0.00 sec
      Start 45: CXXExceptions
45/46 Test #45: CXXExceptions ..........................   Passed    0.00 sec
      Start 46: CXXExceptions_optimised
46/46 Test #46: CXXExceptions_optimised ................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 46

Could you suggest the best way to apply this fix to the libobjc2 library as a whole?  I can use patch or the like to update makefiles or cmake lists as needed.  Once that is done, I will try a rebuild of my original program, and see if this fixes the exception crashes.

Thank you again!

--David
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 17 Nov 2017, at 18:31, Lobron, David <[hidden email]> wrote:

>
>
>> You’ll need to also link with libstdc++.  Using g++ or clang++ instead of gcc / clang will do the right thing.
>
> Thank you!  I added -lobjcxx -lstdc++ and -L.. to the link command.  That fixed the build issues, and I was able to run the tests.  All of the tests pass now, including the exception tests:
>
> 44/46 Test #44: MethodArguments_optimised ..............   Passed    0.00 sec
>      Start 45: CXXExceptions
> 45/46 Test #45: CXXExceptions ..........................   Passed    0.00 sec
>      Start 46: CXXExceptions_optimised
> 46/46 Test #46: CXXExceptions_optimised ................   Passed    0.00 sec
>
> 100% tests passed, 0 tests failed out of 46
>
> Could you suggest the best way to apply this fix to the libobjc2 library as a whole?  I can use patch or the like to update makefiles or cmake lists as needed.  Once that is done, I will try a rebuild of my original program, and see if this fixes the exception crashes.
>
> Thank you again!

I think the best option is probably to give up trying to avoid the libstdc++ dependency and just build a single libobjc.so that links against libstdc++.so if lib{supc++,cxxrt,c++abi}.so is not available.  

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
Hi David,

> I think the best option is probably to give up trying to avoid the libstdc++ dependency and just build a single libobjc.so that links against libstdc++.so if lib{supc++,cxxrt,c++abi}.so is not available.  

I added the following to CMakeLists.txt:

target_link_libraries(objc stdc++)
target_link_libraries(objc objcxx)

All unit tests now pass for me.  However, my test program still crashes when I try to catch a std::exception in ObjC++.

Looking at the tests more closely, it appears that the CXXExceptions tests are compiled as pure ObjC and C++ (i.e., with .m and .cc suffixes, respectively).  I don't see a test with a .mm suffix, so I'm not sure if the tests really cover the bug that's biting me.

I tried making a .mm version of CXXExceptions.cc.  The test compiled, but I've been having trouble linking it (I've copied my link error below- I'm linking explicitly with libobjcxx.so and libobjc.o, but the linker isn't finding objc_autorelease or throw_int).

Do you think I'm barking up the wrong tree here?  Do the existing tests actually cover the case of ObjC++, and I'm just not seeing it?  

Thank you,

David

Linker error when trying to add a .mm version of CXXException to the tests:

(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test$ /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXException.dir/CXXException.mm.o  -o CXXException -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -lstdc++ ../libobjcxx.so.4.6 -L/home/dlobron/build/clangport/akamai/common/lib -lobjcxx -lobjc
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__autorelease':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x98): undefined reference to `objc_autorelease(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__retain':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0xc8): undefined reference to `objc_retain(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__release':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0xf8): undefined reference to `objc_release(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_c_NSAutoreleasePool__addObject_':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x149): undefined reference to `objc_autorelease(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `finally()':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x18d): undefined reference to `throw_int()'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `main':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x3a2): undefined reference to `catchall()'
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David
One more bit of info on the linker error on my .mm test program: I confirmed that libobjc.so has the symbols, e.g.,

(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/common/lib$ nm -C libobjc.so|grep objc_autorelease
00000000000204b0 T objc_autorelease
00000000000200f0 T objc_autoreleasePoolPop
000000000001fc90 T objc_autoreleasePoolPush
00000000000204f0 T objc_autoreleaseReturnValue 

I'm linking with the library:

/home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXException.dir/CXXException.mm.o  -o CXXException -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -lstdc++ ../libobjcxx.so.4.6 -L/home/dlobron/build/clangport/akamai/common/lib -lobjcxx -lobjc

But the symbol is still not found:

CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__autorelease':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x98): undefined reference to `objc_autorelease(objc_object*)'

Full linker error below.

Linker error when trying to add a .mm version of CXXException to the tests:

(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build/Test$ /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXException.dir/CXXException.mm.o  -o CXXException -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -lstdc++ ../libobjcxx.so.4.6 -L/home/dlobron/build/clangport/akamai/common/lib -lobjcxx -lobjc 
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__autorelease':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x98): undefined reference to `objc_autorelease(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__retain':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0xc8): undefined reference to `objc_retain(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__release':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0xf8): undefined reference to `objc_release(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_c_NSAutoreleasePool__addObject_':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x149): undefined reference to `objc_autorelease(objc_object*)'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `finally()':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x18d): undefined reference to `throw_int()'
CMakeFiles/CXXException.dir/CXXException.mm.o: In function `main':
/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x3a2): undefined reference to `catchall()'


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
On 20 Nov 2017, at 19:15, Lobron, David <[hidden email]> wrote:

>
> One more bit of info on the linker error on my .mm test program: I confirmed that libobjc.so has the symbols, e.g.,
>
> (ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/common/lib$ nm -C libobjc.so|grep objc_autorelease
> 00000000000204b0 T objc_autorelease
> 00000000000200f0 T objc_autoreleasePoolPop
> 000000000001fc90 T objc_autoreleasePoolPush
> 00000000000204f0 T objc_autoreleaseReturnValue
>
> I'm linking with the library:
>
> /home/dlobron/build/clangport/akamai/llvm/llvm-5.0.0.install/bin/clang -std=gnu99  -fexceptions  -rdynamic CMakeFiles/CXXException.dir/CXXException.mm.o  -o CXXException -Wl,-rpath,/home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/build ../libobjc.so.4.6 -lstdc++ ../libobjcxx.so.4.6 -L/home/dlobron/build/clangport/akamai/common/lib -lobjcxx -lobjc
>
> But the symbol is still not found:
>
> CMakeFiles/CXXException.dir/CXXException.mm.o: In function `_i_Test__autorelease':
> /home/dlobron/build/clangport/akamai/libobjc2/libobjc2-1.8.1/Test/CXXException.mm:(.text+0x98): undefined reference to `objc_autorelease(objc_object*)’

This looks like it’s trying to all a version with C++ name mangling.  Try sticking an extern “C” { } around the #includes.

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David

> This looks like it’s trying to all a version with C++ name mangling.  Try sticking an extern “C” { } around the #includes.

Thanks, David.  That extern statement did not fix the compilation problem, but I was able to simplify things by reverting to my original test program that simply throws a C++ std::exception in code compiled with a .mm suffix.  That program now builds and runs correctly, whereas previously, it crashed.  So I think the changes we made do fix the problem.

Unfortunately, my main program is still crashing with a NULL exception.  I'm now wondering if there's something wrong with my build command, or maybe with the runtime flags I'm passing to my main program.

I ran nm on the test program to see what exception personality it uses:

$ nm -C CXXException_mm|grep -i except
                 U __cxa_allocate_exception@@CXXABI_1.3
0000000000400ea4 r GCC_except_table0
                 U std::exception::~exception()@@GLIBCXX_3.4
00000000006020d0 V typeinfo for std::exception@@GLIBCXX_3.4
00000000006020a0 V vtable for std::exception@@GLIBCXX_3.4

I checked for those strings in my main program, and the result was similar, although not identical:

$ nm -C obj/mapmaker|grep __cxa_allocate_exception
                 U __cxa_allocate_exception@@CXXABI_1.3
(ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/mapmaker$ nm -C obj/mapmaker|grep std::exception  
                 U std::exception::~exception()@@GLIBCXX_3.4
                 U typeinfo for std::exception@@GLIBCXX_3.4

The only difference here is that the non-working main program doesn't have "vtable for std::exception".  Could that be the source of the problem?  Or could this be a runtime or compile-time difference in my code?

--David
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David

> $ nm -C CXXException_mm|grep -i except
>                 U __cxa_allocate_exception@@CXXABI_1.3
> 0000000000400ea4 r GCC_except_table0
>                 U std::exception::~exception()@@GLIBCXX_3.4
> 00000000006020d0 V typeinfo for std::exception@@GLIBCXX_3.4
> 00000000006020a0 V vtable for std::exception@@GLIBCXX_3.4
>
> I checked for those strings in my main program, and the result was similar, although not identical:
>
> $ nm -C obj/mapmaker|grep __cxa_allocate_exception
>                 U __cxa_allocate_exception@@CXXABI_1.3
> (ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/mapmaker$ nm -C obj/mapmaker|grep std::exception  
>                 U std::exception::~exception()@@GLIBCXX_3.4
>                 U typeinfo for std::exception@@GLIBCXX_3.4
>
> The only difference here is that the non-working main program doesn't have "vtable for std::exception".  Could that be the source of the problem?  Or could this be a runtime or compile-time difference in my code?

Oops, another difference is that the working program has a defined address for the typoinfo, whereas in the non-working one, the typeinfo is undefined.  I'm still not sure whether this is the cause of the crash, though.

--David
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

David Chisnall
In reply to this post by Lobron, David
On 21 Nov 2017, at 16:13, Lobron, David <[hidden email]> wrote:
>
>> This looks like it’s trying to all a version with C++ name mangling.  Try sticking an extern “C” { } around the #includes.
>
> Thanks, David.  That extern statement did not fix the compilation problem, but I was able to simplify things by reverting to my original test program that simply throws a C++ std::exception in code compiled with a .mm suffix.  That program now builds and runs correctly, whereas previously, it crashed.  So I think the changes we made do fix the problem.
>
> Unfortunately, my main program is still crashing with a NULL exception.  I'm now wondering if there's something wrong with my build command, or maybe with the runtime flags I'm passing to my main program.

You will need to make sure that every stack frame that may have C++ exceptions thrown through it is compiled with -fobjc-runtime=gnustep-1.8 (or 1.7, I forget exactly when I fixed this).  The old GCC ABI corrupts foreign exceptions when they are thrown through Objective-C frames.  

> I ran nm on the test program to see what exception personality it uses:
>
> $ nm -C CXXException_mm|grep -i except
>                 U __cxa_allocate_exception@@CXXABI_1.3
> 0000000000400ea4 r GCC_except_table0
>                 U std::exception::~exception()@@GLIBCXX_3.4
> 00000000006020d0 V typeinfo for std::exception@@GLIBCXX_3.4
> 00000000006020a0 V vtable for std::exception@@GLIBCXX_3.4
>
> I checked for those strings in my main program, and the result was similar, although not identical:
>
> $ nm -C obj/mapmaker|grep __cxa_allocate_exception
>                 U __cxa_allocate_exception@@CXXABI_1.3
> (ALSI8)dlobron@bos-lps80:~/build/clangport/akamai/mapmaker$ nm -C obj/mapmaker|grep std::exception  
>                 U std::exception::~exception()@@GLIBCXX_3.4
>                 U typeinfo for std::exception@@GLIBCXX_3.4
>
> The only difference here is that the non-working main program doesn't have "vtable for std::exception".  Could that be the source of the problem?  Or could this be a runtime or compile-time difference in my code?

If it doesn’t have a reference to the vtable for std::exception then that implies that it isn’t actually allocating a std::exception, which is a little bit surprising.

David


_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
Reply | Threaded
Open this post in threaded view
|

Re: Crash occurs when catching std::exception in Objective-C++ code compiled with clang on Linux and using libobjc2

Lobron, David

> You will need to make sure that every stack frame that may have C++ exceptions thrown through it is compiled with -fobjc-runtime=gnustep-1.8 (or 1.7, I forget exactly when I fixed this).  The old GCC ABI corrupts foreign exceptions when they are thrown through Objective-C frames.  

OK- I made sure that -fobjc-runtime=gnustep-1.8 appears in my OBJCXX flags, and I'm trying a complete rebuild.  I'm now getting a compilation error when building a .mm file:

#error  "gnustep-base is configured to use 'traditional' exceptions, but you are building for 'native' exceptions."

The configure script for gnustep-base finds the GNU runtime:

checking the Objective-C runtime... GNU

but it's not able to link the uncaught exception handler, so it turns off native exceptions:

checking for objc_setUncaughtExceptionHandler() in runtime... no

Does this mean that libobjc2 does not support the uncaught exception handler code?  I'm wondering if this is a clue as to why my code crashes, whereas the libobjc2 tests are OK.

--David
_______________________________________________
Discuss-gnustep mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep
12