Sun Studio binding gcc libs: exceptions do not work

I need to create an application with Sun Studio. This application uses a shared library that can only be created using Gnu C ++. The generic lib has a C interface, so the code can be called by Sun Compiler (to avoid problems with the name change, see also this question ).

Everything except exception handling works fine. When an exception is thrown in the shared library, the segfaults program. This only happens when the main program is compiled using the Sun Studio compiler. Compiling the minimal example below using the Gnu C ++ compiler, the program works fine, and the shared library detects an exception.

Plan A: link dynamically Here is an illustration of the installation:

GCC SOLARIS STUDIO shared c_layer.so <----- application (no exceptions) (uses exceptions sol studio) | | use flag -static -static-libstdc++ -static-lib-gcc v gcc_only_lib.so libstdc++.so (uses gcc exceptions) 

Result: segmentation violation after throwing an exception (see code below).

Plan B: Static Link

as above but building c_layer.a

Result:

Undefined first reference character
in the file __cxa_allocate_exception libs / cInterface / libcInterface.a (c_layer.cpp.o) std :: string :: ~ std :: basic_string () LIBS / cInterface / libcInterface.a (c_layer.cpp.o) __cxa_end_catch libs / cInterface .a (c_layer.cpp.o) __cxa_free_exception libs / cInterface / libcInterface.a (c_layer.cpp.o) __cxa_begin_catch libs / cInterface / libcInterface.a (c_layer.cpp.o) __cxa_throw libs / c cpp.o)

Question Why doesn't working with exeption work with Sun Studio?


If I use the gcc executable as follows:

 LD_PRELOAD=/usr/sfw/lib/amd64/libgcc_s.so ./example 

it breaks up differently:

$> termination after calling instance 'std :: runtime_error' $> termination called recursively

dbx , 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbf4c291d [4] abort (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbf497ff2 [5] __gnu_cxx :: __ verbose_terminate_handler (0x0, 0x0, 0x0, 0x0, 0x0 , 0x0), at 0xffff80ffbd9de911 [6] __cxxabiv1 :: __ terminate (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbd5b [7] std :: terminate (0x0, 0x0, 0x0, 0x0, 0x0,0) at 0xffff80ffbd9dbda3 [8] __cxa_rethrow (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dc02d [9] __gnu_cxx :: __ verbose_terminate_handler (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9de8d4 [10] __cxxabiv1 :: __ terminate (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffbd9dbd5b [11] std :: terminate (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), at 0xffff80ffxd9dbth_d , 0x0, 0x0, 0x0, 0x0, 0x0), at 0 xffff80ffbd9dbfd6 [13] clayerCall (0x0, 0x0, 0x0, 0x0, 0x0, 0x0), with 0xffff80ffb9991116 => [14] main (argc = 1, argv = 0xffff80ffbffffa78), line 6 in "exampleMain.cpp"


Here is a minimal example to reproduce the problem:

exampleMain.cpp:

 #include <clayer.h> #include <stdio.h> int main(int argc, char **argv) { if (!clayerCall()) printf("got exception\n"); else printf("OK\n"); } 

general library title:

 extern "C" { bool clayerCall(); } // end extern "C" 

shared lib source:

 #include "clayer.h" #include <exception> #include <stdexcept> #include <stdio.h> extern "C" { bool clayerCall() { try { throw std::runtime_error("hhh"); return true; } catch (std::exception &ex) { return false; } } } // end extern c 

Cmake files look like this:

for executable file

 project(exampleMain) cmake_minimum_required(VERSION 2.8) set(CMAKE_BUILD_TYPE Debug) add_definitions(-m64 -fPIC) include_directories(../stackoverflow) link_directories ( ../stackoverflow ) add_executable(example exampleMain.cpp) target_link_libraries( example stdc++ clayer ) 

for library

 project(clayer) cmake_minimum_required(VERSION 2.8) cmake_policy(VERSION 2.8) set(CMAKE_BUILD_TYPE Debug) add_library( clayer SHARED clayer.cpp ) 
+5
source share
2 answers

Exception handling requires library and linker support, which differs between the Sun Studio C ++ toolchain and Gnu C ++ toolchain (thus, it looks like a name change that you have already noted differs from the two toolchains). Using the β€œC” link here will not help you, because the implementation of the functions you are binding depends on this exception handling function. You generally cannot use C ++ code built with two different tool chains inside the same executable.

If you need to use Sun Studio because you are using closed source libraries that are only compatible with Sun Studio, your easiest way forward is to probably get a library that is "just building with GNU C ++" to build with using the Sun C ++ compiler, assuming this library is open source. This may not be trivial, and you may need the support of the authors of the library. I did this when I had to write small scripts that look like GNU C ++ commands that invoke the Sun compiler with the correct flags.

If this is out of the question, you may need to wrap the library that you are trying to use in the service and use some kind of RPC mechanism to access it from your compiled Sun Studio code.

Edit: since the library associated with this specifically raises this question may be useful. Thus, some parts of boost can be built with your version of the Sun compiler.

+6
source

It is not possible to load a shared library that is built using gcc into an executable created using solaris 12.3. Unless exceptions are disabled.

The problem is that exceptions are not part of the C ABI. The Solaris Studio runtime and gcc runtime use different _Unwind call implementations:

gcc (in particular, libstdC ++) uses additional non-standard _Unwind calls that are not available in Solaris libc, so the details of Unwind implementation in libc differ in libgccs, therefore, when all standard _Unwind routines are allowed in the Solaris version, and one non-standard _Unwind routine is allowed in gcc version, you get the problem (most likely this is what happens to you) (see here for more information )

It is not possible to execute one process that differs from C ++ runtime for parts created using solaris studio and the gcc part. Therefore, loading a shared library built with gcc into an executable created using Solaris Studio is not possible.


The good news is that from the studio solaris 12.4 on, if you enable C ++ 11 support, it can really work:

In Oracle Solaris Studio 12.4, the C ++ compiler supports C ++ 11, the new language, and the ABI (Application Binary Interface). In C ++ 11 CC mode, the compiler uses g ++ ABI and the g ++ runtime library version that ships with Oracle Solaris Studio. For this version, version 4.8.2 is the g ++ runtime library. ( link )

+5
source

Source: https://habr.com/ru/post/1209131/


All Articles