......有点儿。正如这个极其简单的例子所示,
很少(到目前为止只报告过一次),我的应用程序之一就会崩溃。我想像通常那样在发生非特定异常时终止它。我的策略是(低级别)记录问题,然后终止。该应用程序是子系统的一部分,如果检测到任何问题,我想(重新)启动它。它是用C ++ - Builder 6构建的,可以在Windows(XP ... 7,也是8)上运行。我了解到abort()
最有可能导致错误消息。该应用程序有一个GUI,这就是显示消息框的原因,而不是仅仅向stderr
发出(解锁)输出。
只要消息框没有被用户接受,我的应用程序就会保持运行,例如它处理定时器(上例中的生命周期增加)或者处理消息,完全没有意识到这个问题。
在阅读What is the easiest way to make a C++ program crash?和Difference between raise(SIGABRT) and abort() methods的一些答案后,我尝试了以下
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"搜索问题的解决方案"。)
从您的角度来看,这是(为abort注册信号处理程序并在那里调用exit)可靠吗? ......或者至少可以建立一些东西?
答案 0 :(得分:4)
在C ++ Builder安装文件夹中,检查以下文件:
_ErrorMessage
的实施abort
的实现,调用_ErrorMessage
_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;
}
答案 1 :(得分:1)
当未处理的异常导致终止时,您可以使用Windows错误报告来创建进程的转储。然后,您可以在闲暇时查看转储,并允许某些父进程或其他监视程序重新启动您的进程。如果您选择此策略,则不会尝试处理代码中的失败,但允许它。
答案 2 :(得分:1)
如果要捕获任何程序退出,请查看atexit()。如果您想捕获所有终止事件,请查看std::set_terminate(),如果您想要捕获所有意外异常,请查看std::set_unexpected()。如果您只想捕获abort()
,可以使用SIGABRT
信号值来呼叫signal()。您还可以使用try{your code}catch(...){custom event handler}
包装代码。
答案 3 :(得分:1)
我可以做一些测试,我只能确认注册一个SIGABRT信号处理程序只是一个NOOP。
我尝试使用VS2008 Express编写的非常简单的GUI应用程序。 :
结果如下:
如果我放置机器人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 ++构建器在其消息循环中已经有这样的异常处理程序。
希望它有所帮助...