1.结构化异常处理
SEH
是由编译器实现的,不同编译器在实现SEH
时会有些区别。它是Winodws
特有的技术。
SEH
和C++
异常是两种不同的异常机制。在VC
中C++
异常是基于SEH
实现的。
2.结构化异常处理用法
(1)__try
__try
后必须接__finally
和__except
中的一个,且只能有一个。
若__try
中有return,break,continue
等语句,在执行这些语句前,系统会先调用__finally
中的代码然后再跳回到return,break,continue
继续执行。
若__try
中有ExitThread,ExitProcess
等语句,线程或程会立刻退出而不会执行__finally
中的代码。
(2)__leave
若__try
中有__leave
,代码会从该处跳到__try
的未端,直接执行__finally
中的代码,然后继续向下执行,而不会跳回到原处。
建议将程序中的return,break,continue
等语句换成__leave
(3)__finally
它不会处理程序中的异常,但会处理程序中的goto,break,continue,return
等语句。
AbnormalTermination()
函数只能在__finally
块中用,它用于判断程序是因顺序执行到__finally
处,还是因return,goto
等语句跳到__finally
处。
(4)__except
只有当__try
块中的代码产生异常时,__except
中的代码才会执行。
若程序中有异常且无__except
,那么程序会异常退出。
异常处理和软件异常
1.理解异常过虑器表达式
__try
{//some code}
__except(
过虑器表达式)
{//code for exception handling}
2.过虑器表达式的值
值只能为以下三种的一个
(1) EXCEPTION_EXECUTE_HANDLER
程序中遇到异常后,会立刻__except
中的代码,然后接着__except
块后的代码继续执行。
(2) EXCEPTION_CONTINUE_EXECUTION
程序中遇到异常后,会立刻__except
中的代码,然后跳回__try
中发生异常的代码处,重新执行产生异常处的代码。
(3) EXCEPTION_CONTINUE_SEARCH
程序中遇到异常后,__except
中的代码不会被执行,而是寻常外层__try
所对应的__except
。
3.举例
void FunclinRoosevelt2()
{
TCHAR *pchBuffer = NULL;
__try
{
FuncAtude2(pchBuffer);
}
__except (OilFilter2(&pchBuffer))
{
MessageBox(...);
}
}
void FuncAtude2(TCHAR *sz)
{
*sz = TEXT('"0');
}
LONG OilFilter2 (TCHAR **ppchBuffer)
{
if (*ppchBuffer == NULL)
{
*ppchBuffer = g_szBuffer;
return(EXCEPTION_CONTINUE_EXECUTION);
}
return(EXCEPTION_EXECUTE_HANDLER);
}
4. GetExceptionCode
它返回一个DWORD
值,该值用于分析程序产生异常的原因。
DWORD Error
的内部结构
__try
{
x=0;
y = 4 / x; // y is used later so this statement is not optimized away
...
}
__except (
(GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH
)
{
// Handle divide by zero exception.
}
4.SetUnhandledExceptionFilter
SetUnhandledExceptionFilter
设置全局异常处理代码。若程序中的代码在执行时产生异常,且无相应的异常处理代码,
那么系统会自动调用用户设置的全局异常处理代码处理这些异常。
C/C++
程序在启动时,会自动安装一个异常处理函数UnhandledExceptionFilter
注:SetUnhandledExceptionFilter(NULL),
会重新把UnhandledExceptionFilter
置为全局异常处理函数
5.举例
LONG WINAPI TopLevelUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
printf("This is global handler set by SetUnhandledExceptionFilter"n");
return 0?EXCEPTION_CONTINUE_EXECUTION :1?EXCEPTION_EXECUTE_HANDLER:EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
SetUnhandledExceptionFilter(TopLevelUnhandledExceptionFilter);
__try{
int *p = NULL;
*p = 0;}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf(""nok");
}
printf("Recovered from exception handler"n");
return 0;
}
6.Common API:
RaiseException GetExceptionInformation