Windows SEH之全局展开
这里说说SEH中让人费解的全局展开部分。在此之前先复习一下结构化异常处理的流程:

当异常过滤程序的计算结果为EXCEPTION_EXECUTE_HANDLER时,系统会执行全局展开。
下面这张图片展示了全局展开的流程图(对应上图中全局展开的部分):

当一个异常出现的时候,会从检查当前异常的try块是否可以处理该异常(也就是看看是不是有except块,且Filter的计算结果是否为EXCEPTION_EXECUTE_HANDLER),如果不可以则检查当前try块中是否有finally块,有则执行,然后沿着调用链向上查找(也就是看看上级函数中是否有try-except块可以处理该异常)。如果找到可以处理该异常的except块,则执行异常处理程序,执行结束后从异常处理程序的下一条语句开始继续运行。
示例分析一
下面来看一个例子:
#include <iostream>
#include <Windows.h>
int ExceptionFilter()
{
std::cout << "ExceptionFilter" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
void funcA()
{
__try
{
std::cout << "funcA try" << std::endl;
// exception
*(PBYTE)NULL = 5;
std::cout << "funcA try end" << std::endl;
}
__except (ExceptionFilter())
{
std::cout << "funcA ExceptionFilter" << std::endl;
}
}
void funcB()
{
__try
{
std::cout << "funcB try" << std::endl;
funcA();
std::cout << "funcB try end" << std::endl;
}
__finally
{
std::cout << "funcB finally" << std::endl;
}
}
void funcC()
{
__try
{
std::cout << "funcC try" << std::endl;
funcB();
std::cout << "funcC try end" << std::endl;
}
__finally
{
std::cout << "funcC finally" << std::endl;
}
}
int main(int argc, char const *argv[])
{
// C -> B -> A
funcC();
return 0;
}
运行结果如下:

示例分析二
#include <iostream>
#include <Windows.h>
int ExceptionFilter()
{
std::cout << "ExceptionFilter" << std::endl;
return EXCEPTION_EXECUTE_HANDLER;
}
void funcA()
{
__try
{
std::cout << "funcA try" << std::endl;
// exception
*(PBYTE)NULL = 5;
std::cout << "funcA try end" << std::endl;
}
__finally
{
std::cout << "funcA finally" << std::endl;
}
}
void funcB()
{
__try
{
std::cout << "funcB try" << std::endl;
funcA();
std::cout << "funcB try end" << std::endl;
}
__except (ExceptionFilter())
{
std::cout << "funcB ExceptionFilter" << std::endl;
}
}
void funcC()
{
__try
{
std::cout << "funcC try" << std::endl;
funcB();
std::cout << "funcC try end" << std::endl;
}
__finally
{
std::cout << "funcC finally" << std::endl;
}
}
int main(int argc, char const *argv[])
{
// C -> B -> A
funcC();
return 0;
}
运行结果如下:

网硕互联帮助中心




评论前必须登录!
注册