在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 ?
答案 0 :(得分:4)
您需要展开数据as this article explains:
即使你只有一个只调用另一个函数的小函数,你仍然需要展开数据,或者当发生异常时,你的过程将被终止。
答案 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来建立你对它的信心。