MessageBox“exception程序终止”让我的应用程序继续运行

…有点。 正如这个极端简单的例子所示,

在这里输入图像说明

很less(只报告过一次),碰巧我的一个应用程序崩溃了。 我想通常在发生非特定exception时终止它。 我的策略是(低级别)logging问题,然后终止。 该应用程序是一个子系统的一部分,我想(重新)启动它,如果有任何问题被发现。 它使用C ++ Builder 6构build,并在Windows(XP … 7,也是8)上运行。 我了解到, abort()很可能导致了错误信息。 该应用程序有一个GUI,这就是为什么显示一个消息框,而不是只是一个(unblocking)输出到stderr

只要消息框不被用户接受,我的应用程序就会明显运行 ,例如处理定时器(上面示例中的生命周期增加)或进程间消息,完全不知道问题。

阅读一些答案后, 什么是最简单的方法来使一个C ++程序崩溃? 和raise(SIGABRT)和abort()方法之间的区别 ,我尝试了以下

 void mySignalHandler(int sig) { // low-level error reporting here exit(-1); } void __fastcall TForm1::FormCreate(TObject *Sender) { signal(SIGABRT, mySignalHandler); // some more initialisation here } 

如果调用了abort()raise(SIGABRT)也可以正确终止我的应用程序 。 (我也希望阻止Windows“寻求解决问题的办法”)。

这是(注册一个信号处理程序中止和调用退出)从您的angular度来看是可靠的吗? …或者至less可以build立一些东西?

Solutions Collecting From Web of "MessageBox“exception程序终止”让我的应用程序继续运行"

在C ++ Builder安装文件夹中,检查以下文件:

  • source \ cpprtl \ Source \ misc \ errormsg.c – 实现_ErrorMessage
  • source \ cpprtl \ Source \ procses \ abort.c – 执行abort ,调用_ErrorMessage
  • source \ cpprtl \ Source \ misc \ assert.c – 实现_assert ,它调用_ErrorMessage

errormsg.c定义了一个未记录的_messagefunc函数指针,您可以设置该指针来覆盖默认行为。 虽然它没有记录,也没有在任何头文件中声明,但可以声明为extern并以此方式访问它。 示例用法:

 extern int (_RTLENTRY * _EXPDATA _messagefunc)(char *msg); static int LogAndDie(char *msg) { LogMessageToSomeFile(msg); exit(1); return 0; } void InitializeErrorHandling() { _messagefunc = LogAndDie; } 

当未处理的异常导致终止时,您可能可以使用Windows错误报告创建进程的转储。 然后,您可以在闲暇时查看转储,并允许一些父流程或其他监督人员重新启动流程。 如果你选择这种策略,你不会试图处理你的代码中的失败,而是允许它。

如果你想捕获任何程序退出,你应该看看atexit() 。 如果你想捕获所有的终止事件,那么看看std :: set_terminate() ,如果你想排除所有意外的异常,那么看看std :: set_unexpected() 。 如果只想捕获abort() ,则可以用SIGABRT 信号值调用signal() 。 您也可以用try{your code}catch(...){custom event handler}来包装您的代码。

我可以做一些测试,我只能确认注册一个SIGABRT信号处理程序只是一个NOOP。

我用一个用VS2008 Express编写的非常简单的GUI应用程序来试用它。 :

  • 没有框架,也没有.NET,但只有Win API
  • 一个与退出和致命的菜单
  • 菜单直接在WndProc中管理
  • 致命的执行1/0

结果如下:

  • 没有特别的动作=>窗口打开一个MessageBox指示一个致命的错误…
  • SIGABRT的信号处理程序=>相同的MessageBox
  • C ++ try catch(…)=>相同的MessageBox
  • WndProc中的SEH:可以拦截错误!
  • SEH周围的消息循环:可以拦截错误!

如果我把机器人SEH处理程序,最内部(WndProc)捕获。

对你来说新的好处是,如果足以保护消息循环,并且不必进入每个WndProc。

坏的新的是,我不知道C + +的建设者,不能说在哪里找到消息循环。

只是给你一个线索,这里是我如何保护WinAPI应用程序中的消息循环:

 __try { while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } } __except (EXCEPTION_EXECUTE_HANDLER){ ::MessageBox(NULL, _T("FATAL"), _T("MAIN"), MB_OK | MB_ICONERROR); } 

这样,我可以看到我自己的消息框,但没有别的,如果我评论我的消息框应用程序默默退出。

但是…因为你显示的信息不是原始的Windows信息,我怀疑C ++构建器在其消息循环中已经有了这样的异常处理程序。

希望能帮助到你 …