获取当前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
,因为这是for
libstdc++
所做的。您还可以检查
-在
gcc-v
的输出中启用sjlj异常是不正确的,比如说,默认值(即不使用任何
--启用
--禁用
选项时使用的内容)取决于平台。谢谢,Jonathan。仍然在考虑通过编译代码来计算异常模型。@JonathanWakely,我更新了答案,去掉了配置标志检查,感谢您的帮助。我添加了一些在
stdlibc++
配置脚本中找到的异常处理代码段的编译示例,然后查看程序集以确定正确的基本特征。我使用以下内容作为参考: