使用SetUnhandledExceptionFilter让程序优雅的崩溃

来源:互联网 发布:长颈鹿锯锹成虫淘宝 编辑:程序博客网 时间:2024/05/22 00:25
虽然是大公司的产品,QQ它还是会在我们的折腾下崩溃的,但是它总是崩溃的很优雅,还要弹出自己的对话框来结束。并且发送报告,去掉了系统默认的发送报告的对话框。

所以一拍脑袋,想让自己的程序崩溃的体面一点。

自己想了大概的思路,觉得可以用一个进程来监控目标程序。的确也可以拿到了目标程序崩溃的信息,知道它什么时候崩溃的,也可以做额外的操作,但是这样是没办法把默认的发送错误的对话框去掉的。

然后又有人说是不是采用了类似钩子的方法把这个东西在哪里勾掉了。

最后网上查了一番,发现SetUnhandledExceptionFilter这个函数解决了一切。

总结了下搜到的资料,这个函数的返回值有三种情况:



EXCEPTION_EXECUTE_HANDLER equ 1 表示我已经处理了异常,可以优雅地结束了  
EXCEPTION_CONTINUE_SEARCH equ 0 表示我不处理,其他人来吧,于是windows调用默认的处理程序显示一个错误框,并结束  
EXCEPTION_CONTINUE_EXECUTION equ -1 表示错误已经被修复,请从异常发生处继续执行 



具体使用方法如下:

[cpp] view plain copy
print?
  1. #include   <windows.h>     
  2.      
  3.  long   __stdcall   callback(_EXCEPTION_POINTERS*   excp)     
  4.  {     
  5.  MessageBox(0,”Error”,“error”,MB_OK);     
  6.  printf(”Error   address   %x/n”,excp->ExceptionRecord->ExceptionAddress);     
  7.  printf(”CPU   register:/n”);     
  8.  printf(”eax   %x   ebx   %x   ecx   %x   edx   %x/n”,excp->ContextRecord->Eax,     
  9.  excp->ContextRecord->Ebx,excp->ContextRecord->Ecx,     
  10.  excp->ContextRecord->Edx);     
  11.  return   EXCEPTION_EXECUTE_HANDLER;     
  12.  }  
  13.      
  14.  int   main(int   argc,char*   argv[])     
  15.  {     
  16.  SetUnhandledExceptionFilter(callback);     
  17.  _asm   int   3   //只是为了让程序崩溃  
  18.  return   0;     
  19.  }  
 #include   <windows.h>     long   __stdcall   callback(_EXCEPTION_POINTERS*   excp)     {     MessageBox(0,"Error","error",MB_OK);     printf("Error   address   %x/n",excp->ExceptionRecord->ExceptionAddress);     printf("CPU   register:/n");     printf("eax   %x   ebx   %x   ecx   %x   edx   %x/n",excp->ContextRecord->Eax,     excp->ContextRecord->Ebx,excp->ContextRecord->Ecx,     excp->ContextRecord->Edx);     return   EXCEPTION_EXECUTE_HANDLER;     }  int   main(int   argc,char*   argv[])     {     SetUnhandledExceptionFilter(callback);     _asm   int   3   //只是为了让程序崩溃  return   0;     }


成功以后,去翻了下windows核心编程,发现里面已经有提到了这个函数了。只是由于学艺不精,暂时没有去拜读这么高深的书。所以一直不知道。

问了下同事,发现他立马说出了可以用这个函数(说个大概的函数名)来实现,并且提出在win32下是可以的,但是在MFC可能捕获不到这个异常。认为MFC下有自己的一套机制来解决。

后来我半信半疑,在MFC下一试,竟然可以o(∩_∩)o…

并且我是在一个MDI程序下的一个DLL中发生的一个异常,竟然也掉近了回调函数,心理暗爽啊。

然后又在一个出错的控件中试了一下,竟然控件的错误也能捕获到。怎一爽字了得!
0 0