Structured Exception Handling
2007-01-14 20:14:46 来源:WEB开发网简单总结一下,当发生异常时会调用一个回调函数。这个回调函数需要四个参数,其中三个都是结构体指针。在这些结构体中,有些域重要,有些并不重要。关键的问题是_except_handler回调函数收到了大量的信息,比如异常的类型和发生的位置。异常回调函数需要使用这些信息来决定所采取的行动。
我很想现在就给出一个样例程序来说明_except_handler,只是仍有一些东西需要解释,即当异常发生时操作系统是如何知道在那里调用回调函数呢?答案在另一个叫EXCEPTION_REGISTRATION的结构体中。本文通篇都能见到这个结构体,因此对这部分还是不要囫囵吞枣为好。唯一能找到 EXCEPTION_REGISTRATION正式定义的地方就是VisualC++运行时库源代码中的EXSUP.INC文件:
_EXCEPTION_REGISTRATIONstruc
prev dd ?
handlerdd ?
_EXCEPTION_REGISTRATIONends
可以看到,在WINNT.H的NT_TIB结构体定义中,这个结构体被称为_EXCEPTION_REGISTRATION_RECORD。然而_EXCEPTION_REGISTRATION_RECORD的定义是没有的,因此我所能用的只能是EXSUP.INC中的汇编语言的struc定义。对于我前面提到的SEH的未公开,这就是一例。
不管怎样,我们回到目前的问题上来。当异常发生时,OS是如何知道调用位置的呢?EXCEPTION_REGISTRATION结构体有两个域,第一个先不用管。第二个域,handler,为一个指向_except_handler回调函数的指针。有点儿接近答案了,但是还有个问题就是,OS从哪里能找到这个EXCEPTION_REGISTRATION结构体呢?
为了回答这个问题,需要记住结构化异常处理是以线程为基础的。也就是说,每一个线程都有自己的异常处理回调函数。在1996年5月的专栏中,我讲了一个关键的Win32数据结构,线程信息块(TEB或TIB)。这个结构体中有一个域对于WindowsNT,Windows95,Win32s和OS/2都是相同的。TIB中的第一个DWORD是一个指向线程的EXCEPTION_REGISTRATION结构体的指针。在Intel的Win32平台上,FS寄存器永远指向当前的TIB,因此,在FS:[0]就可以找到指向EXCEPTION_REGISTRATION结构体的指针。答案出来了!当异常发生时,系统察看出错线程的TIB并取回一个指向EXCEPTION_REGISTRATION结构体的指针,从而得到一个指向_except_handler回调函数的指针。现在操作系统已经有足够的信息来调用_except_handler函数了,见Figure2。
Tags:Structured Exception Handling
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接