程序异常控制(转)
有时我们希望在程序崩溃时保存一些信息来帮助调试,尤其是在Release版程序
这时我们可以使用SetUnhandledExceptionFilter函数,MSDN对函数的描述是这样的
SetUnhandledExceptionFilterThe SetUnhandledExceptionFilter function enables an application to supersede the top-level exception handler of each thread and process. After calling this function, if an exception occurs in a process that is not being debugged, and the exception makes it to the unhandled exception filter, that filter will call the exception filter function specified by the lpTopLevelExceptionFilter parameter. LPTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter ); ParametersReturn ValuesThe SetUnhandledExceptionFilter function returns the address of the previous exception filter established with the function. A NULL return value means that there is no current top-level exception handler. RemarksIssuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process. The exception handler specified by lpTopLevelExceptionFilter is executed in the context of the thread that caused the fault. This can affect the exception handler’s ability to recover from certain exceptions, such as an invalid stack. |
上面的红字是我做的重点标注,通过注册的回调函数的返回值我们可以控制是否弹出程序崩溃的对话框。
EXCEPTION_EXECUTE_HANDLER 表示结束程序但不弹出崩溃对话框。从宏的拼写上可以认为我处理了这个异常
EXCEPTION_CONTINUE_EXECUTION 表示错误已经被修复,继续执行,这是一个不应该被使用的返回值,因为一个设计良好的程序不会把错误处理放在这个步骤中。
EXCEPTION_CONTINUE_SEARCH 表示结束程序并弹出一个崩溃对话框。从宏的拼写上可以认为我没有处理这个异常,请继续搜索其他的handler
事实上只能有一个回调函数被同时注册,因此如果我们想让所有注册过的回调函数都能执行到的话需要接收SetUnhandledExceptionFilter 的返回值,即the address of the previous exception filter并在回调函数中调用,像这样
LPTOP_LEVEL_EXCEPTION_FILTER g_preFilter; LONG WINAPI func( PEXCEPTION_POINTERS pExceptionInfo ) { //... if(g_preFilter) return g_preFilter(pExceptionInfo); else return EXCEPTION_CONTINUE_SEARCH; } int main () { g_preFilter = SetUnhandledExceptionFilter(func); ///... return 0; }
我们也可以做成,只在preFilter执行返回EXCEPTION_CONTINUE_SEARCH的时候才处理这个异常
LPTOP_LEVEL_EXCEPTION_FILTER g_preFilter; LONG WINAPI func( PEXCEPTION_POINTERS pExceptionInfo ) { LONG res; if(g_preFilter==NULL || (res = g_preFilter(pExceptionInfo)) == EXCEPTION_CONTINUE_SEARCH) { //... return EXCEPTION_CONTINUE_SEARCH; } else { return res; } } int main () { g_preFilter = SetUnhandledExceptionFilter(func); ///... return 0; }
这要根据实际的应用情况决定。
关于如何保留下当时的调用堆栈等信息是个复杂的主题,不过已经有前辈做过这件事了。
附件中包含一个异常处理机制,会在程序崩溃时生成一份报告文件和一份DUMP文件。
原文:http://www.cnitblog.com/luckydmz/archive/2012/01/04/77011.html
天气
分类
标签
存档
- 2024年3月(1)
- 2024年2月(1)
- 2023年8月(1)
- 2023年7月(1)
- 2023年5月(1)
- 2022年9月(1)
- 2022年8月(1)
- 2022年1月(2)
- 2021年10月(1)
- 2021年7月(1)
- 2020年9月(1)
- 2020年8月(1)
- 2020年7月(1)
- 2020年6月(2)
- 2020年5月(1)
- 2019年10月(1)
- 2019年9月(2)
- 2019年7月(1)
- 2019年1月(4)
- 2018年12月(1)
- 2018年11月(1)
- 2018年10月(5)
- 2018年8月(2)
- 2018年7月(5)
- 2018年6月(2)
- 2018年4月(1)
- 2018年2月(1)
- 2017年12月(2)
- 2017年11月(1)
- 2017年10月(4)
- 2017年9月(3)
- 2017年8月(2)
- 2017年5月(2)
- 2017年4月(7)
- 2017年2月(1)
- 2016年12月(1)
- 2016年11月(2)
- 2016年10月(3)
- 2016年6月(2)
- 2016年3月(1)
- 2016年1月(2)
- 2015年12月(3)
- 2015年11月(3)
- 2015年10月(1)
- 2015年9月(1)
- 2015年8月(2)
- 2015年7月(2)
- 2015年5月(1)
- 2015年4月(1)
- 2015年2月(1)
- 2015年1月(1)
- 2014年12月(4)
- 2014年11月(1)
- 2014年10月(1)
- 2014年8月(4)
- 2014年7月(2)
- 2014年6月(1)
- 2014年2月(2)
- 2014年1月(2)
- 2013年12月(26)
- 2013年10月(2)