欢迎来到天天文库
浏览记录
ID:40552319
大小:441.07 KB
页数:17页
时间:2019-08-04
《02.2 A Crash Course on the Depths of Win32 Structured Exception Handling》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库。
1、ACrashCourseontheDepthsofWin32StructuredExceptionHandlingMattPietrek著董岩译在所有Win32操作系统提供的机制中,使用最广泛的未公开的机制恐怕就要数结构化异常处理(structuredexceptionhandling,SEH)了。一提到结构化异常处理,可能就会令人想起_try、_finally和_except之类的词儿。在任何一本不错的Win32书中都会有对SEH详细的介绍。甚至连Win32SDK里都对使用_try、_finally和_except进行
2、结构化异常处理作了完整的介绍。既然有这么多地放都提到了SEH,那我为什么还要说它是未公开的呢?本质上讲,Win32结构化异常处理是操作系统提供的一种服务。编译器的运行时库对这种服务操作系统实现进行了封装,而所有能找到的介绍SEH的文档讲的都是针对某一特定编译器的运行时库。关键字_try、_finally和_except并没有什么神秘的。微软的OS和编译器定义了这些关键字以及它们的行为。其它的C++编译器厂商也只需要尊从它们定好的语义就行了。在编译器的SEH层减少了直接使用纯操作系统的SEH所带来的危害的同时,也将纯操作系
3、统的SEH从大家的面前隐藏了起来。我收到过大量的电子邮件说他们都需要实现编译器级的SEH但却找不到公开的文档。本来,我可以指着VisualC++和BorlangC++的运行时库的源代码说看一下它们就行了。但是,不知道是什么原因,编译器级的SEH仍是个天大的秘密。微软和Borland都没有提供SEH最内层的源代码。在本文中,我会从最基本的概念上讲解结构化异常处理。在讲解的时候,我会将操作系统所提供的与编译器代码生成和运行时库支持的分离开来。当深入关键性操作系统程序的代码时,我基于的都是Intel版的WindowsNT4.0
4、。然而。我所讲的大部分内容同样适用于其它的处理器。我会避免提及实际的C++的异常处理,C++下用的是catch()而不是_except。其实,真正的C++异常处理的实现方式和我所讲的方式也是极为相似的。但是,真正C++异常处理特有的复杂性会影响到我这里所讲的概念。对于深挖那些晦涩的.H和.INC文件并拼凑出Win32SEH的相关代码,最好的一个信息来源就是IBMOS/2的头文件(特别是BSEXCPT.H)。这对有相关经验的人并没什么可希奇的,这里讲的SEH机制在微软开发OS/2时就定义了。因此,Win32的SEH与OS/
5、2的极为相似。SEHintheBuff若将SEH的细节都放到一起讨论,任务实在艰巨,因此,我会从简单的开始,一层一层往深里讲。如果之前从未使用过结构化异常处理,则正好心无杂念。若是用过,那就要努力将_try、GetExceptionCode和EXCEPTION_EXECUTE_HANDLER从脑子中扫出,假装这是一个全新的概念。Areyouready?Good。当线程发生异常时,操作系统会将这个异常通知给用户使用户能够得知它的发生。更特别的是,当线程发生异常时,操作系统会调用用户定义的回调函数。这个回调函数想做什么就能做
6、什么。例如,它可以修正引起异常的程序,也可以播放一段.WAV文件。无论回调函数干什么,函数最后的动作都是返回一个值告诉系统下面该干些什么(这样说并不严格,但目前可以认为是这样)。既然在用户代码引起异常后,操作系统会回调用户的代码,那这个回调函数又是什么样的呢?换句话说,关于异常都需要知道哪些信息呢?其实无所谓,因为Win32已经定义好了。异常的回调函数的样子如下:EXCEPTION_DISPOSITION__cdecl_except_handler(struct_EXCEPTION_RECORD*ExceptionRec
7、ord,void*EstablisherFrame,struct_CONTEXT*ContextRecord,void*DispatcherContext);这个函数原型来自标准Win32头文件EXCPT.H,初看上去让人有点眼晕。如果慢慢看的话,似乎情况还没那么严重。对于初学者来说,大可以忽略返回值的类型(EXCEPTION_DISPOSITION)。所需知道的就是这个函数叫_except_handler,需要四个参数。第一个参数是一个指向EXCEPTION_RECORD的指针。这个结构体定义在WINNT.H中,定义如
8、下:typedefstruct_EXCEPTION_RECORD{DWORDExceptionCode;DWORDExceptionFlags;struct_EXCEPTION_RECORD*ExceptionRecord;PVOIDExceptionAddress;DWORDNumberParameters;DWO
此文档下载收益归作者所有