GCC 4.8.1, C++11, shared libraries and exception handling trouble

2.2k views Asked by At

My project consists of the following:

  • my program, written largely in C++11 (so it's not practical trying to compile it in C++03 mode)
  • a shared library (https://github.com/SOCI/soci), compiled with the same compiler

SOCI throws exceptions I need to catch in my code. It used to work with GCC4.7.3, but now I've migrated to GCC4.8.1 it doesn't anymore: the exception falls through all handlers (including catch(...)) and causes termination:

terminate called after throwing an instance of 'soci::mysql_soci_error'
  what():  Table 'brphrprhprh' doesn't exist
The program has unexpectedly finished.

What I tried:

  • throwing the same exception from my code (near the trouble point): it gets caught with the right handler;
  • recompiling SOCI with -std=c++11: no difference
  • adding __attribute__((visibility("default"))) to the exception class: no difference
  • fiddling with the -u option for typeinfo-related symbols: no difference in behaviour, symbols appear as undefined in nm output. Note that without -u's there are none at all:

    $ nm -D -C myprogram | grep soci | grep error
                     U soci::soci_error::soci_error(std::string const&)
    000000000044013a W soci::soci_error::~soci_error()
    0000000000440124 W soci::soci_error::~soci_error()
    0000000000440124 W soci::soci_error::~soci_error()
    00000000004c43b0 V typeinfo for soci::soci_error
                     U typeinfo for soci::mysql_soci_error
    00000000004c43d0 V typeinfo name for soci::soci_error
                     U typeinfo name for soci::mysql_soci_error
    00000000004c60c0 V vtable for soci::soci_error
                     U vtable for soci::mysql_soci_error
    

I also read http://gcc.gnu.org/wiki/Visibility, but must be missing something else..

Any advice?


EDIT

Actually, that wasn't any dynamic library issue. I should have immidiately tried to compile it statically -- and save a lot of time because the behaviour wouldn't actually change. (See the answer)

1

There are 1 answers

2
vines On BEST ANSWER

Finally I figured out the issue... D'oh.

It was not that the exceptions were left uncaught! The call to std::terminate was made when the exception was being thrown out of a destructor, and that is not allowed by default in C++11. The actual issue I faced was this: Destructors and noexcept -- the compiler bug allowed me to stay unaware of the library bug...