C++ JIT编译器和异常处理
在Windows x64上,假设有三个函数的调用链:C++ JIT编译器和异常处理,c++,windows,exception-handling,64-bit,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++ A调用B,B调用C,然后C抛出A捕获的异常。B只是直线代码;它从不抛出或捕获任何异常,也不包含任何析构函数 表示B必须使堆栈与16字节对齐,这很好。它还表示,必须向B提供解卷数据,但不清楚这些数据应该包含什么或如何提供 在这种情况下,B实际上不必进行任何退
function A, written in C++
function B, generated by a JIT compiler
function C, written in C++
A调用B,B调用C,然后C抛出A捕获的异常。B只是直线代码;它从不抛出或捕获任何异常,也不包含任何析构函数
表示B必须使堆栈与16字节对齐,这很好。它还表示,必须向B提供解卷数据,但不清楚这些数据应该包含什么或如何提供
在这种情况下,B实际上不必进行任何退绕,它是否仍然必须有一个空的退绕数据块,或者您可以忽略该数据块,让异常以静默方式传递给B?您确实需要退绕数据:
即使您只有一个只调用另一个函数的小函数,您仍然需要释放数据,或者当发生异常时,您的进程将被终止
<>但是,它是相当简洁的。< / P> < P>微软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文件。您将看到它将异常数据写入扩展数据$x段。对于展开表的显式命名部分,\uu unwindtable$
符号。很痛苦,不是吗
但除此之外,还有一个非常好的消息:testNoTry()根本没有展开数据。祝贺让它变得不那么琐碎,例如将foo()移动到另一个.cpp文件中,并尝试使用/EHsa来增强您对它的信心。同样重要,