This is the mail archive of the
libc-help@sourceware.org
mailing list for the glibc project.
dlopen and C++ libraries (vtables)
- From: Matthew Chapman <enofish at gmail dot com>
- To: libc-help at sourceware dot org
- Date: Wed, 20 Jul 2011 23:39:30 +1000
- Subject: dlopen and C++ libraries (vtables)
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