【问题标题】:JIT compilers and exception handlingJIT 编译器和异常处理
【发布时间】:2013-03-02 13:58:33
【问题描述】:

在 Windows x64 上,假设存在三个函数的调用链:

function A, written in C++
function B, generated by a JIT compiler
function C, written in C++

A 调用 B,B 调用 C,然后 C 抛出由 A 捕获的异常。B 只是直线代码;它从不抛出或捕获任何异常,也不包含任何析构函数。

http://msdn.microsoft.com/en-us/library/ms235286(v=vs.80).aspx 说 B 必须保持堆栈对齐到 16 个字节,这很好。它还说必须为 B 提供展开数据,但不清楚这些数据应该包含什么或如何提供。

在这种情况下,B 确实 实际上必须进行任何展开,它是否仍然必须有一个空的展开数据块,或者你可以忽略它并让异常静默传递 B ?

【问题讨论】:

    标签: c++ windows exception-handling 64-bit


    【解决方案1】:

    Microsoft C++ 编译器发出与 Windows SEH 统一的异常处理代码。所以它是一个很好的工具来看看它应该如何完成。从一个包含一些测试代码的虚拟项目开始:

    void foo() { throw 1; }
    
    void testNoTry() { foo(); }
    
    void testTry() {
        try { foo(); }
        catch (int& err) {}
    }
    

    项目 + 属性、C/C++、输出文件、ASM 列表位置 = /FAcs。这会生成一个 .cod 文件,其中包含此代码的程序集。 C/C++、代码生成、基本运行时检查 = 默认。这减少了噪音。构建。

    使用文本编辑器打开 .cod 文件。您会看到它将异常数据写入 xdata$x 段。使用显式命名的展开表部分,__unwindtable$ 符号。很痛苦,不是吗。

    但除此之外还有个好消息:testNoTry() 根本没有展开数据。恭喜。通过使其不那么琐碎,例如将 foo() 移动到另一个 .cpp 文件并尝试 /EHsa 来建立您对它的信心。

    【讨论】:

      【解决方案2】:

      你确实需要展开数据as this article explains:

      即使你只有一个很小的函数,它只调用另一个函数,你仍然需要展开数据,或者当发生异常时,你的进程将被简单地终止。

      format of the unwind data is documented,但它相当简洁。

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-25
      • 2010-12-21
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多