![](/img/trans.png)
[英]Windows in atexit() handler getting the current process exit code set by ::exit()
[英]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
是否可以預測? 注意,我對如何修改程序以捕獲異常不感興趣。 我有興趣對可能在現有程序中發生的崩潰進行分類,我可能無法對其進行修改。
關於STATUS_ACCESS_VIOLATION
的評論讓我看到了關於GetExceptionCode
的文檔:
返回值標識異常的類型。 下表列出了由於常見編程錯誤而可能發生的異常代碼。 這些值在WinBase.h和WinNT.h中定義。
EXCEPTION_ACCESS_VIOLATION
映射到STATUS_ACCESS_VIOLATION
列表中的STATUS_ACCESS_VIOLATION
。 前綴為STATUS
的列表中的所有異常都直接定義為以EXCEPTION
為前綴的異常代碼。 根據RaiseException
的文檔,它解釋了在異常發生時嘗試調試異常的過程,最后一步是:
如果未調試進程,或者關聯的調試器未處理異常,則系統會根據異常類型提供缺省處理。 對於大多數例外,默認操作是調用ExitProcess函數。
所以回答我的問題:
EXCEPTION_STATUS_VIOLATION
。 這是Raymond Chen (強調我的)相關的短篇博文 :
流程退出代碼沒有標准。 您可以將任何想要的內容傳遞給ExitProcess,這就是GetExitCodeProcess將返回的內容。 內核沒有解釋這個值。 如果你想要代碼42意味着“發生了無限不可能的事情”那么你就會有更多的權力。
然而,有一個約定,退出代碼為零意味着成功(雖然什么構成“成功”由程序作者自行決定)和非零退出代碼意味着失敗(再次,細節留給自行決定)程序員)。 通常,退出代碼的較高值表示更嚴重的故障類型。 命令處理器ERRORLEVEL關鍵字的設計考慮了這些約定。
在某些情況下,您的進程將處於如此糟糕的狀態,以至於組件將自行終止該進程。 例如,如果進程無法找到它導入的DLL,或者其中一個DLL無法初始化, 則加載程序將終止該進程並使用狀態代碼作為進程退出代碼。 我相信當程序因未處理的異常而崩潰時,異常代碼將用作退出代碼。
一位客戶看到他們的程序崩潰,退出代碼為3,無法弄清楚它的來源。 他們從不在程序中使用退出代碼。 最終,識別出幻數3的來源: C運行時中止函數使用退出代碼3終止進程 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.