【发布时间】:2011-02-16 05:13:12
【问题描述】:
在为 Ruby 开发一个 SWIG 封装的 C++ 库时,我们在 C++ 代码内的异常处理过程中遇到了无法解释的崩溃。
我不确定重新创建问题的具体情况,但它首先发生在调用std::uncaught_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
最重要的主题似乎是多种情况的组合:
- 一个 C 应用程序链接到多个 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。
有没有人能够更深入地了解这个问题?是否有实际的解决方案或仅存在变通方法?
谢谢。
【问题讨论】:
-
找到问题的真正原因。希望这将帮助其他遇到此错误的人。您可能在某处有一些未正确初始化的静态数据。我们做到了,解决方案在我们的代码库的 boost-log 中。 sourceforge.net/projects/boost-log/forums/forum/710022/topic/…。真正的问题是延迟加载库(加上静态),而不是来自不同库的潜在多个 C++ 版本。欲了解更多信息:parashift.com/c++-faq-lite/ctors.html#faq-10.13
-
您应该将其复制到答案中,以便其他人更容易看到。
标签: c++ linux exception g++ segmentation-fault