Structured Exception Handling

http://tech.ddvip.com   2007年01月14日    社区交流 收藏本文

本文详细介绍Structured Exception Handling

  我给出了一个异常回调不能处理异常的例子,见Figure5的MYSEH2.CPP。为简单起见,我用了一点编译器级的异常处理。main函数只是建立一个_try/_except块。_try块中的是一个对HomeGrownFrame函数的调用。函数与前面的MYSEH程序中的代码很类似。它在堆栈上创建了一个EXCEPTION_REGISTRATION记录并使FS:[0]指向此纪录。在建立了新的处理程序后,函数主动引起异常,向NULL指针处进行写入:

  *(PDWORD)0=0;

  这里的异常回调函数,也就是_except_handler,与前面的那个很不一样。代码先打印出函数的ExceptionRecord参数的异常代号和标志。后面会说明打印此异常标志的原因。因为这个_except_handler函数并不能修复引起异常的代码,它就返回ExceptionContinueSearch。这就使得操作系统继续查找链表中的下一个EXCEPTION_REGISTRATION记录。下一个异常回调是用于main函数中的_try/_except代码的。_except块只是打印“Caughttheexceptioninmain()”。此处的异常处理就是简单地将其忽略。此处的一个关键的问题就是执行控制流。当处理程序不能处理异常时,就是在拒绝使控制流在此处继续。接受异常的处理程序则在所有异常处理代码完成之后决定控制流在哪里继续。这一点并不那么显而易见。

  当使用结构化异常处理时,如果一场处理程序没能处理异常,则函数可以用一种非正常的方式退出。例如,MYSEH2的HomeGrownFrame函数中的处理程序并没有处理异常。因为异常处理链中后面的某个处理程序(main函数)处理了此异常,所以引起异常的指令之后的printf从未获得执行。从某种意义上说,使用结构化异常处理和使用运行时库函数setjmp和longjmp差不多。

  若是运行MYSEH2,其输出可能会令人惊讶。看上去似乎调用了两次_except_handler函数。第一次是可以理解的,那第二次又是怎么回事呢?

作者:Matt Pietrek    责编:豆豆技术应用

正在加载评论...