Boost logo

Boost Users :

Subject: [Boost-users] Using Boost 1.63 and 1.66 together with GNU unique global objects
From: Jamie Jason (jamie.jason_at_[hidden])
Date: 2019-04-29 22:11:00

Apologies if this is a newbie question, but I have done my best to search
Google, etc., and haven't been able to find a solution.

The project I am working on uses Boost 1.63 statically linked and a
third-party shared library that uses Boost 1.66 statically linked on
CentOS 7. For reasons that are beyond my control, these are the versions
that must be used.

I am running into a problem with g++ 4.5.8 and the GNU extension to ELF for
unique global symbols.

Take as example the function get_netdb_category() in
boost/asio/impl/error.ipp. The function has a static
boost::asio::error::detail::netdb_category object that it returns a const
reference to. When I use nm to inspect the main executable the symbol
appears in the data segment and the type for
boost::asio::error::detail::netdb_category()::instance is "u", which
indicates that the compiler has marked this as a globally-unique symbol.

The problem occurs when the loader loads the third-party shared library.
Because the symbol
boost::asio::error::detail::netdb_category()::instance has been marked as
unique in the shared library as well (verified by running readelf on the
.so), the loader decides that it will simply use the one from the
executable. Because the shared library's version of the object is larger
than the executable's version, when it is constructed it overwrites the 16
bytes beyond the end of the executable's object, trashing the contents of
the data segment that were there previously.

I tried using the -fno-gnu-unique flag when compiling our executable, but
that doesn't fix the problem - it marks the symbol as weak in the main
executable, but the shared library, because I cannot re-compile, still has
the symbol marked as unique. I tried using dlopen with RTLD_LOCAL and that
fixes the problem of overwriting the main executable's memory, however the
corresponding symbols in the shared library have pointers back into the
main executable's data segment (where the corresponding netdb_category
static lives), which means that when if the shared library accesses these
objects it will be following invalid pointers as it will overlay a larger
v1.66 object onto a smaller v1.63 object.

Has anyone encountered a problem like this? And, if so, did you find a
good solution?

Much thanks,

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at