Windows终止异常程序

注意 : 不要将结构化异常处理同 C++ 的异常处理相混淆 .C++ 异常处理是一种不同形式的异常处理 , 其形式是使用 C++ 关键字 catch throw. 微软的 Visual  C++ 也支持 C++ 的异常处理 , 并且在内部实现上利用了已经引入到编译程序和 Windows 操作系统的结构化异常处理的功能 .
SEH 实际包含两个主要功能 : 结束处理 (termination handling) 和异常处理 ( exception handling).
__try __finally 关键字用来标出结束处理程序两段代码的轮廓 . 在上面的代码段中 , 操作系统和编译程序共同来确保结束处理程序中的 __finally 代码块能够被执行 , 不管保护体 (try ) 是如何退出的 . 不论你在保护体中使用 return, 还是 goto, 或者是 longjump, 结束处理程序 (finally ) 都将被调用 .
当编译程序看到 try 块中的 goto 语句 , 它首先生成一个局部展开来执行 finally 块中的内容 .
注意 : 当控制流自然地离开 try 块并进入 finally 块时 , 进入 finally 块的系统开销是最小的 . x86  CPU 上使用微软的编译程序 , 当执行离开 try 块进入 finally 块时 , 只有一个机器指令被执行 , 读者可以在自己的程序中注意到这种系统开销 . 当编译程序要生成额外的代码 , 系统要执行额外的工作时 , 系统开销就很值得注意了 .
尽管结束处理程序可以捕捉 try 块过早退出的大多数情况 , 但当线程或进程被结束时 , 它不能引起 finally 块中的代码执行 . 当调用 ExitThread ExitProcess , 将立即结束线程或进程 , 而不会执行 finally 块中的任何代码 . 另外 , 如果由于某个程序调用 TerminateThread TerminateProcess, 线程或进程将死掉 ,finally 块中的代码也不执行 . 某些 C 运行期函数 ( 例如 abort) 要调用 ExitProcess, 也使 finally 块中的代码不能执行 . 虽然没有办法阻止其他程序结束你的一个线程或进程 , 但你可以阻止你自己过早调用 ExitThread ExitProcess.
实际上 , 最好将 return continue break goto 等语句从结束处理程序的 try 块和 finally 块中移出去 , 放在结束处理程序的外面 . 这样做会使编译程序产生较小的代码 , 因为不需要再捕捉 try 块中的过早退出 , 也使编译程序产生更快的代码 ( 因为执行局部展开的指令也少 ). 另外 , 代码也更容易阅读和维护 . 为了帮助我们尽可能避免写出让 try 块提前退出的代码, Microsoft 为它的 C/C++ 编译器加入一个关键字 :__leave, 会导致代码执行控制流跳转到 try 块的结尾, 这是正常进入 finally 语句, 开销最小 .
BOOL  Fun1()
{
      BOOL  bRet  FALSE;
      __try
      {
           …//
           if(NULL  ==  pBuff)
                 __leave;
      }
      __finally
      {
          
           }
     r eturn  bRet;
}
强制执行 finally 块的三种情况 :
1) 正常控制流 : try 块到 finally 的正常代码控制流 ;
2) 局部展开 : try 块中的提前退出 ( goto, longjump, continue, break, return 等语句引起 ) 将控制流强制转入 finally ;
3) 全局展开 .
由于以上三种情况中某一种的结果而导致 finally 块中的代码开始执行 . 为了确定是哪一种情况引起 finally 块执行 , 可以调用内部函数 AbnormalTermination. 这个内部函数只在 finally 块中调用 , 返回一个 Boolean . 指出与 finally 块相结合的 try 块是否过早退出 . 换句话说 , 如果控制流离开 try 块并自然进入 finally ,AbnormalTermination 将返回 FALSE. 如果控制流非正常退出 try 块—通常由于 goto return break continue 语句引起的局部展开 , 或由于内存访问违规或其他异常引起的全局展开—对 AbnormalTermination 的调用将返回 TRUE.
DWORD  Fun2()
{
      __try
      {
          
      }
      __finally
      {
          i f(!AbnormalTermination())
           {
                …// 正常控制流
           }
          e lse
           {
                ...// 局部展开
           }
      }
     r eturn  0;
}

你可能感兴趣的:(Windows终止异常程序)