【问题标题】:Obtaining current GCC exception model获取当前 GCC 异常模型
【发布时间】:2013-07-31 19:32:33
【问题描述】:

g++ 是使用DWARF2sjljseh 异常模型构建的。 MinGW-builds 提供具有不同异常模型的 g++ 的各种构建。我希望能够从gcc 工具链中确定正在使用什么异常模型。是否有g++ 参数会转储编译器的默认异常模型?

【问题讨论】:

  • 看起来你可以通过检查程序集编译的输出来确定 gcc 是否正在使用 sjlj /跨度>
  • 您也可以在gcc -v的输出中检查--enable-sjlj-exceptions

标签: gcc mingw-w64


【解决方案1】:

为了补充上面的答案,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 下)上对其进行了测试。

【讨论】:

    【解决方案2】:

    编辑:最初,我正在测试g++ -v 中描述的配置标志。正如 Jonathon Wakely 在 cmets 中指出的那样,这不是一件好事

    一种检查方法是编译成程序集:

    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

    【讨论】:

    • 这是不正确的,正如docs 所说,默认值(即不使用任何--enable--disable 选项时使用的内容)取决于平台。
    • 谢谢,乔纳森。仍在寻找通过编译代码制定异常模型。
    • @JonathanWakely,我更新了答案,取出了配置标志检查,感谢您提供帮助。我添加了一些我在stdlibc++ 配置脚本中找到的异常处理sn-p 的编译示例,然后查看了程序集以确定正确的基本特性。我使用以下内容作为参考:hexblog.com/wp-content/uploads/2012/06/…
    猜你喜欢
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2023-02-01
    • 2016-04-06
    • 2014-12-21
    • 2013-04-25
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多