一直以来写windows应用层程序没有注意“未处理异常”,所以也不会调用SetUnhandledExceptionFilter处理“未处理异常”。最近注意到“未处理异常”需要写程序来“处理”,即调用上面SetUnhandledExceptionFilter,并将你所希望“未处理异常”发生时调用什么函数作为参数;其目的无非是设置一个回调函数了,呵呵。当有未处理异常,则操作系统会自动调用你设置的回调函数。
呵呵,基本方法会了,但有个问题就是这个回调函数无法使用V6.0或VSXX系列的调试器进行调试,甚是郁闷。后来查了《软件调试》一书,在P287页11.3.3节找到答案,原文如下“对于第一轮(异常)处理机会,KiDispatchException会试图先将该异常分发给用户态的调试器”,呵呵,所以当异常发生时,并不会直接到我们设置的未处理异常函数内,而是把异常处理的机会抛给了调试器(VC6)。这个原因找到了,有没有方法可以调试呢?
有的。请看下面的代码:
LONG WINAPI MyUnhandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo){ printf("exception filter/n"); //line 3
return EXCEPTION_EXECUTE_HANDLER;}
int main(int argc, char* argv[]){ SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); int *p = 0; *p = 3; return -1;}
如果你直接在line 3位置处设置断点,肯定是不会到这个断点的。VC6的调试器只会抛一个“Unhandled exception.....”,永远不会到line3。如改成下面的代码就好了:
LONG WINAPI MyUnhandledExceptionFilter(_EXCEPTION_POINTERS *ExceptionInfo){ printf("exception filter/n"); // line 3'
return EXCEPTION_EXECUTE_HANDLER;}
int main(int argc, char* argv[]){ //SetUnhandledExceptionFilter(MyUnhandledExceptionFilter); __try { int *p = 0; *p = 3; } __except(EXCEPTION_EXECUTE_HANDLER == MyUnhandledExceptionFilter(GetExceptionInformation())) { printf("something happened./n"); } return -1;}
此时你在line 3'位置处设置断点,则一定会断下来,赶快试一下吧。呵呵。