3

在 32 位 Windows 中(至少使用 Microsoft 编译器),异常处理使用调用堆栈上动态分配的异常帧堆栈来实现的;异常堆栈的顶部由 TIB 条目指向。运行时成本是每个需要处理异常的函数的一对PUSH/POP指令,将异常处理程序访问的变量溢出到堆栈上,并且在处理异常时,一个简单的链表遍历。

64 位 WindowsItanium / System V x86-64 ABI中,展开改为使用一个大的排序列表来描述内存中的所有函数。运行时成本是每个函数的一些表(不仅仅是涉及异常处理的表),动态生成代码的复杂性,以及在处理异常时,每个活动函数遍历函数列表一次,无论它是否与异常有关或不。

后者比前者好在哪里?我理解为什么 Itanium 模型在常见情况下比基于setjmp/的传统 UNIX 模型便宜longjmp,但是在 32 位 Windows 中,几个PUSHes 和s 加上一些寄存器溢出似乎并没有那么糟糕,因为(似乎)很多POP它提供的更快和更简单的处理。(IIRC,无论如何,Windows API 调用通常都会消耗 Ks 的堆栈空间,因此我们不会通过将这些数据强制放入表中来获得任何东西。)

4

1 回答 1

0

除了优化快乐案例之外,也许还有一个担忧,即缓冲区溢出漏洞可能会暴露异常中的信息。如果此信息被破坏,它可能会严重混淆用户,甚至可能导致进一步的错误(请记住,如果抛出另一个异常,则会调用 std::terminate())。

来源:http ://www.osronline.com/article.cfm%5earticle=469.htm

于 2020-04-12T02:30:44.520 回答