g++
是使用DWARF2
,sjlj
或seh
异常模型构建的。 MinGW-builds提供了g++
具有不同异常模型的各种构建。我希望能够从gcc
工具链中确定正在使用什么异常模型。是否有一个g++
参数会转储编译器的默认异常模型?
3 回答
编辑:最初,我正在测试g++ -v
. 正如 Jonathon Wakely 在评论中指出的那样,这不是一件好事。
一种检查方法是编译为程序集:
struct S { ~S(); };
void bar();
void foo() {
S s;
bar();
}
结果中g++ -S <filename> -o output.s
包含以下异常引用:
MinGW-4.8.1-x86-posix-sjlj
:
.def ___gxx_personality_sj0; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def __Unwind_SjLj_Resume; .scl 2; .type 32; .endef
MinGW-4.8.1-x86-posix-dwarf
:
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
MinGW-4.8.1-x64-win32-sjlj
:
.def __gxx_personality_sj0; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef
MinGW-4.8.1-x64-posix-seh
:
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
MinGW-4.8.1-x64-posix-sjlj
:
.def __gxx_personality_sj0; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Register; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Unregister; .scl 2; .type 32; .endef
.def _Unwind_SjLj_Resume; .scl 2; .type 32; .endef
FC17-g++-4.7.2-x64
:
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
看起来我们应该搜索__gxx_personality_([a-z])(0-9]+)
并比较第一个捕获组:
v
=dwarf
seh
=seh
sj
=sjlj
为了补充上面的答案,GCC 有一个预定义的宏,允许在编译时识别是否使用了 SJLJ 异常模型:
__USING_SJLJ_EXCEPTIONS__
如果编译器使用基于 setjmp 和 longjmp 的旧机制进行异常处理,则定义此宏,值为 1。
见https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
根据文档,它至少从版本 3.1.1 开始可用;我刚刚在 GCC 7.1(在 MinGW-w64 下)上对其进行了测试。
对我来说,为每个异常模型找到相应的 DLL 是可行的:
libgcc_s_dw2-1.dll (DWARF)
libgcc_s_seh-1.dll (SEH)
libgcc_s_sjlj-1.dll (SJLJ)
参考:https ://stackoverflow.com/a/19791995/16550663