SWIG 包装库中 __cxa_allocate_exception 期间的段错误 [英] segfault during __cxa_allocate_exception in SWIG wrapped library

查看:13
本文介绍了SWIG 包装库中 __cxa_allocate_exception 期间的段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在为 Ruby 开发一个 SWIG 封装的 C++ 库时,我们在 C++ 代码内的异常处理过程中遇到了无法解释的崩溃.

While developing a SWIG wrapped C++ library for Ruby, we came across an unexplained crash during exception handling inside the C++ code.

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

I'm not sure of the specific circumstances to recreate the issue, but it happened first during a call to std::uncaught_exception, then after a some code changes, moved to __cxa_allocate_exception during exception construction. Neither GDB nor valgrind provided any insight into the cause of the crash.

我找到了几个类似问题的参考资料,包括:

I've found several references to similar problems, including:

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

The overriding theme seems to be a combination of circumstances:

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

解决方案"是显式地将您的库与 libstdc++ 链接,也可能与 libGL 链接,强制链接顺序.

The "solution" is to explicitly link your library with libstdc++ and possibly also with libGL, forcing the order of linking.

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

After trying many combinations with my code, the only solution that I found that works is the LD_PRELOAD="libGL.so libstdc++.so.6" ruby scriptname option. That is, none of the compile-time linking solutions made any difference.

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

My understanding of the issue is that the C++ runtime is not being properly initialized. By forcing the order of linking you bootstrap the initialization process and it works. The problem occurs only with C applications calling C++ libraries because the C application is not itself linking to libstdc++ and is not initializing the C++ runtime. Because using SWIG (or boost::python) is a common way of calling a C++ library from a C application, that is why SWIG often comes up when researching the problem.

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

Is anyone out there able to give more insight into this problem? Is there an actual solution or do only workarounds exist?

谢谢.

推荐答案

根据 Michael Dorgan 的建议,我将我的评论复制到答案中:

Following Michael Dorgan's suggestion, I'm copying my comment into an answer:

找到问题的真正原因.希望这将帮助其他遇到此错误的人.您可能在某处有一些未正确初始化的静态数据.我们做到了,解决方案在我们代码库的 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

Found the real cause of the problem. Hopefully this will help someone else encountering this bug. You probably have some static data somewhere that is not being properly initialized. We did, and the solution was in boost-log for our code base. https://sourceforge.net/projects/boost-log/forums/forum/710022/topic/3706109. The real problem is the delay loaded library (plus statics), not the potentially multiple versions of C++ from different libraries. For more info: http://parashift.com/c++-faq-lite/ctors.html#faq-10.13

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

Since encountering this problem and its solution, I've learned that it's important to understand how statics are shared or not shared between your statically and dynamically linked libraries. On Windows this requires explicitly exporting the symbols for the shared statics (including things like singletons meant to be accessed across different libraries). The behavior is subtly different between each of the major platforms.

这篇关于SWIG 包装库中 __cxa_allocate_exception 期间的段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆