_set_se_translator这个函数的目的就是把SEH异常转换成C++异常,这样用一个try catch块就能保证代码里面产生的任何异常都能被捕获到,从而达到程序不崩溃的目的。
但是VS2005之后的版本,微软增加了一些新的异常机制,新机制在出现错误时默认不通知应用程序,这时程序就崩溃了。
VS2005添加了这两个函数:_set_invalid_parameter_handler、_set_purecall_handler, 通过它们可以设置自己的异常处理函数。
经过测试,如果程序出现了Invalid Parameter的异常(比如atoi(null),就会出现这种异常),_set_se_translator会失效,try catch块捕获不到SEH异常。但是我这样设置的
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
//禁止CRT的异常处理修改SetUnhandledExceptionFilter
DisableSetUnhandledExceptionFilter();
异常处理函数却可以正常捕获到SEH异常,dmp文件也可以正常生成。因为是未经处理的程序,所以程序会崩溃退出。
因此要想确保try catch块能够捕获到所有的异常,还必须调用_set_invalid_parameter_handler、_set_purecall_handler这两个函数,设置自己的处理函数,在处理函数里面抛出一个标准的C++异常(比如throw 1),这样try catch就可以捕获到了。
_set_invalid_parameter_handler(myInvalidParameterHandler);
_set_purecall_handler(myPurecallHandler);
void myInvalidParameterHandler(const wchar_t* expression,
const wchar_t* function,
const wchar_t* file,
unsigned int line,
uintptr_t pReserved)
{
OutputDebugStringA("Invalid Parameter Expression:");
OutputDebugStringW(expression);
// 必须抛出异常,否则无法定位错误位置
throw 1;
}
void myPurecallHandler(void)
{
OutputDebugStringA("In _purecall_handler.");
// 必须抛出异常,否则无法定位错误位置
throw 1;
}
经过测试: _set_se_translator这个函数只对当前线程有用,其它线程要想转换SEH的异常就必须调用_set_se_translator一次。而_set_invalid_parameter_handler、_set_purecall_handler这两个函数与SetUnhandledExceptionFilter一样,是全局的,只需调用一次即可。