下面分情况说明:
1、结束处理程序:
SEH中引入了try、finally对来进行结束化程序处理。具体的执行顺序可参考对finally的两种分类:
a)从try块中进入finally块的正常控制流。
b)局部展开:从try块的过早退出(goto,longjump,continue,break,return)等强制转移到finally块。
下面举例说明:
int f1()
{
//1.do any processing here.
……
__try
{//2.
WaitForSingleObject(g_hSem,INFINITE);
g_dwProtectedData=5;
dwTemp=g_dwProtectedData;
}
__finally
{//3.
ReleaseSemaphore(g_hSem,1,NULL);
}
//4.
return(dwTemp);
}
上面这个例子属于情况a)从try中自然执行到finally中。
int f2()
{
//1.do any processing here.
……
__try
{//2.
WaitForSingleObject(g_hSem,INFINITE);
g_dwProtectedData=5;
dwTemp=g_dwProtectedData;
return(dwTemp);
}
__finally
{//3.
ReleaseSemaphore(g_hSem,1,NULL);
}
//4.
dwTemp=9;
return(dwTemp);
}
在这个例子中同1的区别是在try中加入了return 并且在finally下面的return 之前加入了dwTemp=9;这样就属于情况b),导致局部展开,执行顺序为在进入try后执行到return之前,finally中的语句先被执行,然后再执行try中的return语句,使进程结束。结果返回5,而不是9。
2.异常处理程序
除了try,finally对意外,还有try,exception对。
对于异常其表达式的值只能是以下三种:EXCEPTION_CONTINUE_SEARCH ,EXCEPTION_EXECUTE_HANDLER,EXCEPTION_EXECUTE_HANDLER。该标识符在文件excpt.h中定义。
对于EXCEPTION_EXECUTE_HANDLER,当出现异常,将会执行一个全局展开(global unwind),这个全局展开使所有那些在处理异常的try,except块之后开始执行但未完成的try,finally块恢复执行。举例如下
void f3()
{
//1.do any processing here.
__try{//2.
fun();
}
__except(/*6.*/EXCEPTION_EXECUTE_HANDLER){
//8.
……
}
}
void fun(){
DWORD dwTemp=0;
//3 do any processing here.
__try{
//4.
WaitForSingleObject(g_hSem,INFINITE);
//5.
g_dwProtectData=5/dwTemp;
}
__finally{
//7.
ReleaseSemaphore(g_hSem,1,NULL);
}
}
对于EXCEPTION_EXECUTE_HANDLER指从引起异常的指令处继续执行。
对于EXCEPTION_CONTINUE_SEARCH,在调试树中进行异常继续查找,直到找到不为EXCEPTION_CONTINUE_SEARCH。如果对于所有的except中,过滤值都为EXCEPTION_CONTINUE_SEARCH时,就追溯到系统的except中,调用UnhandledExceptionFilter()。这个函数负责显示一个消息框,指出有一个进程的线程存在未处理的异常,并且能让用户结束或调试这个进程。