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(); }
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 )