获取当前GCC异常模型
获取当前GCC异常模型,gcc,mingw-w64,Gcc,Mingw W64,g++是使用DWARF2、sjlj或seh异常模型构建的。提供具有不同异常模型的g++的各种版本。我希望能够从gcc工具链中确定正在使用的异常模型。是否有一个g++参数将转储编译器的默认异常模型?编辑:最初,我正在测试g++-v中描述的配置标志。正如乔纳森在评论中清醒地指出的那样,这不是一件好事 一种检查方法是编译到汇编: struct S { ~S(); }; void bar(); void foo() { S s; bar(); } g++-S-o output.S的结果中有以下
g++
是使用DWARF2
、sjlj
或seh
异常模型构建的。提供具有不同异常模型的g++
的各种版本。我希望能够从gcc
工具链中确定正在使用的异常模型。是否有一个g++
参数将转储编译器的默认异常模型?编辑:最初,我正在测试g++-v
中描述的配置标志。正如乔纳森在评论中清醒地指出的那样,这不是一件好事
一种检查方法是编译到汇编:
struct S { ~S(); };
void bar();
void foo() {
S s;
bar();
}
g++-S-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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
MinGW-4.8.1-x86-posix-dwarf
:
.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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
MinGW-4.8.1-x64-posix-seh
:
.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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
FC17-g++-4.7.2-x64
:
.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
.def ___gxx_personality_v0; .scl 2; .type 32; .endef
.def __Unwind_Resume; .scl 2; .type 32; .endef
.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
.def __gxx_personality_seh0; .scl 2; .type 32; .endef
.def _Unwind_Resume; .scl 2; .type 32; .endef
.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
.cfi_personality 0x3,__gxx_personality_v0
.globl __gxx_personality_v0
call _Unwind_Resume
看起来我们应该搜索\uuuugxx\u personality([a-z])(0-9]+)
,然后将第一个捕获组与以下组进行比较:
v
=dwarf
seh
=seh
sj
=sjlj
为了补充上述答案,GCC有一个预定义的宏,允许在编译时识别是否使用了SJLJ异常模型:
\uuuuu使用SJLJ\uuu异常
如果编译器使用基于setjmp和longjmp的旧机制进行异常处理,则定义该宏,值为1
看
根据文件,至少从3.1.1版开始提供;我刚刚在GCC 7.1上测试了它(在MinGW-w64下).看起来您可以通过检查程序集编译的输出来确定gcc是否正在使用sjlj
,查找\u Unwind\u sjlj\u Resume
或\u Unwind\u Resume
,因为这是forlibstdc++
所做的。您还可以检查-在gcc-v
的输出中启用sjlj异常是不正确的,比如说,默认值(即不使用任何--启用或--禁用选项时使用的内容)取决于平台。谢谢,Jonathan。仍然在考虑通过编译代码来计算异常模型。@JonathanWakely,我更新了答案,去掉了配置标志检查,感谢您的帮助。我添加了一些在stdlibc++
配置脚本中找到的异常处理代码段的编译示例,然后查看程序集以确定正确的基本特征。我使用以下内容作为参考: