C++例外和 ELF .eh_frame部分
C++ exceptions and the .eh_frame ELF section
是.eh_frame ELF部分的缺失或损坏是我的C++代码停止工作异常的原因吗?以前成功捕获的任何异常现在都在调用 std::terminate((。
我的情况:
-
我的 zzz.so 共享库有 try-catch 块:
try { throw Exc(); } catch (const Exc &e) { LOG("ok " << e.what()); } catch (...) { LOG("all"); }
-
加载 zzz.so 的可执行文件(使用 ldopen(。它在 zzz.so 中调用函数
- zzz.so 中抛出的所有异常都已成功捕获到 zzz.so 中,并转储到我的日志文件中
- 还有另一个 aaa.so 加载到另一个二进制文件中。另一个 aaa.so 正在加载我的 zzz.so。
- zzz.so 中抛出的所有相同异常都会导致调用 std::terminate((。
这怎么可能?
更新
我不知道这怎么可能,但是 Clang 3.3 (FreeBSD clang 版本 3.3 (tags/RELEASE_33/final 183502( 20130610( 解决了这个问题。
这怎么可能?
引发异常时,控制权传递给__cxa_throw
例程(通常为 libstdc++.so
(,然后该例程负责查找 catch
子句并在此过程中调用析构函数,或者在找不到catch
时调用std::terminate
。
那么答案很可能是第一个可执行文件(异常工作的可执行文件(使用能够解码库中.eh_frame
的libstdc++.so
,而第二个应用程序(异常不起作用的应用程序(要么使用较旧(不兼容(版本的libstdc++.so
,要么针对libstdc++.a
的链接,或类似的东西。
注意:引发异常的实际工作是由_Unwind_RaiseException
在libgcc_s.so.1
中完成的,所以即使两个应用程序使用相同的libstdc++.so
,它们仍然可能使用不同的libgcc
。
更新:
我将 libstdc++ 和 libgcc 静态链接到我的 .so 库中受益吗?
或。DR:这很复杂。
有几件事需要考虑:
-
在 i386 以外的任何平台上,您必须构建自己的
libstdc++.a
副本并使用-fPIC
libgcc.a
,然后才能将它们链接到您的zzz.so
中。通常这些库是在没有-fPIC
的情况下构建的,并且不能静态链接到任何.so
。 -
将
libstdc++.a
静态链接到您的zzz.so
可能会使其成为衍生作品,并受 GPL 约束(请咨询您的律师(。 -
即使有从
zzz.so
导出_Unwind_RaiseException
,通常已经有另一个在(较早加载的(libgcc_s.so
中定义的_Unwind_RaiseException
实例,并且该较早的实例是将被调用的实例,从而使您的解决方法无效。为了确保调用_Unwind_RaiseException
的副本,您需要将zzz.so
与-Bsymbolic
链接,或者使用特殊的链接器脚本,以便在内部对_Unwind_RaiseException
(以及libgcc.a
中的所有其他所有内容(进行所有调用。 -
您的解决方法可能会解决
zzz.so
的问题,但可能会导致稍后加载的不相关yyy.so
出现问题,并且需要系统提供的_Unwind_RaiseException
,而不是来自zzz.so
的。这是隐藏所有libgcc.a
符号并使它们成为zzz.so
内部的另一个论点。
所以简短的回答是:这种解决方法可能会给您带来很多痛苦。
- 部分定义/别名模板模板参数
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- 程序在执行程序的其余部分之前退出
- 在更改for循环的第三部分后,未使用for循环结果
- 从具有默认值的部分指定模板类继承时发生SWIG错误,具有不带默认值的正向声明
- 部分专业化和嵌套模板
- 为C++03编译器编写部分unique_ptr,该编译器与较新的编译器在公共代码库上运行
- 如何将数组部分初始化为某个默认值?
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 在疯狂的部分中声明变量
- 由于PC显示设置的更改,Qt小部件被部分剪裁
- 在未链接的部分上生成警告
- 是同一作用域的函数部分中的函数调用
- C++:部分模板专用化用例
- 部分专业化和对标准::void_t<>的需求
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- C++ 初始化 .data 部分中的变量
- 如何在对象库中部分公开对象内容?