在SWIG包装库中的__cxa_allocate_exception期间发生段错误

lef*_*cus 13 c++ linux g++ exception segmentation-fault

在为Ruby开发SWIG包装的C++库时,我们在C++代码中的异常处理期间遇到了无法解释的崩溃.

我不确定重新创建问题的具体情况,但它在调用期间首先发生std::uncaught_exception,然后在一些代码更改后,__cxa_allocate_exception在异常构造期间移动到.GDB和valgrind都没有提供有关崩溃原因的任何见解.

我发现了几个类似问题的参考,包括:

最重要的主题似乎是情况的组合:

  • AC应用程序链接到多个C++库
  • 编译期间使用了多个版本的libstdc ++
  • 通常,使用的C++的第二个版本来自libGL的仅二进制实现
  • 将库与C++应用程序(仅与C应用程序)链接时,不会发生此问题

"解决方案"是将您的库与libstdc ++以及可能还与libGL明确地链接,从而强制链接的顺序.

在尝试使用我的代码进行多次组合之后,我找到的唯一解决方案就是LD_PRELOAD="libGL.so libstdc++.so.6" ruby scriptname选项.也就是说,编译时链接解决方案都没有任何区别.

我对该问题的理解是C++运行时未正确初始化.通过强制链接的顺序,您可以引导初始化过程并且它可以正常工作.只有C应用程序调用C++库时才会出现此问题,因为C应用程序本身并不链接到libstdc ++,并且没有初始化C++运行时.因为使用SWIG(或boost :: python)是从C应用程序调用C++库的常用方法,所以在研究问题时经常出现SWIG.

是否有人能够更深入地了解这个问题?是否存在实际解决方案或仅存在解决方法?

谢谢.

lef*_*cus 6

按照迈克尔·多根的建议,我将我的评论复制到一个答案中:

找到了问题的真正原因.希望这会帮助其他人遇到这个bug.您可能在某处未正确初始化的某些静态数据.我们做了,解决方案是我们的代码库的boost-log.https://sourceforge.net/projects/boost-log/forums/forum/710022/topic/3706109.真正的问题是延迟加载库(加上静态),而不是来自不同库的潜在的多个C++版本.欲了解更多信息:http://parashift.com/c++-faq-lite/ctors.html#faq-10.13

由于遇到了这个问题及其解决方案,我了解到了解静态和动态链接库之间如何共享或不共享静态非常重要.在Windows上,这需要显式导出共享静态的符号(包括意味着跨不同库访问的单例).每个主要平台之间的行为略有不同.