dlopen and C++ libraries (vtables)

Matthew Chapman enofish@gmail.com
Wed Jul 20 13:39:00 GMT 2011


Hi,

I've run into an issue with dlopen and loading C++ libraries.  I
apologise if this is a FAQ and "can't be done" or "is easily solved".
This is happening deep inside a third-party commercial tool, so it
would be nice if I could feed back some advice for dealing with it.


Consider a program (main) that depends on a plugin (libmine) that then
happens to depend on some system library written in C++ (e.g.
libstdc++ or libboost or libxerces-c).

If main is linked at build time with libmine.so, it seems this always
works as expected.  Initializers are called in the order
/usr/lib64/libxerces-c.so, ./libmine.so, ./main; and finalizers in the
reverse order ./main, ./libmine.so, /usr/lib64/libxerces-c.so.


However, if main loads libmine.so with dlopen(), things can go bad.
During relocation processing, the dynamic linker decides:
      3199:     file=./libmine.so [0];  needed by
/usr/lib64/libxerces-c.so [0] (relocation dependency)
(_ZTVN11xercesc_2_713XSerializableE)

i.e. there is a false circular dependency created where libxerces-c.so
requires ./libmine.so.  The problem is that the same vtables and
typeinfo structures will often be weakly defined in both libraries,
e.g.:

./libmine.so:
0000000000200df0 V _ZTVN11xercesc_2_813XSerializableE
/usr/lib64/libxerces-c.so:
00000000005797a0 V _ZTVN11xercesc_2_813XSerializableE

and it seems that the first one is always chosen (load order rather
than dependency order?).

The problem then is that - due to the false dependency - the libraries
then sometimes get unloaded in the wrong order, causing symbol
resolution errors (or worse) in destructors.  I can come up with a
test case if needed.

As previously noted this doesn't happen when the library is loaded as
part of the normal dependencies, which must use a different resolution
order.


Are there any ways of getting around this behaviour?  I've tried
various dlopen flags with no success so far.  I would argue that it if
it's possible to make libmine.so load correctly at startup, it should
also be possible to make it work with dlopen()...

Thanks,
Matt



More information about the Libc-help mailing list