MessageBox “Abnormal program termination” keeps my application running

陌路散爱 提交于 2019-12-05 06:48:13

In the C++Builder installation folder, check the following files:

  • source\cpprtl\Source\misc\errormsg.c - implementation of _ErrorMessage
  • source\cpprtl\Source\procses\abort.c - implementation of abort, which calls _ErrorMessage
  • source\cpprtl\Source\misc\assert.c - implementation of _assert, which calls _ErrorMessage

errormsg.c defines an undocumented _messagefunc function pointer that you can set to override the default behavior. Although it's undocumented and not declared in any header files, you can declare it as an extern and access it that way. Sample usage:

extern int (_RTLENTRY * _EXPDATA _messagefunc)(char *msg);

static int LogAndDie(char *msg)
{
  LogMessageToSomeFile(msg);
  exit(1);
  return 0;
}

void InitializeErrorHandling()
{
  _messagefunc = LogAndDie;
}

You might be able to use Windows Error Reporting to create a dump of the process, when an unhandled exception causes a termination. Then you can review the dump at your leisure and allow some parent-process or other watchdog to restart your process. If you chose this strategy, you would not try to deal with the failure in your code, but to allow it.

If you want to capture any program exit you should look at atexit(). If you want to capture all termination events then look at std::set_terminate(), if you want to caputure all unexpected exceptions then look at std::set_unexpected(). If you want to capture only abort() you can call signal() with the SIGABRT signal value. You can also wrap your code with try{your code}catch(...){custom event handler}.

I could do some tests, and I only can confirm that registering a SIGABRT signal handler is simply a NOOP.

I tried it with a very simple GUI application written with VS2008 Express. :

  • no framework, nor .NET but only Win API
  • one menu with Exit and Fatal
  • menu managed directly in WndProc
  • Fatal execute 1/0

Here are the result :

  • no special action => windows opens a MessageBox indicating a fatal error ...
  • signal handler for SIGABRT => same MessageBox
  • C++ try catch(...) => same MessageBox
  • SEH in WndProc : can intercept the error !
  • SEH around message loop : can intercept the error !

If I put bot SEH handlers, the most internal (WndProc) catches.

The good new for you is that if is enough to protect the message loop, and you do not have to go into every WndProc.

The bad new is that I do not know C++ builder and cannot say where to find the message loop.

Just to give you a clue, here is how I could protect the message loop in a WinAPI application :

__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);
}

That way, I can see my own message box, but nothing else and if I comment my message box the application silently exits.

But ... as the message you show is not original Windows one, I suspect C++ builder to already have such an exception handler in its message loop.

Hope it helps ...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!