簡體   English   中英

MessageBox“異常程序終止”使我的應用程序保持運行

[英]MessageBox “Abnormal program termination” keeps my application running

...的種類。 正如這個極其簡單的例子所示,

在此輸入圖像描述

很少(到目前為止只報告過一次),碰巧我的一個應用程序崩潰了。 我想像通常那樣在發生非特定異常時終止它。 我的策略是(低級別)記錄問題,然后終止。 該應用程序是子系統的一部分,如果檢測到任何問題,我想(重新)啟動它。 它是用C ++ - Builder 6構建的,可以在Windows上運行(XP ... 7,也是8)。 我了解到abort()很可能導致錯誤消息。 該應用程序有一個GUI,這就是為什么顯示一個消息框而不是僅向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) ,它也可以使我的應用程序正確abort() (我也希望阻止Windows“尋找問題的解決方案”。)

從您的角度來看,這是(為abort注冊信號處理程序並在那里調用exit)可靠嗎? ......或者至少可以建立一些東西?

在C ++ Builder安裝文件夾中,檢查以下文件:

  • 源\\ cpprtl \\來源\\雜項\\ 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

結果如下:

  • 沒有特殊操作=> windows打開一個消息框,指示致命錯誤...
  • 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 ++ builder在其消息循環中已經有了這樣的異常處理程序。

希望能幫助到你 ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM