如何在.NET程序崩潰時自動創建Dump?

今天在瀏覽張隊轉載文章的留言時,遇到一個讀者問了這樣的問題,如下圖所示:

如何在.NET程序崩潰時自動創建Dump?

文章插圖
首先能明確的一點是"程序崩潰退出了是不能用常規的方式dump的",因為整個進程樹都已經退出 ?,F場已經無法使用常規的方式讀取到 。
一般來說常規的方法是沒辦法讀取到的 , 也有一些特殊的方式,比如有關部門在調查取證時,就可以通過一些工具讀取到內存中的信息 。當然這是一些hack手段,不在本文討論中 。
不過好消息是,雖然您無法在程序崩潰退出以后創建Dump,但是您可以在程序崩潰時自動創建Dump,這樣下次遇到程序崩潰,那么就可以有分析的現場了 。
Windows平臺在 Windows 中 , 可以將 Windows 錯誤報告 (WER) 配置為在應用程序崩潰時生成轉儲 。
這個方式對所有程序都有效果 , 不僅僅是.NET程序,如C++、Go等等都可以;而且和.NET、.NET Core版本無關
  1. 打開regedit.exe
  2. 打開目錄HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps
  3. 創建KEY DumpFolder 類型為REG_EXPAND_SZ用于配置存放Dump文件的目錄
  4. 另外可以創建KEY DumpCount 類型為REG_DWORD配置Dump的總數量
    如何在.NET程序崩潰時自動創建Dump?

    文章插圖
當然也可以使用PowerShell命令來配置這些:
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name "LocalDumps"New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpFolder" -Value "%LOCALAPPDATA%\CrashDumps" -PropertyType ExpandStringNew-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpCount" -Value 10 -PropertyType DWord按照上面的配置,如果程序發生了異常退出 , 那么就會在%LOCALAPPDATA%\CrashDumps目錄創建程序的Dump 。如下圖所示:
如何在.NET程序崩潰時自動創建Dump?

文章插圖
.NET Core全平臺那么如果您是.NET Core跨平臺應用 , 那么在Linux、MacOS等操作系統上,有更簡單和更豐富的方式 , 下方有一些環境變量的參數:
  • COMPlus_DbgEnableMiniDump 或 DOTNET_DbgEnableMiniDump: 如果設置為 1,則發生故障時啟用CoreDump生成 。默認值為:0
  • COMPlus_DbgMiniDumpType 或 DOTNET_DbgMiniDumpType: 要收集的轉儲類型 。有關詳細信息,請看下文的說明 。默認值為:2
  • COMPlus_DbgMiniDumpName 或 DOTNET_DbgMiniDumpName: 寫入轉儲的文件路徑 。確保運行 dotnet 進程的用戶具有指定目錄的寫入權限 。默認值為:/tmp/coredump.<pid>
  • COMPlus_CreateDumpDiagnostics 或 DOTNET_CreateDumpDiagnostics: 如果設置為 1,則啟用轉儲進程的診斷日志記錄 。默認值為:0
  • COMPlus_EnableCrashReport 或 DOTNET_EnableCrashReport:(需要.NET 6 或更高版本,目前僅Linux和MacOS可用)如果設為 1,運行時會生成 JSON 格式的故障報表,其中包括有關故障應用程序的線程和堆棧幀的信息 。故障報表名稱是追加了 .crashreport.json 的轉儲路徑/名稱 。
  • COMPlus_CreateDumpVerboseDiagnostics 或 DOTNET_CreateDumpVerboseDiagnostics:(需要 .NET 7 或更高版本)如果設為 1,則啟用轉儲進程的詳細診斷日志記錄 。
  • COMPlus_CreateDumpLogToFile 或 DOTNET_CreateDumpLogToFile:(需要 .NET 7 或更高版本)應寫入診斷消息的文件路徑 。如果未設置,則將診斷消息寫入故障應用程序的控制臺 。
對于這些環境變量,.NET 7 標準化前綴 DOTNET_,而不是 COMPlus_ 。但是,COMPlus_ 前綴仍將繼續正常工作 。如果使用的是早期版本的 .NET 運行時,則環境變量仍應該使用 COMPlus_ 前綴 。
關于DOTNET_DbgMiniDumpType的說明如下所示: