Visual C++编译器内部:异常处理与RTTI详解

0 下载量 9 浏览量 更新于2024-07-14 收藏 872KB PDF 举报
在Igor Skorchinsky于2012年的Recon大会上的演讲"Compiler Internals: Exceptions and RTTI"中,他深入探讨了Visual C++和编译器内部处理异常和运行时类型识别(Runtime Type Information, RTTI)的机制。这场演讲主要关注了两个关键概念:结构化异常处理(Structured Exception Handling, SEH)和C++异常处理(C++ Exception Handling, EH)。 首先,SEH是低级别的系统层技术,它允许程序捕获并处理由操作系统(如Windows内核)或用户代码引发的异常。在Visual C++中,C++异常是建立在SEH基础之上的,这意味着尽管C++异常提供了更高级别的抽象,但在底层实现上依赖于SEH的支持。SEH使用关键字如`__try`、`__except`和`__finally`来提供编译器级别的异常处理支持,每个函数都有一个单一的异常处理器,但会根据函数范围使用不同的支持结构(称为作用域表)。 在SEH的实现细节中,异常处理框架(registration frame)被放置在栈上,除了系统所需的字段(如处理器地址和下一个指针)外,Visual C++还添加了一些特定的字段。这个框架的结构包括指向下一个成员的指针,以及用于存储异常指针和可能的其他相关信息的空间,例如结构体`EH3_EXCEPTION_REGISTRATION`。 另一方面,RTTI是C++提供的一种功能,用于在运行时查询类的信息,如类名、基类列表和虚函数指针等。这有助于在异常发生时确定异常对象的确切类型,以便进行适当的处理。然而,与C++异常处理相比,RTTI的开销通常更高,因为它涉及到动态类型检查,可能会带来性能上的影响,尤其是在追求零成本设计(zero-cost design)的情况下。 演讲者还提到了SjLj(SetJump/LongJump)异常处理模型,这是GCC和其他一些编译器中采用的一种异常处理策略,它试图平衡异常处理的效率和可移植性。SjLj模型通过设置和恢复现场(setjmp/longjmp)来管理异常,减少了异常处理过程中的间接调用,从而可能提供更快的执行速度。 Igor Skorchinsky在这场演讲中详细解释了Visual C++中的异常处理机制,包括SEH的基础结构、C++异常如何在SEH之上构建以及RTTI的使用和其潜在性能成本。对于深入理解编译器内部异常管理和优化,这场演讲提供了宝贵的见解。