Windows 當機傾印收集入門 - WER/ProcDump/WinDbg

· 更新日期: · · Windows 開發, 缺陷調查, 當機傾印, WER, ProcDump, WinDbg

更新紀錄(2 筆,最後更新 2026年09月04日)

本文的修改紀錄。已保存的更新前版本,可透過附有 DOI 的永久連結閱讀。

已將繁體中文版改寫為日文原文的完整翻譯。先前的繁體中文版只譯出日文原文的一部分,遺漏了章節、表格、Mermaid 圖、圖說與 FAQ。本次依日文原文將這些內容全部補回,並新增本文的知識地圖章節。技術主張與日文版一致。 查看更新前的版本 (DOI: 10.5281/zenodo.22279423)
補上了日文原文中已有的諮詢引導(consultation_services)。內文沒有改動。 查看更新前的版本 (DOI: 10.5281/zenodo.21616307)
初次發布
引用本文(DOI: 10.5281/zenodo.21616306)

本文保存於 Zenodo。以下同時提供一律指向最新版本的 DOI,以及固定於您正在閱讀版本的 DOI。

Go Komura(2026)。〈Windows 當機傾印收集入門 - WER/ProcDump/WinDbg〉。小村軟體有限公司。https://doi.org/10.5281/zenodo.21616306 https://comcomponent.com/zh-TW/blog/2026/03/16/008-windows-app-crash-dump-collection-introduction/

DOI(最新版本)
10.5281/zenodo.21616306
DOI(此版本)
10.5281/zenodo.22297145

Windows 應用程式一旦開始出現「偶爾才會當掉」的狀況,光靠日誌追不下去的場面相當多。

特別難處理的是這幾種狀況。

  • 只在客戶環境發生
  • 例外訊息有拿到,但呼叫端的來龍去脈不夠
  • 不只是 C# / .NET 的 managed 側,還牽涉 COM、P/Invoke、native DLL、廠商 SDK
  • 只有在長時間運轉後才當掉

這種時候派得上用場的就是當機傾印。只要把當機時點的處理程序狀態寫成檔案,事後就能讀到例外代碼、當掉的執行緒的堆疊、當時載入的模組,以及部分或全部的記憶體。

在 Windows 上,先用 WER 的 LocalDumps,必要時再加上 Sysinternals ProcDump,還想進一步控制才用 MiniDumpWriteDump,照這個順序思考最容易理解。本文以 Windows 桌面應用程式、常駐應用程式、Windows 服務、設備介接工具等為前提,梳理當機傾印收集的第一步。

思考收集手段的順序說明 Windows 的當機傾印收集,先用 WER 的 LocalDumps,必要時再用 Sysinternals 的 ProcDump,還想進一步控制才用 MiniDumpWriteDump,照這個順序思考最容易理解的圖。先用 WER LocalDumps必要時再加 ProcDump還想進一步控制就用 MiniDumpWriteDump

圖 1: 從標準功能開始,只在不足的部分才補上工具的順序。

本文反覆出現的術語

先把用語簡短地固定下來。這裡含糊不清的話,後面幾章也會跟著模糊。

術語 意義
PDB 建置時產生的偵錯資訊檔案。是把位址還原成函式名稱與行號的對照表
符號 位址與名稱的對應資訊,由 PDB 或符號伺服器提供。沒有它,呼叫堆疊就只會是一串位址
first chance exception 例外剛發生、應用程式的例外處理常式還沒處理的階段。應用程式若把它 catch 起來,處理就會照常繼續
second chance exception 應用程式沒能處理完,以未處理的例外形式讓處理程序走向結束的階段。一般說「當掉了」指的是這一種
postmortem debugger 當機時由作業系統自動啟動的偵錯器。是以整台機器的當機時行為登記的
迷你傾印/完整傾印 傾印所含記憶體量的差別。第 7 章會處理

1. 先講結論

先把最該掌握的幾點列出來。

  • 起手 以應用程式為單位設定 WER LocalDumps 最穩妥。不用額外工具,就能在當機後把傾印留在本機。
  • 重現率低的實務調查,或想連 first chance exception/hang 都看到時,就用 ProcDump。
  • 自製收集擺到最後再考慮 剛剛好。等真的需要了再評估 MiniDumpWriteDump 就足夠。
  • 和傾印一樣重要的是 PDB 與散發用二進位檔的保存。只有傾印而沒有符號,能讀出來的量會少很多。
  • 完整傾印很強,但檔案大小與機密資訊混入的風險也一樣強。保存位置、保留份數、存取權限、分享流程要先決定。

入門階段建議的組合,大致會落在下面這一帶。

環境 起手的組合
開發機/驗證機 以應用程式為單位設定 WER LocalDumps,先用 DumpType=2 的完整傾印
客戶環境/現場機 看容量與機密需求選 DumpType=1 或 2。只在必要時追加 ProcDump
長時間運轉或 hang 調查 除了 WER 之外,再評估 ProcDump 的 -h 或 -e 1
想連自製 UI 與附帶日誌都納入 以獨立處理程序為前提,用 MiniDumpWriteDump 自製收集

簡單說就是 先 WER,再 ProcDump,最後才自製。從相反的順序開始,設計通常會變得很重。

圖中實線表示始終成立的關係,虛線表示附帶條件的關係(成立條件寫在詳細頁面中各關係的說明中)。關係的完整清單(共 21 條,附依據與可信度)以及主要概念的定義,彙整在知識地圖詳細頁面(日文)。資料:JSON-LD / Turtle

2. 當機傾印能看出什麼

當機傾印是「那一瞬間的快照」。與其說是監視錄影畫面,不如說更接近事故現場的靜止影像。

因此,下面這類資訊相當容易取得。

  • 是以哪個例外代碼當掉的
  • 是哪條執行緒當掉
  • 那個時間點的呼叫堆疊
  • 當時載入的模組
  • 依照納入了多少記憶體,還能看到堆積上的狀態與物件的內容

另一方面,也有一些光靠傾印容易不足的東西。

  • 走到那一步為止的時序
  • 從幾小時前就開始的增加趨勢
  • 與通訊或設備之間的外部狀態
  • 當機前的輸入與業務脈絡

所以實務上,不要想只靠傾印就把事情做完,要搭配日誌與 heartbeat 才是基本。

傾印與日誌的組合說明當機傾印像事故現場的靜止影像,對那一瞬間的狀態很強,而走到那一步為止的時序與外部狀態則由日誌與 heartbeat 補足,因此基本上要兩者搭配使用的圖。當機傾印〔瞬間的靜止影像〕組合起來調查日誌與 heartbeat〔時序〕對例外代碼與堆疊很強對走到那一步的經過很強

圖 2: 靜止影像的傾印與時序的日誌,擅長的領域切得很乾淨。

3. 收集方法的全貌

Windows 應用程式的傾印收集中,入門階段要掌握的方法有下列 4 種。

方法 適合的場面 強項 注意事項
WER LocalDumps 想先常設下來的當機收集 Windows 標準功能。容易以應用程式為單位設定 基本上針對當機。hang 與細部的條件分支較弱
ProcDump 重現率低的調查、hang、first chance exception 觸發條件多。容易投入實務現場 會變成外部工具的維運
工作管理員的建立傾印 想手動取得現在的狀態 用 GUI 當場就能取得 不是自動收集
MiniDumpWriteDump 想做自己的診斷功能 容易把附帶日誌或自訂中繼資料合在一起 實作草率反而會把東西弄壞

對新手來說最重要的是,比起「用什麼取」,更要先決定「在什麼條件下」「取到哪裡」「取多大」。

比道具更早要決定的事說明當機傾印收集要先決定在什麼條件下、取到哪裡、取多大這三件事,之後才進到用什麼取這個道具選擇的圖。在什麼條件下取先決定的 3 點輸出到哪裡取多大然後才選道具

圖 3: 條件、輸出位置與大小決定好之後,選道具就不會猶豫。

4. 起手最推薦 WER LocalDumps

4.1 最先要看的登錄檔值

Windows Error Reporting (WER) 有 LocalDumps,可以在當機後把使用者模式傾印存到本機。不必散發額外工具,作為第一步相當好處理。

基本的機碼在這裡。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

你也可以在這裡放全域設定,但實務上收攏到 以應用程式為單位的子機碼 更好處理。

LocalDumps 設定的放置位置說明雖然可以把全域設定放在 LocalDumps 機碼正下方,但實務上收攏到像 MyApp.exe 這種以應用程式為單位的子機碼更好處理的圖。LocalDumps 機碼正下方的全域設定以應用程式為單位的子機碼實務上這一邊比較好處理

圖 4: 同一個機碼,收攏到應用程式名稱的子機碼就能縮小影響範圍。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe

最先要看的值有 3 個。

值 意義 起手的建議
DumpFolder 傾印的輸出位置 切一個專用資料夾
DumpCount 保留份數 從 5〜10 左右開始
DumpType 0=自訂、1=迷你、2=完整 一開始用 2,容量吃緊就用 1

4.2 以應用程式為單位的設定範例

例如針對 MyApp.exe,想在 C:\CrashDumps\MyApp 最多留下 10 個完整傾印,可以先像下面這樣設定。

reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDumps\MyApp" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpCount /t REG_DWORD /d 10 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpType /t REG_DWORD /d 2 /f

這個範例的重點有 4 個。

  • 限定在 MyApp.exe,而不是全域
  • 把輸出位置分離到專用資料夾
  • 起手先用完整傾印
  • 把保留份數限制在 10

4.3 確認有沒有真的取到

設定放進去之後,在正式環境等它自然發生之前,先在驗證環境確實取到 1 次 比較安全。

要確認的是這 4 點。

  1. 預期的資料夾裡會不會出現 .dmp
  2. 檔案大小是否符合維運上的設想
  3. WinDbg 能不能打開
  4. 事件檢視器的「應用程式」記錄檔裡看不看得到 crash
設定後的驗證流程說明設定放進去後,在正式環境等它自然發生之前,先在驗證環境確實取到 1 次,並確認資料夾裡有沒有傾印、大小是否符合設想、WinDbg 能不能打開、事件檢視器裡看不看得到 crash 的流程圖。放入設定在驗證環境刻意讓它當掉確認傾印是否存在與大小確認 WinDbg 能否打開確認事件檢視器的記錄檔

圖 5: 在等正式環境自然發生之前,先在驗證環境確實取到 1 次。

4.4 刻意讓程式當掉的最小程式碼

雖然說要「確實取到」,但一直等真正的當機發生並不能算驗證。準備一個驗證用、只會刻意當掉的小型 EXE 會快很多。

.NET 的話,只要一個會拋出未處理例外的主控台應用程式就夠。.NET 的受管理未處理例外會讓處理程序結束,所以直接就會成為 WER 的對象。

// CrashTest.csproj: <TargetFramework>net8.0</TargetFramework>
using System;
using System.Threading;

internal static class Program
{
    private static void Main()
    {
        Console.WriteLine($"PID={Environment.ProcessId} / 3 秒後讓它當掉。");
        Thread.Sleep(3000);

        throw new InvalidOperationException("intentional crash for dump collection test");
    }
}

想確認原生側的話,引發存取違規 (0xC0000005) 比較接近。為了避免被最佳化消掉,加上 volatile。

// crash_test.cpp / C++17 / MSVC
int main()
{
    volatile int* p = nullptr;
    *p = 1;  // 這裡會發生 STATUS_ACCESS_VIOLATION
    return 0;
}

這裡有一個特別容易弄錯的點。 LocalDumps 的子機碼名稱,必須和現在要弄當掉的 EXE 檔名一致。 只建立 MyApp.exe 的機碼,卻讓 CrashTest.exe 當掉,當然不會產出傾印。驗證時要嘛暫時建立 CrashTest.exe 的機碼,要嘛改用全域設定那邊來試,二選一。

子機碼名稱必須一致的陷阱說明 LocalDumps 的子機碼名稱必須和現在要弄當掉的 EXE 檔名一致,否則不會產出傾印,因此驗證時要暫時建立 CrashTest.exe 的機碼,或改用全域設定來試的圖。只建立 MyApp.exe 的機碼讓 CrashTest.exe 當掉不會產出傾印機碼名稱要和當掉的 EXE 名稱一致

圖 6: 子機碼名稱與 EXE 名稱對不上,是驗證空轉的經典陷阱。

Sysinternals 的 NotMyFault 也常被當成「刻意弄當機」的工具提起,但它是用來讓 Windows 系統本身 crash/hang,產生藍色當機畫面的傾印,而且需要系統管理員權限。要驗證使用者模式應用程式的 LocalDumps,用上面那種自己寫的小型 EXE 更安全也更確實。

5. 什麼場面用 ProcDump

WER 就夠用的情況很多,但也有 ProcDump 比較方便的場面。

  • 想避免在登錄檔常設
  • 只想監控已經在執行中的處理程序
  • 只想從下次啟動開始監控
  • 想看 first chance exception
  • 想取得 hang
  • 想用效能計數器或附帶條件的方式採集

5.1 常用的選項

只挑入門階段常用的來看,ProcDump 記住下面這些就相當夠打了。

選項 意義
-ma 完整傾印
-mp MiniPlus 傾印
-mc <Mask> 自訂傾印。以 16 進位指定 MINIDUMP_TYPE 的位元遮罩
-e 在未處理的例外時取得傾印
-e 1 在 first chance/second chance 例外時取得傾印
-h 在視窗停止回應時取得傾印
-w 等待目標處理程序啟動
-x 啟動目標處理程序並監控
-n 傾印的最大份數
-accepteula 自動同意初次的 EULA 確認

5.2 代表性的指令範例

對已在執行中的處理程序,在未處理的例外時取完整傾印

procdump -accepteula -ma -e 1234 C:\CrashDumps\MyApp

等待下次啟動,在未處理的例外時取完整傾印

procdump -accepteula -ma -e -w MyApp.exe C:\CrashDumps\MyApp

由自己啟動,並就這樣監控

procdump -accepteula -ma -e -x C:\CrashDumps\MyApp MyApp.exe

連 first chance exception 也想取

procdump -accepteula -ma -n 3 -e 1 MyApp.exe C:\CrashDumps\MyApp

想取得停止回應

procdump -accepteula -h MyApp.exe C:\CrashDumps\MyApp

5.3 不把 -i 當成第一步的理由

ProcDump 也有用 -i 註冊成 postmortem debugger 的用法。這很強大,但因為 會動到整台機器當機時的行為,作為入門階段的第一步稍嫌沉重。

所以一開始從 WER 的應用程式單位設定,或 ProcDump 的 -w / -x / 指定 PID 切入比較好處理。

不把 -i 當成第一步的理由說明 ProcDump 的 -i 是註冊成 postmortem debugger 的強大用法,但會動到整台機器當機時的行為,因此入門階段從 WER 的應用程式單位設定,或 ProcDump 的 -w、-x、指定 PID 切入比較好處理的圖。用 ProcDump 的 -i 註冊動到整台機器的行為對入門的第一步來說太重一開始用應用程式單位的設定WER 的應用程式單位設定ProcDump 的 -w、-x 或指定 PID

圖 7: 從影響範圍收在應用程式單位的入口開始。

6. 自製收集使用 MiniDumpWriteDump 時的思路

適合自製收集的,例如是這些場面。

  • 想在 UI 上放一個「儲存診斷資訊」的按鈕
  • 想把日誌、設定、追蹤 ID 和傾印綁在一起
  • 想把相關的子處理程序或輔助處理程序也一起收進來
  • 想在上傳前加入自訂的遮罩或壓縮

這裡的核心 API 是 MiniDumpWriteDump。

不過這裡有點脾氣。入門階段特別不想弄錯的是下面 2 點。

  1. 可以的話,從傾印對象以外的處理程序呼叫
  2. DbgHelp 系列以 single-threaded 為前提來使用
自製收集不想弄錯的 2 點說明用 MiniDumpWriteDump 自製收集時,要注意可以的話從傾印對象以外的處理程序呼叫,以及以 single-threaded 為前提使用 DbgHelp 系列這 2 點的圖。用 MiniDumpWriteDump 自製收集從別的處理程序呼叫DbgHelp 以 single-threaded 為前提實作草率反而會把東西弄壞

圖 8: 自製收集的脾氣,集中在呼叫的位置與執行緒這 2 點。

7. 迷你傾印/完整傾印/中間大小怎麼選

在這裡猶豫的人相當多。把實務上的選法整理成一張表。

種類 適合的場面 好處 注意事項
迷你傾印 想先廣泛放進去、想讓分享輕一點 檔案小、容易傳送 還原狀態的深度較弱
完整傾印 想以原因調查為優先,懷疑 native 邊界或堆積 能取得的資訊多 檔案大、機密混入的風險高
MiniPlus/Custom 迷你不夠,完整又太重 能取得平衡 需要調整的知識

給新手的建議相當單純。

  • 開發機/驗證機用完整傾印
  • 客戶環境依維運條件在迷你與完整之間選
  • 懷疑是記憶體毀損、原生 DLL、COM、P/Invoke,或長時間運轉後的狀態異常,就偏向完整
傾印種類的起手選法說明開發機或驗證機用完整傾印,客戶環境依維運條件選迷你或完整,懷疑記憶體毀損、原生邊界或長時間運轉後的狀態異常就偏向完整的選法圖。開發機/驗證機客戶環境有毀損味道或原生邊界要在哪種環境取得完整傾印依維運條件選迷你或完整

圖 9: 猶豫時就用環境決定,可疑的味道越濃就越往完整那一邊靠。

7.1 MiniPlus/Custom 實際上要怎麼指定

只有表格的第 3 列,指定方法比較難懂,這裡補充說明。

WER LocalDumps 的情況,是把 DumpType 設成 0(自訂)之後,在 CustomDumpFlags 放入 MINIDUMP_TYPE 的位元組合。CustomDumpFlags 是只有在 DumpType=0 時才會使用的值,預設是 0x00000121(MiniDumpWithDataSegs、MiniDumpWithUnloadedModules、MiniDumpWithProcessThreadData 的組合)。

reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpType /t REG_DWORD /d 0 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v CustomDumpFlags /t REG_DWORD /d 0x121 /f

ProcDump 的情況,-mp 是 MiniPlus,-mc <Mask> 是自訂。

procdump -accepteula -mp -e MyApp.exe C:\CrashDumps\MyApp

MiniPlus 的名字聽起來小,內容其實相當偏完整。根據文件,它包含 全部的 private 記憶體,以及全部可 read/write 的 image/mapped 記憶體,並在此之上 只排除超過 512MB 的最大 private 區域 來壓低大小。結果它的定位就是「詳細程度和完整傾印相當,但大小是完整的 10%〜75%」。

不過有 2 個注意事項。

  • CLR 處理程序因為偵錯上的限制,即使指定 -mp 也會以完整(-ma)的形式採集。 在 .NET 應用程式上指望 MiniPlus 縮小檔案,多半會落空
  • 如果想壓低大小的動機是「想減少機密資訊混入」,那不要用 MiniPlus,從迷你傾印那一邊思考比較直接了當
MiniPlus 的定位與限制說明 MiniPlus 包含全部的 private 記憶體與可 read/write 的 image 或 mapped 記憶體,只排除超過 512MB 的最大 private 區域,大小落在完整的一成到七成多,但 CLR 處理程序即使指定 -mp 也會以完整的形式採集的圖。CLR 處理程序的情況以 MiniPlus 採集private 記憶體幾乎全部包含只排除巨大的 private 區域比完整小又詳細會以完整的形式採集

圖 10: MiniPlus 的內容偏向完整,在 .NET 應用程式上縮小檔案的效果不會出現。

8. 維運上要先決定的事

傾印收集比起實作,更常在維運上跌倒。以下列出想先決定好的事。

8.1 PDB 與二進位檔要怎麼留

這件事最重要。

  • 散發出去的 EXE/DLL 的正確版本
  • 對應那個版本的 PDB
  • 是用哪個 commit/哪條建置管線做出來的
  • 安裝程式與散發物的版本資訊

8.2 要輸出到哪裡、留幾份

完整傾印會變得相當大。輸出位置與保留方針從一開始就決定好比較安全。

  • 不要就這樣丟在系統磁碟機的根目錄
  • 分離到專用資料夾
  • 用 DumpCount 或 -n 設上限
  • 把長期保存與一次保存分開

8.3 誰可以看

完整傾印裡可能混入機密資訊或個人資料。

  • 明文設定
  • 連線字串
  • 權杖與認證資訊
  • 當機前正在處理的業務資料
  • 檔案路徑與使用者名稱

所以必須 在設計「怎麼取」的同時,也決定「誰可以碰」。

維運上要先決定的 3 點說明當機傾印收集比起實作更容易在維運上跌倒,因此要先決定 PDB 與二進位檔的保存、輸出位置與保留份數,以及誰可以看這個存取方針的圖。PDB 與二進位檔的保存先決定好輸出位置與保留份數誰可以看比起實作更容易在維運上跌倒

圖 11: 傾印收集的失敗,多半來自維運上的約定不足。

9. 取到之後最短的分析動線

取到傾印之後,最先要做的事意外地單純。

9.1 安裝 WinDbg

現在的 WinDbg 用 Microsoft Store 或 winget 都變得容易安裝。

winget install Microsoft.WinDbg

9.2 打開傾印

windbg -z C:\CrashDumps\MyApp\MyApp_YYMMDD_HHMMSS.dmp

這裡的檔名是 ProcDump 加上的預設名稱。ProcDump 的預設檔名是 PROCESSNAME_YYMMDD_HHMMSS.dmp,可以把 PROCESSNAME / PID / EXCEPTIONCODE / YYMMDD / HHMMSS 當成替換指定子使用。

另一方面,WER LocalDumps 建立檔案時用的是與 ProcDump 不同的命名。命名規則在 Microsoft Learn 上沒有明確寫出來,所以與其猜名字去找,不如把輸出資料夾照更新日期時間排序來看比較確實。

dir /o-d "C:\CrashDumps\MyApp\*.dmp"

沒有設定 DumpFolder 時,預設的輸出位置是 %LOCALAPPDATA%\CrashDumps。不過 服務的當機會輸出到各執行帳戶的設定檔資料夾。System 服務是 %WINDIR%\System32\Config\SystemProfile,Network Service/Local Service 則在 %WINDIR%\ServiceProfiles 底下。覺得「傾印沒有出來」時,先懷疑這裡。

找不到傾印時該去哪裡找說明沒有設定 DumpFolder 時的預設是 LOCALAPPDATA 底下的 CrashDumps,而服務的當機會輸出到各執行帳戶的設定檔資料夾,因此覺得沒有出來時要先懷疑那裡的圖。一般應用程式服務找不到傾印當時是以哪種形式在執行LOCALAPPDATA 底下的 CrashDumps執行帳戶的設定檔底下SystemProfile 或 ServiceProfiles

圖 12: 預設的輸出位置會隨帳戶而不同,所以要從尋找的位置開始懷疑。

9.3 設定符號

先讓 Microsoft 公開符號處於可用的狀態,之後再加上自己 PDB 的位置。

.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload

9.4 先看自動分析

!analyze -v

在此之上,

  • 是哪個例外代碼
  • faulting module 是什麼
  • 自己的程式碼在堆疊上露出到哪裡
  • 例外執行緒之外,有沒有可疑的等待或卡住

依序查看這幾點。

取到之後最短的分析動線說明安裝 WinDbg、打開傾印、設定 Microsoft 公開符號與自己的 PDB,先看 analyze -v 的自動分析,再依序確認例外代碼、faulting module、自己的程式碼露出到哪裡,以及其他執行緒有沒有卡住的流程圖。安裝 WinDbg打開傾印設定符號與 PDB先看自動分析依序讀例外代碼與堆疊

圖 13: 打開、接通符號、從自動分析開始讀,是最短的路。

10. 常見的卡關處

10.1 傾印取到了,但沒有 PDB

這種情況相當多。就算傾印收集成功了,用來閱讀的材料還是不足。 在做收集設定的同一個時間點,把 PDB 的保存設計也一起放進去 比較好。

10.2 沒看 DumpFolder 的 ACL

在服務或做過權限分離的處理程序上,這裡很容易落空。 先確認「那個處理程序真的寫得進去嗎」。Microsoft Learn 也寫著,如果使用預設以外的路徑,要確認「ACL 是當機的處理程序寫得進去的狀態」。

目前的 ACL 可以用 icacls 查看。

icacls C:\CrashDumps\MyApp

寫入權限不足時,就給執行帳戶加上 M(變更)。傾印資料夾底下的檔案也需要同樣的權限,所以加上 (OI) 與 (CI) 讓它繼承。

rem 範例: 以 Network Service 執行的服務
icacls C:\CrashDumps\MyApp /grant "NT AUTHORITY\NETWORK SERVICE:(OI)(CI)M"

(OI) 是讓 ACE 繼承到底下的檔案,(CI) 是繼承到底下的資料夾。繼承的範圍就直接等於「誰讀得到傾印」,所以在加上去之前,先確認一次是否與 8.3 決定的方針有出入。

DumpFolder 的 ACL 檢查流程說明服務或做過權限分離的處理程序在寫入上容易落空,因此要用 icacls 檢查目前的 ACL,不足時給執行帳戶加上帶繼承的變更權,並把繼承範圍與閱覽方針對照的流程圖。寫不進去寫得進去用 icacls 查看目前的 ACL執行帳戶寫得進去嗎加上帶繼承的變更權就這樣維運繼承範圍要與閱覽方針對照

圖 14: 寫不寫得進去的確認,與誰讀得到的確認,在同一個地方一起做完。

10.3 持續把完整傾印輸出到正式機的系統磁碟機

這是容量出包的經典。 保留份數限制與輸出位置分離 從一開始就放進去。

10.4 想只靠 WER 把 hang 也全部看完

WER LocalDumps 首先是對 crash 很強。 有些場面 hang 或 first chance exception 用 ProcDump 更合適。

10.5 一直開著 -e 1,變成例外的暴風雨

first chance exception 很方便,但件數本來就多。 加上件數限制、只在短時間內開啟、限定對象 比較實際。

11. 總結

當機傾印對重現率低的故障來說,是相當有力的觀測點。尤其是 Windows 應用程式牽涉到 COM、P/Invoke、native DLL、長時間運轉時,一開始就先決定好「當掉之後會留下什麼」很有價值。

建議的順序很簡單。

  1. 先以應用程式為單位放入 WER LocalDumps
  2. 必要時再加上 ProcDump
  3. 還想進一步控制時,以獨立處理程序為前提使用 MiniDumpWriteDump

照這個順序推進,比較不容易大幅走偏。

12. 參考資料

共用相同標籤的最新文章。能以相近的主題延伸理解。

與本文相近的主題頁面。以本文為起點,可進一步連到相關服務與其他文章。

本文連結到以下服務頁面,歡迎從最接近的入口查看。

故障調查 & 根本原因分析

把當機傾印、日誌與重現條件組合起來釐清原因的流程,與缺陷調查、原因分析這類主題相當契合。尤其是只在實務現場才發生的當機,或長時間運轉後才出現的故障,觀測設計本身就會變成關鍵。

常見問題

整理諮詢這個主題時常見的問題。

什麼是當機傾印?能看出什麼?
它是把當機那一瞬間的處理程序狀態存成檔案,像事故現場靜止影像一樣的快照。事後可以查看例外代碼、當掉的執行緒與它的呼叫堆疊、當時載入的模組,並依照納入的記憶體多寡,連堆積上物件的內容都能看到。另一方面,走到當機為止的時序,以及與通訊或設備之間的外部狀態容易不足,所以實務上基本上要搭配日誌與 heartbeat 一起使用。
WER 的 LocalDumps 要在哪裡設定?
在登錄檔的 HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps 底下設定。實務上比起全域設定,收攏到像 MyApp.exe 這種以應用程式為單位的子機碼更好處理。最先要看的值有三個:輸出位置的 DumpFolder、保留份數的 DumpCount、種類的 DumpType,不必散發額外工具就能把當機後的傾印留在本機。
迷你傾印與完整傾印該選哪一種?
大致的判斷基準是:開發機與驗證機用完整傾印(DumpType=2),客戶環境則看容量與機密需求,在迷你傾印(DumpType=1)與完整傾印之間選一個。懷疑是記憶體毀損、原生 DLL、COM、P/Invoke,或長時間運轉後的狀態異常時,偏向完整傾印比較有利。不過完整傾印檔案很大,也有把連線字串、權杖等機密資訊一起帶進去的風險,因此必須先決定保存位置、保留份數與存取權限。
ProcDump 在什麼時候使用?
WER LocalDumps 基本上是針對當機,所以想連 hang 或 first chance exception 都看到、想避免在登錄檔常設、或只想監控已經在執行中的處理程序時,ProcDump 比較合用。代表性的選項有完整傾印的 -ma、在未處理的例外時採集的 -e、偵測停止回應的 -h、等待啟動的 -w 等。以 first chance exception 為對象的 -e 1 件數容易變多,因此用 -n 加上上限、短時間且限定範圍地使用比較實際。

作者檔案

本文作者的個人檔案頁面。

Go Komura

小村軟體有限公司 代表

以 Windows 軟體開發、技術諮詢與故障調查為中心,在難以重現的故障調查與既有資產仍在運作的專案上具有優勢。

回到部落格一覽