Win32结构化异常处理(SEH)探秘(上)
在 Win32 操作系统提供的所有功能中,使用最广泛但最缺乏文档描述的也许就是结构化异常处理了(SEH),当你考虑 Win32 结构化异常处理时,你也许会想到诸如 _try,_finally 以及 _except 这些术语。你能在任何有关 Win32 的书中发现对 SEH 很好的描述(即使是 remedial)。即便是 Win32 SDK 也具备有相当完整的使用 _try,_finally 和 _except 进行结构化异常处理的概述。 有了这些文档,那为何还说 SEH 缺乏文档呢?其实,Win32 结构化异常处理是操作系统提供的一个服务。你能找到的关于 SEH 的所有文档都是描述特定编译器的运行时库,这个运行库对操作系统实现进行包装。_try,_finally 和 _except 这些关键字没有任何神奇的地方。微软的操作系统及其编译器系列定义这些关键字和用法。其他的编译器提供商则只是沿用这些语义。虽然借助编译器层的 SEH 可以挽回一些原始操作系统级 SEH 处理不良口碑,但在大众眼里对原始操作系统 SEH 细节的处理感觉依旧。 我收到人们大量的e-mail,都是想要实现编译器级的 SEH 处理,又无法找到操作系统功能提供的相关文档。通常我都是建议参考 Visual C++ 或者 Borland C++ 运行库源代码。唉,出于一些未知的原因,编译器级的 SEH 似乎是一个大的秘密,微软和 Borland 都不提供其对 SEH 支持的核心层源代码。 在本文中,我将一层一层对 SEH 进行解剖,以便展现其最基本的概念。我打算通过代码产生和运行时库支持将操作系统提供的功能和编译器提供的功能分开。当我深入代码考察关键的操作系统例程时,我将使用 Intel 平台上的 Windows NT4.0 作为基础。但我将要描述的大多数内容同样适用于其它处理器上运行的应用。 我打算避免涉及到真正的 C++ 异常处理,它们使用 catch(),而不是 _except。其实,真正的 C++ 异常处理实现非常类似于本文中描述的内容。但是 C++ 异常处理有一些额外的复杂性会影响我想要涉及的概念。 通过深入研究晦涩的 .H 和 .INC 文件来归纳 Win32 SEH 构成,我发现有一个信息源之一就是 IBM OS/2 头文件(尤其是 BSEXCPT.H)。为此你不要觉得大惊小怪。。此处描述的 SEH 机制在其源头被定义时,微软仍然开发 OS/2 平台(译注: OS/2 平台起初是IBM 和 微软共同研发的,后来由于种种原因两个公司没有再继续下去)。所以你会发现Win32 下的 SEH 和 OS/2 下的 SEH 极其相似。 SEH 浅析 从整体来看,SEH 的可谓不可一世,绝对压倒一切,我将从细微之处开始,用我自己的方式一层一层研究。如果你是一张白纸,以前从没接触过结构化异常处理,那就最好不过了。如果你以前使用过 SEH。那就尝试清理你头脑中的 _try,GetExceptionCode 和 EXCEPTION_EXECUTE_HANDLER 等诸如此类的词,权当自己是个新手。做一个深呼吸,准备好了吗?好,我们开始。 想象一下,我告诉你某个线程出错了,操作系统给你一个机会通知了这个线程错误,或者再具体一点,当线程出错后,操作系统调用某个用户定义的回调函数。这个回调函数可以所任何它想做的事情。例如,它可以修复任何原因导致的错误,或者播放一个 .wav 文件。不管回调函数做什么,其最后总是返回一个值,这个值告诉系统下一步做什么。(这里描述的情况不一定完全一样,但足够接近。) 假定当你的代码出现了混乱,你不得不回来,想看看回调函数是什么样子的?换句话说,你想知道什么样的异常信息呢?其实这无关紧要,因为 Win32 已经帮你决定了。一个异常回调函数就象下面这样:
该原型出自标准的 Win32 头文件 EXCPT.H,初看就有那么一点不同 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |