JIT编译器和异常处理

时间:2013-03-14 09:33:41

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

在Windows x64上,假设有一个包含三个函数的调用链:

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

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

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

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

2 个答案:

答案 0 :(得分:4)

您需要展开数据as this article explains

  

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

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

答案 1 :(得分:2)

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段。使用unwind表的显式命名部分,__unwindtable$符号。痛苦,不是吗。

但是非常好的消息:testNoTry()根本没有展开数据。恭喜。通过使它变得不那么简单,将foo()移动到另一个.cpp文件中并尝试/ EHsa来建立你对它的信心。

相关问题