g++
使用DWARF2
、sjlj
或seh
异常模型构建。 MinGW-builds提供了不同异常模型的g++
版本。 我想从gcc
工具链中确定正在使用哪种异常模型。是否有一个g++
参数可以输出编译器的默认异常模型?
g++
使用DWARF2
、sjlj
或seh
异常模型构建。 MinGW-builds提供了不同异常模型的g++
版本。 我想从gcc
工具链中确定正在使用哪种异常模型。是否有一个g++
参数可以输出编译器的默认异常模型?
编辑:最初,我正在测试在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
stdlibc++
配置脚本中找到,然后查看汇编代码以确定正确的基本人格。我使用以下内容作为参考:http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf - Matt Clarkson补充以上答案,GCC有一个预定义宏可以在编译时识别是否使用SJLJ异常模型:
__USING_SJLJ_EXCEPTIONS__
如果编译器使用基于setjmp和longjmp的旧机制处理异常,则定义此宏,值为1。
参见https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
根据文档,自至少3.1.1版本以来就可用;我刚在MinGW-w64下的GCC 7.1上测试了它。
libgcc_s_dw2-1.dll (DWARF)
libgcc_s_seh-1.dll (SEH)
libgcc_s_sjlj-1.dll (SJLJ)
sjlj
,因为这是用于libstdc ++
的配置脚本所做的。 - Matt Clarksongcc -v
的输出中检查--enable-sjlj-exceptions
。 - Matt Clarkson