Exceptions on Linux from a shared object (.so)

2019-05-06 06:22发布

问题:

I have a test program called ftest. It loads .so files that contain tests and runs the tests that it finds in there. One of these tests loads and runs a .so that contains a Postgres database driver for our O/RM.

When the Postgres driver throws an exception which is defined in that .so file (or one that it links to, but ftest does not link to) and is caught by the test framework the exception destructor triggers a segfault.

This segfault happens whenever the compiled exception is in a .so that has been dynamically loaded (using dload).

This sort of thing works fine in Windows which has the same architecture. We don't really want to restrict ourselves to only use exceptions that are from the core libraries -- add-ins should be free to create their own exception classes and have them handled normally.

The exceptions are sub-classes of std::exception. Sometimes the exceptions may be defined in libraries (such as libpqxx) which means that exceptions are sometimes out of our control too.

Exceptions are thrown using something like:

throw exception_class( exception_arguments );

And are caught using:

catch ( std::exception &e ) {
    // handler code
}

Is there some special compiler option needed to get this working? Do we need to switch to throw exceptions via throw new exception_class( args ) (we don't really want to do this)?

回答1:

Assuming your using gcc -

Append -Wl,-E when you build the executable calling dlload(). This exports all type info symbols from the executable, which should allow the RTTI (when catching the exception) to work properly.

VC++ uses string compares to match typeinfo, results in slower dynamic_cast<> etc but smaller binaries. g++ uses pointer compares.

I encountered the same problem when attempting to use pure virtual interfaces classes implemented in a run-time loaded .so.

There are a few articles relating to the subject floating around on the net as well.

hope that helps, Hayman.