4

我的项目包括以下内容:

  • 我的程序,主要用 C++11 编写(因此尝试在 C++03 模式下编译它是不切实际的)
  • 一个共享库(https://github.com/SOCI/soci),使用相同的编译器编译

SOCI 抛出我需要在我的代码中捕获的异常。它曾经与 GCC4.7.3 一起工作,但现在我已经迁移到 GCC4.8.1,它不再存在:异常通过所有处理程序(包括catch(...))并导致终止:

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

我尝试了什么:

  • 从我的代码中抛出相同的异常(靠近问题点):它被正确的处理程序捕获;
  • 重新编译 SOCI -std=c++11:没有区别
  • 添加__attribute__((visibility("default")))到异常类:没有区别
  • 摆弄 -related 符号的-u选项typeinfo:行为没有区别,符号在nm输出中显示为未定义。请注意,如果没有-u',则根本没有:

    $ 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
    

我还阅读了http://gcc.gnu.org/wiki/Visibility,但必须缺少其他内容..

有什么建议吗?


编辑

实际上,这不是任何动态库问题。我应该立即尝试静态编译它——并节省大量时间,因为行为实际上不会改变。(见答案)

4

1 回答 1

4

最后我弄清楚了这个问题...... D'oh。

并不是没有发现例外!当异常从析构函数中抛出时进行调用,std::terminate而在 C++11 中默认情况下不允许这样做。我面临的实际问题是:析构函数和noexcept——编译器错误让我不知道库错误......

于 2013-09-13T13:52:31.507 回答