SWIG包装库中__cxa_allocate_exception期间的segfault

在为Ruby开发一个SWIG封装的C ++库的同时,我们发现在C ++代码中的exception处理期间出现了无法解释的崩溃。

我不确定重新创build问题的具体情况,但是在调用std::uncaught_exception ,首先发生了一些情况,然后在修改了一些代码之后,在构造exception的时候移动到__cxa_allocate_exception 。 GDB和valgrind都没有提供任何有关崩溃原因的信息。

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

  • http://wiki.fifengine.de/Segfault_in_cxa_allocate_exception
  • http://forums.fifengine.de/index.php?topic=30.0
  • http://code.google.com/p/osgswig/issues/detail?id=17
  • https://bugs.launchpad.net/ubuntu/+source/libavg/+bug/241808

压倒一切的主题似乎是情况的组合:

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

“解决scheme”是明确地链接你的库与libstdc ++,也可能与libGL,强制链接的顺序。

尝试了很多与我的代码组合后,我发现唯一的解决scheme是LD_PRELOAD="libGL.so libstdc++.so.6" ruby scriptname选项。 也就是说,编译时链接解决scheme没有任何区别。

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

有没有人能够更深入地了解这个问题? 有没有一个实际的解决scheme或只有解决方法存在?

谢谢。

Solutions Collecting From Web of "SWIG包装库中__cxa_allocate_exception期间的segfault"

遵循Michael Dorgan的建议,我将我的评论复制到一个答案中:

找到问题的真正原因。 希望这会帮助别人遇到这个错误。 你可能有一些静态数据没有正确初始化。 我们做了,解决方案是在我们的代码库的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上,这要求显式地导出共享静态符号(包括像意思是在不同库中访问的单例)。 每个主要平台之间的行为是微妙的不同的。

我最近遇到了这个问题。 我的进程创建一个用作Python C ++扩展的共享对象模块。 最近从RHEL 6.4升级到6.5的操作系统暴露了这个问题。

按照这里的提示,我只是添加了-lstdc ++到我的链接开关,并解决了这个问题。

使用SWIG for cpp库(Clipper)时遇到同样的问题,我发现使用LD_PRELOAD正如你所建议的。 作为另一个不需要LD_PRELOAD的解决方法,我发现我也可以将libstdc ++链接到我的模块的.so库文件中,例如

 ld -shared /usr/lib/i386-linux-gnu/libstdc++.so.6 module.o module_wrap.o -o _module.so 

然后我可以导入它在python没有任何进一步的选择。

我意识到@lefticus接受了与我猜测的静态初始化顺序相关的答案; 然而,我有一个非常类似的问题,这次用boost::python

我试图找到任何静态初始化问题,而不能 – 我重构了一大块代码库; 而当这一切没有奏效时,就完全消除了例外。

不过,还有一些人趁火打劫,我们又开始了这些段错误。

经过一番调查,我发现这个链接 ,谈论自定义分配器。

我们确实使用tcmalloc自己; 当我从导出到boost::python库中删除它之后,我们没有更多的问题了!

所以对于任何一个在这个线程中绊倒的人来说,只要一个FYI就可以了 – 如果@ lefticus的回答不起作用,请检查你是否使用了不同的分配器来使用python