转载请注明来源:https://www.cnblogs.com/hookjc/
碰到某些程序崩溃时弹出带红色叉叉的错误窗口或者是叫你选择调试或关闭的窗口,很碍眼。不过平时也没去理它,点掉就好。
今天客户反映我们的程序崩溃后就起不来了,其实我们为了方便无人化管理,做了一个守护进程。如果程序异常退出就会重启那个程序,这在linux下没问题,程序崩溃了就直接退出返回非零值,但是window就bug了,搞不好就给你弹出个错误对话框,你不点掉其实程序就没退出,守护进程就不知道这个程序是否崩溃,于是这个程序就永远死在那个窗口上了。现在这不仅碍眼,还碍事!于是着手摆平之。
先是晚上搜到可以修改注册表来组织程序或系统的弹出对话框,参考:http://technet.microsoft.com/en-us/library/cc976167.aspx。不过这不可行,我们只是希望我们的程序不会弹出对话框,尽量少改系统的。而且试了下发现还是会弹出来,就是那个werfault.exe进程,xp下可能不会。算了,这条路不走了。
用代码肯定也有办法解决。你看人家qq什么的奔溃了有弹出的都是自家的温馨提示,我们不需要温馨提示,只要返回非零值就好。
万能的Google一下子就搜出结果来了。原来Microsoft对c和c++进行了扩展,支持异常处理,而且貌似标准c++里的异常处理也是它的一个封装。Microsoft的异常处理函数是__try,__except。
先试了这么个简单的例子
[cpp]view plaincopy
- #include <windows.h>
- #include <excpt.h>
- #include <stdio.h>
- #define CRASH_SILENTLY 1
- #if defined(_MSC_VER) && CRASH_SILENTLY
- #include <excpt.h>
- #define Q_TRY_BEGIN __try {
- #define Q_TRY_END }
- //EXCEPTION_EXECUTE_HANDLER
- #define Q_EXCEPT __except(EXCEPTION_EXECUTE_HANDLER) { \
- printf("Shit happens!\n");fflush(NULL); \
- return 1;}
- #else
- #define Q_TRY_BEGIN
- #define Q_TRY_END
- #define Q_EXCEPT
- #endif
- int main(int, char**)
- {
- Q_TRY_BEGIN
- int *a = 0;
- *a = 0;
- Q_TRY_END
- Q_EXCEPT
- printf("Exiting 0...\n");
- fflush(NULL);
- return 0;
- }
如果把CRASH_SILENTLY定义为0,那么在程序崩溃就会弹出对话框,设为一就只打印Shit happens!然后就返回。
__except的参数有三种,详细内容见http://msdn.microsoft.com/en-us/library/s58ftw19%28v=vs.80%29.aspx,我就不抄了。
其实为什么系统会弹出这么一个对话框呢?其实在vc运行库中顶层函数也用了__try, __except的异常捕获机制。不知您看了__except的参数了没,我的示例程序里是EXCEPTION_EXECUTE_HANDLER,表示异常被识别,就在__except后面的代码段进行异常处理。如果是EXCEPTION_CONTINUE_SEARCH,那么异常会继续被派发到外层,这最外层就是vc库,vc库它的处理手段就是碍眼又碍事的对话框!
上面这个程序只是演示用的,很简单。然后我就满怀希望地对公司的程序也做了类似的处理,然后悲剧发生了,竟然编译都通不过!编译错误是C2712:cannot use __try in functions that require object unwinding。于是又google了一番。msdn真的很棒,资料丰富,这下有时msdn上的方法解决的。详见http://msdn.microsoft.com/en-us/library/xwtb73ad%28VS.80%29.aspx
With /EHsc, a function with structured exception handling cannot have objects that require unwinding (destruction).
我们的程序里出现了有析构函数的对象,同时编译参数又有/EHsc,于是出现编译错误了。
更改:vs-》工程-》属性-》c/c++-》Code Generation-》Enable C++ Exception-》NO
来源:python脚本自动迁移
