JIT 编译器和异常处理

问题描述 投票:0回答:2

在 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 64-bit
2个回答
5
投票
如本文所述

即使您只有一个仅调用另一个函数的小函数,您仍然需要展开数据,否则当发生异常时,您的进程将被终止。

展开数据的
格式已记录

,但相当简洁。


2
投票

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,使其不再那么琐碎,从而增强您对它的信心。

© www.soinside.com 2019 - 2024. All rights reserved.