I’m having some trouble with exceptions across dynamic
libs with gcc 3.3. All works well with gcc4.0.
This situation is a bit complex, but can be summarized as follows: There
is code in one dynamic lib that has a throw and catch. In the catch, it
calls to another dynamic lib which does a rethrow of the exception.
The code fails on the re-throw, because it has lost track of the exception and thinks
the re-throw is happening outside of a catch block, so it terminates. This
seems to happen because each of my dynamic libraries has its own
__cxa_begin_catch, __cxa_throw and __cxa_rethrow, and I suspect that there
should only be one. With gcc4.0 there is the dynamic libg++, and so there
is only one set of code for these routines.
What I’ve been able to piece together so far indicates
that when the implementation of __cxa_begin_catch gets the globals
(__cxa_get_globals) so it can store the exception it is catching, it is getting
a different memory address across the different shared lib versions (and
certainly a different address than the __cxa_throw call to __cxa_get_globals).
So when one dylib handles the catch and sets up the exception, then calls
through to another dylib which does the re-throw, the re-throw can’t find
the exception because it is looking in the wrong place.
Does anyone have any experience with anything like
this? We had to do some work with symbol visibility (export everything) in
gcc4.0 to get the run time type information properly hooking up across dynamic
libs, but this seems more related to the static libc++ of gcc3.3 vs. the
dynamic libc++ of gcc4.0.
My current thoughts are to create a dynamic lib containing just some dummy
throw and catch code, and adding an export file to export the __cxa*
calls. Then I’ll have to add similar import files on all my other
.dylibs in the hopes that they will all wind up sharing the same version.
But I’m not sure if that is going to work, and it would be a pain.
Does anyone have any good ideas?
Thanks,
David Litwin
BigFix