can't catch exceptions from inside dynamically loaded object

Paul Forgey
Sun Jan 31 00:26:00 GMT 1999

What you point out makes perfect sense.  As a win32 developer also, I am
quite aware of some of the gotchas of dynamic libraries.  Win32 has a
similar gotcha, but there is no equivilent to the --export-dynamic.

Consider a main application using a DLL, but both exe and dll are linked to
have the crt in a dll.  In this case, and only in this case, may the dll and
exe free() or delete memory malloc()'d or new'd in the other, and dittio for
catch()ing exceptions throw()n in the other.

Here's where the egcs solaris behavior becomes a bug, but I'm not certain if
it's a solvable bug.

My .so is statically linked against libstd++ (I ln'd a libstdc++-ar so I can
have the libstdc++ static and not loose dynamic linkage against other
things, like libpthread, which needs one and only one instance).  So the
dynamic library has it's own version of any global objects which need to be
constructed at load time.  Solaris does not seem to have a shared library
function which gets called at load time (like via dlopen()).

This is how the win32 senario is able to work.  If my exe was linked against
the dll, and the dll is staically linked against the crt, then the dll
becomes it's own little island (as far as crt objects are concerned), but
global initialization of the dll's crt is able to happen because of
DllMain(), which gets called when the process starts, exists, thread start,
thread exit.

One possible workaround would be to call a crtmainstartup() (or whatever it
is that gets called by the linker or kernel), but this could have very
unintended side affects.

I think we can conclude a few things:

when building the dynamic library, one option would be to NOT link in
libstdc++ at all, which would require the main application be using libstd++
as a shared object
which means the application will have already initialized it, and the .so
being loaded will be using the same copy (which is why you don't put in the
import linkage when building it; you want only one copy process-wide)
which means things will work just fine (and they do according to my tests)

But if the shared object is linking against a library needing static
initialization, then the shared object must call it's initializer.

-----Original Message-----
From: <>
To: <>;
Date: Saturday, January 30, 1999 5:10 AM
Subject: RE: can't catch exceptions from inside dynamically loaded object

>I have discovered that we can catch such exceptions if just *one*
>instance of __register_frame_info() is *in use* throughout the address
>space including the main executable and dynamically loaded shared
>objects. This can be achieved by either one of:
>    - link the main executable with "-export-dynamic" option of GNU ld.
>    - link the main executable with shared library
>The first method has severe side effect on i586-pc-linux-gnu platform.
>If same symbol is used in the main executable and the shared object, the
>symbol in shared object will be always ignored. For example,
>    add this code to "a.cpp" in my previous email
>        void xxx() { cerr << "this is xxx() in A." << endl; }
>    add this code to "b.cpp"
>        void xxx() { cerr << "this is xxx() in B." << endl; }
>    add this line to "b.cpp" before throwing an exception.
>        xxx();
>    on i586-pc-linux-gnu platform, the output from "a" will be:
>        I am B.
>        this is xxx() in A.
>        caught int
>    on sparc-sun-solaris2.5.1 platform, it will be:
>        I am B.
>        this is xxx() in B.
>        caught int
>The second method may not happy for me on some situation.
>Above methods are far from *perfect* because they require special
>compilation or environment for running. To achieve the perfect, there
>should be no way other than modify "frame.c" to change how it maintains
>a linked list headed by "struct object* objects".
>Shigeru Kanemoto
>HappySize, Inc.

More information about the Gcc-bugs mailing list