Win32-00 Windows编程前奏--结构化异常处理

想象一下要写一个不会因为异常而终止的程序---------有足够的内存,不会有非法的指针,并且要访问的文件也是始终存在,也不会发生死锁。在这样的条件下写代码一定时愉快的事情。代码将会容易编写,容易阅读,并且也容易理解。再也不需要为代码里随处可见的if语句等儿烦恼。

结构化异常处理(structured exception hangding,SEH)就可以为你解决这些事情它把主要功能编写和软件异常处理分开,让我们能集中注意力完成手头的工作,而后再去处理软件可能的异常。


SEH包含两方面功能:

1,终止处理;

2,异常处理;


一,终止处理

语法为:

try{
//Guarded body
...
}
_finally{
//Termination hander
...
}


除非在执行try块的时候调用了 ExitProcess,ExitThread ,TerminateProcess,TerminateThread(调用这几个函数引起的各种问题以后再叙述),否则_finally块内的代码一定能执行。


下面有几个小例子来解释系统如何执行代码。

1,Func1 (信号量的释放) 注释中的序号为代码执行顺序

DWORD Func1()
{
    //1,
    DWORD temp ;
    ......
     _try{
      //2,
      ......
      WaitForSingleObject(g_hSem,INFINITE;
      ......
   }
     _finally{
        //3,
        ReleaseSemapore(g_Shem,1,NULL);
    }
   //4,
    return temp;
}

这个例子看起来并没有给我们带来什么方便,它等待一个信号量,然后做一些操作后接着释放信号量资源。

下面我们稍微改动

2,Func2

DWORD Func2()
{
    //1,
    DWORD temp ;
    ......
     _try{
      //2,
      ......
      WaitForSingleObject(g_hSem,INFINITE;
      temp = 5;
       ......
      return temp;
 }
     _finally{
        //3,
      printf("ReleaseSemapore\n"); 
      ReleaseSemapore(g_Shem,1,NULL);
    }
   //4,
     temp = 9; 
     return temp;
}
那对于这种情况呢?函数返回值是多少?

函数最后返回的是5,并且信号量最终也是释放了。虽然在_try块中调用return不是一个聪明的做法。

当return语句试图退出try块的时候,编译器会保证return在 finally块之后执行,而后面的代码自然就没机会执行了。


3,Func3

终止处理程序将真正证明它的价值。

DWORD Func1()
{
    //1,
    DWORD temp ;
    ......
     _try{
      //2,
      ......
      WaitForSingleObject(g_hSem,INFINITE;
      temp = FuncOther();
       ......
   }
     _finally{
        //3,
        ReleaseSemapore(g_Shem,1,NULL);
    }
   //4,
    return temp;
}
假设FuncOther 存在一个缺陷会导致程序访问非法的内存。

如果没有SEH,这种情况下, 最终导致Windows错误报告,弹出终止对话框。一旦用户选择取消这个对话框,进程就会终止,但此时信号量没有释放,其他进程会无休止的等待。

而在SEH框架下,这个问题就得到完美的解决,信号量一定能得到释放。


二,异常处理

语法为:

try{
//Guarded body
...
}
_except(exception filter){
//exception hander
...
}


1,Func4

DWORD Funcmeister2() 
{
   DWORD dwTemp = 0;
   //1. Do any processing here.
   ...
   __try 
   {
      //2. Perform some operation(s).
      dwTemp = 5 / dwTemp;    // Generates an exception
      dwTemp += 10;           // Never executes
   }
   __except(EXCEPTION_EXECUTE_HANDLER) //3
   {
      //4. Handle an exception.
      MessageBeep(0);
      ... 
    }
    //5. Continue processing.
    return(dwTemp);
}

try块中,一个指令视图用5除以0,CPU会捕获到这个事件,并抛出一个硬件异常。当异常被抛出时,系统定位到exception块的开始处,并对异常过滤程序的表达式求值。

EXCEPTION_EXECUTE_HANDLER                                                                  1               异常执行处理

EXCEPTION_CONTINUE_SEARCH                                                                  0                异常继续查找

EXCEPTION_CONTINUE_EXECUTION                                                           -1                异常继续执行


异常处理过程如下图:

2,关于EXCEPTION_EXECUTE_HANDLER


这个值是告诉系统,我知道可能会产生这个异常,并且我要处理它。

处理过程完成后,程序会接下来执行exception块的下一条语句。


3,关于EXCEPTION_CONTINUE_EXECUTION
这个值是告诉系统,在执行了异常处理代码后,再次执行发送异常的那句代码。


4,EXCEPTION_CONTINUE_SEARCH

这个值是告诉系统,这里没有处理这个异常的代码,需要寻找最近的try块的异常处理程序。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值