JIT编译器和异常处理
JIT compilers and exception handling
在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提供unwind数据,但不清楚这些数据应该由什么组成,也不清楚如何提供。
在这种情况下,B 不实际上必须执行任何展开,它是否仍然需要有一个空的展开数据块,或者您可以忽略它并让异常静默地传递给B?
您确实需要展开数据,正如本文所解释的:
即使你只有一个很小的函数,只调用另一个函数,你仍然需要unwind数据,或者当一个异常发生时,你的进程将被终止。
unwind数据的格式有文档记录,但它相当简洁。
Microsoft c++编译器发出与Windows SEH统一的异常处理代码。所以它是一个很好的工具,可以帮助我们了解应该如何做。从一个包含一些测试代码的虚拟项目开始:
void foo() { throw 1; }
void testNoTry() { foo(); }
void testTry() {
try { foo(); }
catch (int& err) {}
}
Project + Properties, C/c++, Output Files, ASM List Location =/FAcs。生成带有此代码的程序集的.cod文件。C/c++,代码生成,基本运行时检查=默认。这样可以减少噪音。构建。
用文本编辑器打开.cod文件。您将看到它将异常数据写入xdata$x段。为展开表显式命名的部分,__unwindtable$
符号。很痛,不是吗?
但是在其他方面是非常好的消息:testNoTry()根本没有unwind数据。祝贺你。通过使它不那么琐碎来建立您对它的信心,例如,将foo()移动到另一个.cpp文件中并尝试/EHsa.
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- 处理编译器关于可能丢失数据的警告的最优雅方法是什么
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- 使用 stoi 功能进行异常处理
- 子系统中的异常处理:本机
- 与异常处理程序中的操作员<<不匹配
- 数组 C++ 上的异常处理程序
- 异常处理:如果用户输入不是三个特定字符之一
- C++ 异常处理错误输出
- 视觉 std::矢量无异常:警告 C4530:使用了C++异常处理程序,但未启用展开语义.指定 /EHsc
- C++交换机状态异常处理
- 在字符串类上的成员函数和out_of_range异常处理
- 奇怪的消息 (_Base_bitset::_M_do_to_ulong) 从溢出异常处理程序中打印出来
- 执行视觉工作室异常处理模式
- 为什么隐式转换在异常处理中从派生到基?
- C++执行期间的类成员函数错误/异常处理
- C++ 中未处理的异常处理程序
- 用户定义的异常处理
- JIT编译器和异常处理