0x00 异常处理结构
__try
{
// guarded body of code
}
__except (filter-expression)
{
// exception-handler block
}
Filter-expression为以下值
EXCEPTION_EXECUTE_HANDLER
EXCEPTION_CONTINUE_SEARCH
EXCEPTION_CONTINUE_EXECUTION
0x01 文档
https://docs.microsoft.com/en-us/windows/win32/debug/structured-exception-handling
0x02 实验
实验1
_try
{
RaiseException(0,0,0, 0); //触发异常
printf("1\n");
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("2\n");
}
结果: 打印 2
结论: filter-expression 为 EXCEPTION_EXECUTE_HANDLER 时,执行exception-handler block
实验2
__try
{
RaiseException(0, 0, 0, 0); //触发异常
printf("1\n");
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("2\n");
}
结果: 系统报错
结论: EXCEPTION_CONTINUE_SEARCH不能单独使用
实验3:
__try
{
RaiseException(0, 0, 0, NULL); //触发异常
printf("1\n");
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{
printf("2\n");
}
结果: 打印 1
结论: filter-expression 为 EXCEPTION_CONTINUE_EXECUTION 时,不执行exception-handler block,而是回到异常触发点继续执行
实验4
__try
{
__try
{
RaiseException(0, 0, 0, 0); //触发异常
printf("1\n");
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("2\n");
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("3\n");
}
结果: 打印 3
结论: filter-expression 为 EXCEPTION_CONTINUE_SEARCH 时,当前的 exception-handler block不执行,然后将异常交给外部的异常处理,由外部的异常处理判断.
实验5
__try
{
__try
{
__try
{
RaiseException(0, 0, 0, 0); //触发异常
printf("1\n");
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("2\n");
}
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("3\n");
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("4\n");
}
结果: 打印 4
结论: 进一步验证实验4
实验6
__try
{
__try
{
__try
{
RaiseException(0, 0, 0, 0); //触发异常
printf("1\n");
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("2\n");
}
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("3\n");
}
}
__except (EXCEPTION_CONTINUE_SEARCH)
{
printf("4\n");
}
结果: 报错
结论: 当前程序如果通过EXCEPTION_CONTINUE_SEARCH将异常继续抛出,则程序会终止
实验7
__try
{
RaiseException(0, 0, 0, 0); //触发异常
printf("1\n");
}
__except (GetExceptionCode() == 0 ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
printf("4\n");
}
结果: 打印 4
结论: filter-expression可以为表达式,从而决定如何处理异常(例如:我们关心的则处理,不关心的可以继续向外抛出)
实验8
DWORD FilterFunction()
{
printf("1 ");
return EXCEPTION_EXECUTE_HANDLER;
}
VOID main(VOID)
{
__try
{
RaiseException(0, 0, 0, 0); //触发异常
}
__except (FilterFunction())
{
printf("3\n");
}
}
结果: 打印 1 3
结论: filter-expression可以为函数,必须返回特定的值.且执行FilterFunction()在执行exception-handler block
实验9
DWORD FilterFunction()
{
printf("1 ");
return EXCEPTION_EXECUTE_HANDLER;
}
VOID main(VOID)
{
__try
{
__try
{
RaiseException(0, 0, 0, 0); //触发异常
}
__finally
{
printf("2 ");
}
}
__except (FilterFunction())
{
printf("3\n");
}
}
结果: 打印 1 2 3
结论: 执行顺序 filter-expression > termination-handler block > exception-handler block