簡體   English   中英

可預測的Windows中崩潰進程的退出代碼

[英]Predictable exit code of crashed process in Windows

對於在Windows中正常退出的進程,進程的退出代碼通常是main的返回值,或者是傳遞給std::exit的退出代碼。 然后可以使用%ERRORLEVEL%來查詢退出代碼,並且可以用於確定程序是否正確執行,或者是否存在一些指示特定問題的特殊輸入/故障(特定於應用程序)。

但是,如果進程崩潰,我對退出代碼感興趣。 舉一個非常簡單的示例程序:

int main()
{
    int * a = nullptr;
    *a = 0xBAD;
    return 0;
}

當我編譯並在Windows中運行時,在命令行上我得到:

MyCrashProgram.exe -> crashes
echo %ERRORLEVEL%  -> -1073741819

退出代碼始終為此數字。 這引出了幾個問題:

  • 基於無效的寫入崩潰,退出代碼-1073741819是否可以預測?
  • 如果是這樣,有沒有辦法根據退出代碼確定崩潰的類型?
  • 這是否隨使用的編譯器而改變(我使用的是MSVC 2012)?
  • 這是否隨使用的Windows版本而改變(我使用的是Win10 TP)?
  • 這是否隨體系結構而變化(例如x64 - 我使用的是Win32)?

注意,我對如何修改程序以捕獲異常不感興趣。 我有興趣對可能在現有程序中發生的崩潰進行分類,我可能無法對其進行修改。

關於STATUS_ACCESS_VIOLATION的評論讓我看到了關於GetExceptionCode的文檔:

返回值標識異常的類型。 下表列出了由於常見編程錯誤而可能發生的異常代碼。 這些值在WinBase.h和WinNT.h中定義。

EXCEPTION_ACCESS_VIOLATION映射到STATUS_ACCESS_VIOLATION列表中的STATUS_ACCESS_VIOLATION 前綴為STATUS的列表中的所有異常都直接定義為以EXCEPTION為前綴的異常代碼。 根據RaiseException的文檔,它解釋了在異常發生時嘗試調試異常的過程,最后一步是:

如果未調試進程,或者關聯的調試器未處理異常,則系統會根據異常類型提供缺省處理。 對於大多數例外,默認操作是調用ExitProcess函數。

所以回答我的問題:

  • 是的,退出代碼是可預測的,它映射到EXCEPTION_STATUS_VIOLATION
  • 其他類型的錯誤將映射到其他常見的異常代碼。 但是,通過使用任意異常代碼(未處理)調用RaiseException,進程的退出代碼可以是任何內容
  • 退出代碼取決於Windows SDK,而不是編譯器,執行Windows版本或體系結構。 雖然理論上這可以隨着更新的Windows SDK而改變,但這對於向后兼容性來說是極不可能的。

這是Raymond Chen (強調我的)相關的短篇博文

流程退出代碼沒有標准。 您可以將任何想要的內容傳遞給ExitProcess,這就是GetExitCodeProcess將返回的內容。 內核沒有解釋這個值。 如果你想要代碼42意味着“發生了無限不可能的事情”那么你就會有更多的權力。

然而,有一個約定,退出代碼為零意味着成功(雖然什么構成“成功”由程序作者自行決定)和非零退出代碼意味着失敗(再次,細節留給自行決定)程序員)。 通常,退出代碼的較高值表示更嚴重的故障類型。 命令處理器ERRORLEVEL關鍵字的設計考慮了這些約定。

在某些情況下,您的進程將處於如此糟糕的狀態,以至於組件將自行終止該進程。 例如,如果進程無法找到它導入的DLL,或者其中一個DLL無法初始化, 則加載程序將終止該進程並使用狀態代碼作為進程退出代碼。 我相信當程序因未處理的異常而崩潰時,異常代碼將用作退出代碼。

一位客戶看到他們的程序崩潰,退出代碼為3,無法弄清楚它的來源。 他們從不在程序中使用退出代碼。 最終,識別出幻數3的來源: C運行時中止函數使用退出代碼3終止進程

這絕不是一個全面的答案,而是一些提示,以便您可以繼續前進。

我認為沒有辦法自動區分所有可能的崩潰原因。 要做到這一點,您必須自己捕獲錯誤並提供自己的退出代碼

為了捕獲所有可能的(可捕獲的)錯誤,您必須設置異常和信號處理程序。 這是因為訪問沖突是Linux下的窗口和信號(SIGSEV)下的異常。

有關Windows上不同類型錯誤的詳細信息,請參閱此問題: 捕獲訪問沖突異常

這是另一個在linux上進行信號處理的線程

暫無
暫無

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

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