Hi, Giuseppe Corbelli <giuseppe.corbe...@copanitalia.com> wrote on 09.04.2013 09:09:14:
> On 08/04/2013 14:11, Holger Joukl wrote: > >> I have found a couple of references. > >> http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html (see static-libgcc) > >> http://gcc.gnu.org/wiki/Visibility > > > > Thanks, I'll need to look into these. > > > >> The proprietary lib is shared, right? linked to? shared? static? > > > > Shared C lib, we compile a shared C++ lib linked to the C lib from the > > vendor > > C++ sources, which we shared-link the (shared) Boost.Python wrapper to. > > Quoting from the manual: > There are several situations in which an application should use the shared > libgcc instead of the static version. The most common of these is when the > application wishes to throw and catch exceptions across different shared > libraries. In that case, each of the libraries as well as the application > itself should use the shared libgcc. Both the shared libboost_python.so and the extension module I'm building link against the shared libgcc_s.so. > However, if a library or main executable is supposed to throw or catch > exceptions, you must link it using the G++ or GCJ driver, as appropriate for > the languages used in the program, or using the option -shared-libgcc, such > that it is linked with the shared libgcc. > > Likely the C_lib.so is not linked to libgcc_s.so. Don't know if it'spossible > to "extract" the objects from the shared .so. Maybe playing dirty > with LD_PRELOAD? While the shared lib is indeed not linked to libgcc_s.so I now don't think this does make any difference for the problem at hand: Experimenting with this simple test lib: 0 $ cat dispatch.h // File: dispatch.h #ifdef __cplusplus extern "C" { #endif typedef char const *cb_arg_t; typedef void (*callback_func_ptr_t)(cb_arg_t); void invoke(callback_func_ptr_t cb, cb_arg_t arg); #ifdef __cplusplus } #endif 0 $ cat dispatch.c // File: dispatch.c #include <stdio.h> #include "dispatch.h" void invoke(callback_func_ptr_t cb, cb_arg_t arg) { printf("--> invoke(%d, %s)\n", &(*cb), arg); (*cb)(arg); printf("<-- invoke(%d, %s)\n", &(*cb), arg); } $ cat dispatch_main.cpp // File: dispatch_main.cpp #include <iostream> #include <stdexcept> #include "dispatch.h" void callback(cb_arg_t arg) { printf("--> CPP callback(%s)\n", arg); printf("<-- CPP callback(%s)\n", arg); } void callback_with_exception(cb_arg_t arg) { printf("--> CPP exception-throwing callback(%s)\n", arg); throw std::runtime_error("throwing up"); printf("<-- CPP exception-throwing callback(%s)\n", arg); } int main(void) { std::cout << "--> CPP main" << std::endl; cb_arg_t s = "CPP main callback argument"; invoke(&callback, s); try { invoke(&callback_with_exception, s); } catch (const std::exception& exc) { std::cout << "caught callback exception: " << exc.what() << std::endl; } std::cout << "<-- CPP main" << std::endl; return 0; } I've found that: (1) linking the C lib dynamically or statically against libgcc does not make any difference wrt exception segfaulting. I.e. lib compiled with - gcc -static-libgcc -o libdispatch.so -shared -fPIC dispatch.c: $ ldd libdispatch.so libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1 - gcc -o libdispatch.so -shared -fPIC dispatch.c $ ldd libdispatch.so libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1 will not make any difference when running the main program: 0 $ g++ -I. -L. -R. -ldispatch dispatch_main.cpp 0 $ ./a.out --> CPP main --> invoke(68316, CPP main callback argument) --> CPP callback(CPP main callback argument) <-- CPP callback(CPP main callback argument) <-- invoke(68316, CPP main callback argument) --> invoke(68372, CPP main callback argument) --> CPP exception-throwing callback(CPP main callback argument) terminate called after throwing an instance of 'std::runtime_error' what(): throwing up Abort (core dumped) (2) Compiling the C lib with exception support i.e. -fexceptions will make the segfault disappear: 0 $ gcc -static-libgcc -fexceptions -o libdispatch.so -shared -fPIC dispatch.c 0 $ ./a.out --> CPP main --> invoke(68720, CPP main callback argument) --> CPP callback(CPP main callback argument) <-- CPP callback(CPP main callback argument) <-- invoke(68720, CPP main callback argument) --> invoke(68776, CPP main callback argument) --> CPP exception-throwing callback(CPP main callback argument) caught callback exception: throwing up <-- CPP main 0 $ ldd libdispatch.so libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1 0 $ gcc -fexceptions -o libdispatch.so -shared -fPIC dispatch.c 0 $ ./a.out --> CPP main --> invoke(68720, CPP main callback argument) --> CPP callback(CPP main callback argument) <-- CPP callback(CPP main callback argument) <-- invoke(68720, CPP main callback argument) --> invoke(68776, CPP main callback argument) --> CPP exception-throwing callback(CPP main callback argument) caught callback exception: throwing up <-- CPP main 0 $ ldd libdispatch.so libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 libc.so.1 => /lib/libc.so.1 libm.so.2 => /lib/libm.so.2 /platform/SUNW,Sun-Fire-V490/lib/libc_psr.so.1 So, wrapping up, it looks like if the C lib isn't compiled with exception support there is no way that an exception can propagate through the C parts without segfaulting, regardless of linking dynamically or statically against libgcc. >From the cited gcc documentation I understand that linking dynamically or statically will however influence your capabilities on throwing in *one* shared lib and catching in *another* shared lib, all participating libraries *compiled with exception support*, though. Which means I'll need to do something along the lines that Niall sketched out. Thanks, Holger Landesbank Baden-Wuerttemberg Anstalt des oeffentlichen Rechts Hauptsitze: Stuttgart, Karlsruhe, Mannheim, Mainz HRA 12704 Amtsgericht Stuttgart _______________________________________________ Cplusplus-sig mailing list Cplusplus-sig@python.org http://mail.python.org/mailman/listinfo/cplusplus-sig