- 正確配置轉儲類型和事件日誌記錄是準確診斷 Windows 中任何藍色畫面死機 (BSOD) 的關鍵。
- WinDbg 以及 Microsoft 符號路徑和 !analyze -v、.bugcheck、!thread 或 !irp 等命令,可以幫助您識別故障中涉及的驅動程式和資源。
- RESOURCE_NOT_OWNED、DRIVER_IRQL_NOT_LESS_OR_EQUAL 或 MULTIPLE_IRP_COMPLETE_REQUESTS 等錯誤通常揭示驅動程式衝突,需要透過詳細的 IRP 和堆疊分析來澄清。
- 結合使用驅動程式驗證工具、Sysinternals 和良好的故障排除實踐,有助於隔離故障硬體或軟體,並大幅減少藍色畫面現象。
當Windows電腦出現藍色畫面死機時,這不僅令人惱火:記憶體轉儲檔案中通常隱藏著一些有價值的訊息,可以告訴我們核心究竟發生了什麼。與其責怪記憶體、BIOS或立即重裝系統,不如學習如何讀取這些資料。
只要稍加練習,像 WinDbg 這樣的工具以及!analyze -v、.bugcheck 等函數,再加上正確使用符號,就能讓我們從「遇到藍屏錯誤」到「知道是哪個驅動程式、資源或裝置導致了藍屏死機」。本文將一步一步、詳細地講解如何使用內核轉儲文件分析藍屏死機,包括有哪些類型的轉儲文件、如何準備所有文件,以及如何使用命令來最大程度地利用分析結果。
什麼是藍色畫面死機(BSOD)?它包含哪些資訊?
當 Windows 遇到危及系統完整性且無法安全恢復的情況時,它會呼叫一個名為KeBugCheckEx 的內部核心函數。正是這個呼叫觸發了臭名昭著的藍色畫面死機 (BSOD)。
KeBugCheckEx 總是接收五個參數:一個停止代碼(錯誤檢查代碼)和四個提供錯誤技術上下文的附加參數。我們可以參考這些數據。
- 在藍色畫面上 如果系統未配置為自動重啟,則會出現經典情況。
- 在 Windows 事件日誌中在事件檢視器(系統日誌)中。
- 在記憶體轉儲檔案中 使用 WinDbg 和類似命令(小型轉儲、核心轉儲或完整轉儲)
!analyze -vo.bugcheck.
每個錯誤檢查代碼都有一個符號名稱和一個關聯的十六進位值。例如,錯誤檢查DRIVER_POWER_STATE_FAILURE 的代碼為0x9F,而RESOURCE_NOT_OWNED對應的代碼為0xE3。這些程式碼及其參數都會記錄在 Microsoft 錯誤檢查程式碼參考文件中,建議您始終將其放在手邊。
除了錯誤代碼外,藍色畫面可能還會顯示一個疑似相關的 .sys 驅動程式名稱。如果是第三方驅動程式(例如防毒軟體、網路卡、顯示卡等),我們通常就能明確找到問題所在。如果顯示的是通用系統元件(例如 ntoskrnl.exe、win32k.sys 等),或者根本沒有顯示任何內容,則需要執行記憶體轉儲並使用 WinDbg 進行進一步調查。
Windows 中的記憶體轉儲類型
要深入分析藍色畫面死機 (BSOD),我們需要 Windows 在故障發生時產生記憶體轉儲檔案 (DMP)。該文件記錄了錯誤發生時的系統狀態,並且可以是不同類型的文件。
在「啟動與故障復原」選項中(右鍵點選「此電腦/我的電腦」→屬性→進階系統設定→「進階」標籤→「啟動與故障復原」下的「設定」按鈕),您可以選擇幾種類型的轉儲檔案。每種文件都有其優點和缺點。
小型記憶體轉儲(Minimp)
minidump格式的檔案最小(約 64 KB),但對於進階偵錯而言也最為有限。不過,它在許多藍色畫面死機 (BSOD) 場景下仍然有助於快速診斷問題。
小型轉儲檔案儲存的資料包括:
- 停止訊息、錯誤檢查代碼及其參數.
- 處理器上下文 導致故障的處理器的 (PRCB)。
- 核心行程資訊 (EPROSS)崩潰時活動進程的
- 內核中的線程訊息 導致崩潰的線程的 (ETHREAD)。
- 核心模式呼叫堆疊 該線程(最多 16 KB)。
- 已載入驅動程式列表 在判決作出之時。
- 已載入和已下載的模組列表.
- 調試資料區塊 包含基本系統資訊。
這種類型的轉儲檔案通常會保存在%SystemRoot%\Minidump 目錄中(例如,C:\Windows\Minidump)。對於許多基本支援或診斷情況,使用!analyze -v指令對小型轉儲檔案進行徹底分析可能就足夠了。
核心記憶體轉儲
核心記憶體轉儲包含崩潰時核心記憶體的內容,但不包含使用者進程記憶體空間。它在檔案大小和詳細資訊之間取得了很好的平衡,通常是診斷大多數藍色畫面死機 (BSOD) 的建議選項。
此轉儲檔案以MEMORY.DMP的名稱保存在%SystemRoot% 目錄下(預設為C:\Windows\MEMORY.DMP)。其大小取決於核心使用的內存,但通常比小型轉儲檔案大得多,也比完整轉儲檔案更容易管理。
完整記憶體轉儲
完整的記憶體轉儲會保存錯誤發生時 RAM 中的幾乎所有內容:核心、使用者進程等。它是最詳細的,但也是佔用空間最大、配置要求最高的。
要使完整的轉儲文件有效,必須滿足以下幾個條件:
- El 分頁文件 必須在 Windows 安裝在同一個分割區。.
- 必須有 磁碟空間至少等於實體記憶體的大小 機器的
- 如果想要避免轉儲檔案損壞,請不要將頁面檔案移至另一個實體磁碟。
在記憶體大的生產環境中,完整轉儲可能不太實際,但對於非常複雜或間歇性的問題,它可以對定位問題起到至關重要的作用。
設定 Windows 以擷取和記錄藍色畫面死機 (BSOD)
在使用 WinDbg 之前,必須確保系統正確產生轉儲檔案並記錄藍色畫面事件。
在「啟動和恢復」視窗中,我們可以找到幾個相關選項:
- 將事件寫入系統日誌必須啟用此功能才能將錯誤檢查記錄到事件檢視器中。
- 寫入調試訊息在這裡,我們可以選擇小型記憶體轉儲、核心記憶體轉儲或完整記憶體轉儲。
- 轉儲檔案路徑: 預設 %SystemRoot%\MEMORY.DMP 內核/完整版。
- 自動重啟如果想要的話,建議取消勾選。 冷靜地觀看藍屏 並記下出現的內容。
對於某些製造商或支援部門,例如某些網路適配器,會要求使用者提交轉儲文件。該文件通常位於C:\Windows\memory.dmp,建議按日期/時間查找,以確定與上次故障對應的文件。
如果我們想要即使在系統凍結(鍵盤或滑鼠無回應)的情況下也能強制產生轉儲文件,那麼對於 PS/2 鍵盤(而非 USB/藍牙鍵盤)來說,還有一個非常有用的技巧,那就是配置註冊表,透過組合鍵觸發轉儲文件。
如果系統凍結,請使用鍵盤強制執行轉儲操作。
即使螢幕完全凍結,您也可以使用PS/2 鍵盤上的CrashOnCtrlScroll選項來產生記憶體轉儲。此方法不適用於 USB 或藍牙鍵盤。
在註冊表中,我們必須建立或修改以下鍵:
HKEY_LOCAL_MACHINE
System
CurrentControlSet
Services
i8042prt
Parameters
Nombre: CrashOnCtrlScroll
Tipo: REG_DWORD
Valor: 1
重新啟動後,您可以隨時(即使螢幕凍結)觸發受控崩潰,方法是先按右Ctrl鍵,再按兩次 Scroll Lock 鍵,讓系統產生記憶體轉儲檔案。這對於調查那些不會自動顯示藍色畫面死機 (BSOD) 的嚴重崩潰問題非常有用。
WinDbg核心轉儲分析簡介
WinDbg 是微軟用於核心偵錯和記憶體轉儲分析的頂級工具。它是免費的(目前也可以在 Microsoft Store 中以 WinDbg Preview 的形式下載),雖然乍一看可能令人生畏,但對於初步的藍色畫面死機 (BSOD) 分析,您只需要了解幾個基本選項。
我們可以將 WinDbg 安裝在故障機器本身或其他任何電腦上;.dmp 檔案可以透過網路、USB 甚至壓縮成 CAB 檔案進行複製。我們分析轉儲檔案的處理器和 Windows 版本不一定需要與崩潰機器的處理器和 Windows 版本相同。
從命令列啟動 WinDbg 並產生轉儲文件
在 WinDbg 中開啟記憶體轉儲檔案的經典方法是使用帶有`-z`參數的命令列,指定轉儲檔案的路徑。這可以與其他參數結合使用,例如符號或二進位檔案的路徑。
windbg -y <RutaSimbolos> -i <RutaBinarios> -z <RutaDump>
-v參數會啟用詳細模式,這對於查看更多上下文資訊非常有用。除了 WinDbg 之外,還有kd.exe,這是一個基於控制台的調試器,它幾乎可以實現相同的功能,但沒有圖形介面。
kd.exe -z "Ruta\al\volcado.dmp" -y "Ruta\simbolos" -i "Ruta\busqueda\binarios"
從圖形介面開啟轉儲文件
如果 WinDbg 已在被動模式下打開,您可以使用「檔案」→「開啟崩潰轉儲」功能表或快速鍵Ctrl+D載入崩潰轉儲檔案。選擇 .dmp 檔案(甚至是包含該檔案的 .cab 檔案),WinDbg 將載入崩潰資訊。
另一種方法是啟動 WinDbg,進入後運行.opendump命令,指定轉儲檔案的路徑,然後執行g(執行)命令來啟動轉儲偵錯會話:
.opendump C:\Windows\Memory.dmp
g
WinDbg 甚至允許 一次清理多個垃圾場新增多個參數 -z 在命令列中或透過重複操作 .opendump 使用不同的路線並管理多目的地會話。
在 WinDbg 中配置符號路徑
如果沒有符號文件,WinDbg 幾乎無法正常工作。符號檔案(.pdb)包含有關函數、內部結構、變數、偏移量等的偵錯訊息,對於可靠的分析至關重要,尤其是在處理核心時。
要使用 Microsoft 的公共符號而無需手動下載,最佳實踐是配置一個指向 Microsoft 官方伺服器和本機快取目錄的符號伺服器。例如,我們可以先建立一個名為C:\symbols 的資料夾,然後在 WinDbg 中以下列方式配置符號路徑:
SRV*c:\symbols*https://msdl.microsoft.com/download/symbols
這可以透過「檔案」→「符號檔案路徑」選單完成,或者在 WinDbg Preview 中,透過「檔案」→「設定」→「偵錯設定」調整「預設符號路徑」。首次分析特定係統的轉儲檔案時,偵錯器會自動從網路下載必要的符號,這可能需要幾分鐘時間,具體取決於您的網路連線。
需要注意的是,微軟的公共符號有時並不包含所有內部類型信息,因此您可能會看到類似“調試器未使用正確的符號”或引用無法解析類型的警告。對於基本的藍色畫面死機 (BSOD) 分析,公共符號通常足夠使用,但如果您需要更詳細的信息,則會受到限制。
初步分析:基本命令與錯誤檢查
載入轉儲檔案並配置符號後,WinDbg 通常會顯示一個包含系統資訊的標題欄以及類似「使用 !analyze -v 取得詳細偵錯資訊」的警告。這是我們進行初步分析的第一步。
!analyze -v指令會對轉儲檔案進行自動分析,通常會提供以下資訊:
- 錯誤檢查程式碼 (例如,0xE3、0xD1、0x9F、0x44…)。
- 參數 Arg1、Arg2、Arg3 和 Arg4 來自錯誤檢查。
- 最有可能的模組或驅動程式 故障原因(
Probably caused by). - 相關過程 那一刻(例如,Teams.exe)。
- 呼叫堆疊(堆疊追蹤) 引發崩潰的線程。
- 儲存桶資訊 以及失敗哈希值,可用於關聯重複錯誤。
例如,在實際的錯誤檢查案例中,如果出現 RESOURCE_NOT_OWNED (0xE3) 錯誤,分析結果可能表明某個線程試圖釋放它不擁有的資源,則該線程的進程顯示為Teams.exe ,並且指向win32kbase.sys文件,例如在DrvEnumDisplaySettings之類的函數中。這表示出錯的執行緒正在透過 Windows 圖形圖層從使用者空間查詢或操作顯示設定。
為了更深入地了解停止程式碼及其參數的細節,我們還有以下命令。 .bugcheck它會再次顯示錯誤檢查和四個參數,如果我們想重複該資訊而不重新運行所有內容,這將非常有用。 !analyze -v.
實際案例:驅動因素與典型衝突
藍色畫面死機 (BSOD) 分析通常圍繞著識別故障或異常的驅動程式、驅動程式衝突、不正確的記憶體存取、錯誤處理 I/O 請求套件 (IRP) 等問題展開。讓我們來看一些實際案例,以便更好地理解這個過程。
與 Teams 和 win32kbase.sys 相關的 RESOURCE_NOT_OWNED (0xE3)
在 Windows 10 系統中,如果執行數天後出現藍色畫面死機 (BSOD),錯誤代碼為0xE3 (RESOURCE_NOT_OWNED),則微型核心轉儲檔案會顯示類似下列內容:
RESOURCE_NOT_OWNED (e3)
A thread tried to release a resource it did not own.
Arguments:
Arg1: <dirección recurso>
Arg2: <dirección thread>
Arg3: 0
Arg4: 0
PROCESS_NAME: Teams.exe
STACK_TEXT:
...
win32kbase!DrvEnumDisplaySettings+0x356
win32kbase!NtUserEnumDisplaySettings+0x59
win32k!NtUserEnumDisplaySettings+0x15
nt!KiSystemServiceCopyEnd+0x28
...
這裡,偵錯器顯示錯誤檢查是由與Teams.exe關聯的執行緒觸發的,但關鍵時刻堆疊上的實際程式碼屬於win32kbase.sys,具體來說是DrvEnumDisplaySettings函數。這不一定意味著 Teams 是直接的罪魁禍首,而是Teams 呼叫了一個使用者 API,導致圖形子系統中出現同步或資源釋放錯誤。
這類診斷的結論通常是:問題出在 Windows 圖形堆疊、特定的顯示卡驅動程序,或是應用程式與驅動程式之間的互動。實際的解決方案可能包括更新 GPU 驅動程式、更新 Teams,甚至應用特定的 Windows 補丁,而不是只等待問題自行修復。
DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1) 與 NotMyFault
Sysinternals 的NotMyFault工具是一個教育工具,它允許您以可控的方式產生核心錯誤,從而學習如何分析螢幕截圖。例如,如果您從 NotMyFault 啟動“高 IRQL 故障(核心模式)”選項並按一下“執行錯誤”,則會強制出現DRIVER_IRQL_NOT_LESS_OR_EQUAL (0xD1) 錯誤。
在藍色畫面上,我們會看到類似DRIVER_IRQL_NOT_LESS_OR_EQUAL 的訊息,以及可能存在的候選驅動程式(例如,MyFault.sys,即該工具使用的驅動程式)。產生轉儲檔案並使用 WinDbg 開啟後,初始輸出可能如下所示:
Use !analyze -v to get detailed debugging information.
BugCheck D1, {e1071800, 1c, 0, f7cda403}
*** ERROR: Module load completed but symbols could not be loaded for myfault.sys
Probably caused by : memory_corruption
Followup: memory_corruption
雖然調試器指向記憶體損壞,但我們知道真正的原因與 NotMyFault 及其驅動程式有關。為了確認這一點,我們可以繼續使用類似`!thread` 的命令進行跟踪,以查看線程在故障發生時發出的調用,並使用 ` !irp` 命令分析涉及的 IRP(如果錯誤檢查與 I/O 操作相關)。
例如,使用`!thread <dir_thread>` 命令,我們可以查看線程的堆疊跟踪,並找到出現`myfault+0x403` 的指令,從而確定測試驅動程式出錯的位置。從那裡,我們可以檢查 IRP、記憶體狀態等等,就像處理真實 bug 一樣。
多個 IRP 完成請求 (0x44) 和 USB 衝突
另一個非常典型的例子是錯誤檢查。 多個 IRP 完成請求 (0x44)當出現此錯誤時, IRP(I/O 請求包)會被多次完成通常是因為兩個不同的司機都認為自己擁有同一個IRP,而且都打電話詢問。 IoCompleteRequest().
使用!analyze -v進行分析可能會產生類似如下的描述:
MULTIPLE_IRP_COMPLETE_REQUESTS (44)
A driver has requested that an IRP be completed (IoCompleteRequest()), but
the packet has already been completed.
...
Arguments:
Arg1: <IRP_ADDRESS>
Arg2: 00000d75
Arg3: 00000000
Arg4: 00000000
Probably caused by : usbehci.sys
最初,嫌疑對像似乎是usbehci.sys,它是微軟用於 USB EHCI 控制器的驅動程式。然而,由 Windows 原生驅動程式引起且不涉及任何第三方互動的 bug 相對罕見。為了找到問題所在,我們使用 bugcheck 提供的 IRP 位址(Arg1)並運行!irp <IRP_ADDRESS>:
!irp 87e5a490
Irp is active with 3 stacks 3 is current (= 0x87e5a548)
...
> [ f, 0] 0 c0 8a055618 00000000 b69de300-00000000 Success Error
\Driver\usbehci ax88172
Args: b70989c0 00000000 00220003 00000000
在最後一行,我們可以清楚地看到字串“\Driver\usbehci ax88172”,這表明 IRP 已經遍歷了usbehci.sys和一個名為ax88172.sys的驅動程序,後者與特定的 USB 網路晶片組 (AX88172) 相關聯。因此,我們可以得出結論,衝突源自於這個第三方 USB 網路卡驅動程序,而不是微軟的通用 EHCI 驅動程式。
在這種情況下,解決方案包括更新 USB 適配器驅動程式、更換設備,或必要時將其移除。這種 IRP 分析對於與 USB、儲存裝置、網路卡以及任何使用密集型 I/O 的元件相關的藍色畫面死機 (BSOD) 問題尤其有用。
核心模式下有用的 WinDbg 指令
除了!analyze -v和.bugcheck之外,還有幾個 WinDbg 擴展和命令在我們需要更深入地了解內核轉儲時非常有用。
一些最常見的例子包括:
- !線:顯示有關線程的詳細信息,包括其調用堆疊、狀態、關聯的 IRP 等。它允許您查看系統崩潰時正在運行的線程的“最後操作”。
- !進程 0 0此清單顯示崩潰發生時所有正在執行的進程。它有助於識別電腦上是否運行任何可疑的進程、服務、EDR、防毒軟體等。
- !irp分析特定的 IRP 並顯示 它所經過的司機的痕跡I/O 命令、標誌等是與以下方面相關的錯誤的關鍵: 多個 _ IRP _ 完成 _ 請求 以及其他 I/O 錯誤。
- !cpuinfo:提供有關處理器的資訊(製造商、MHz、簽章、特性),用於驗證硬體環境。
- !peb:顯示 PEB(進程環境區塊)的詳細信息,例如電腦名稱、Windows 安裝路徑、處理器數量等。
- !token:提供有關進程或執行緒的安全性令牌、權限和安全性上下文的資訊。
- .cls:清除命令窗口,就像在普通控制台中一樣。
此外,許多特定的檔案系統副檔名(例如 PnP、NTFS 等)可讓您從轉儲檔案中提取更多資訊。在某些情況下,WinDbg 會指示是否存在BLACKBOX*(BLACKBOXBSD、BLACKBOXNTFS、BLACKBOXPNP、BLACKBOXWINLOGON),這些是在錯誤檢查期間擷取的額外資料區塊,用於協助診斷特定係統區域的問題。
使用驅動程式驗證程式尋找問題驅動程式
絕大多數的 Windows 藍色畫面死機 (BSOD) 錯誤都是由故障或程式編寫不良的驅動程式所造成。為了主動偵測這類問題,系統內建了一個強大的工具:驅動程式驗證程式。
驅動程式驗證程式即時運行,並對選定的驅動程式進行一系列測試和壓力測試:它會檢查正確的記憶體使用情況、核心池使用情況、IRQL、IRP 等。如果偵測到驅動程式運作異常,它可以強制執行受控藍屏死機,以便我們分析更清晰的轉儲文件,通常很容易從中識別出問題所在。
要啟動驅動程式驗證程式管理器,只需以管理員權限開啟命令提示字元並鍵入:
verifier
接下來,我們可以選擇要驗證的驅動程式。謹慎行事是明智的:驗證程序會增加系統開銷並可能降低效能,因此建議僅對少數可疑驅動程式啟用驗證,而不是不加選擇地選擇所有驅動程式。
一旦驅動程式驗證程式偵測到異常行為並觸發藍色畫面死機 (BSOD),我們可以使用 WinDbg 分析核心轉儲文件,並有望清楚地看到哪個驅動程式被捕獲以及它犯了什麼錯誤。微軟關於驅動程式驗證程式的參考文章詳細解釋了各種選項和使用策略。
為工程師和技術人員提供的實用建議
無論你是驅動程式開發人員、與核心互動的軟體開發人員,還是負責處理所有藍屏死機問題的技術人員,都有一些值得牢記的準則,以避免迷失在藍屏死機的叢林中。
如果錯誤與你自己的程式碼有關,第一步就是系統地使用核心偵錯器來重現和分析問題。透過將偵錯器連接到目標機器(透過網路、串列埠等),錯誤檢查會導致系統在偵錯器內部停止運行,而不是直接顯示藍色畫面。這樣,你就可以檢查記憶體、堆疊、結構體,並修正程式碼。
在其他情況下,錯誤檢查可能是由於我們無法控制的第三方驅動程式、硬體或軟體造成的。在這種情況下,目標從「修復程式碼」轉變為隔離和緩解問題。
- 使用 WinDbg 和轉儲分析來識別可疑的驅動程式或硬體元件。
- 更新或還原 驅動程式版本、BIOS、韌體或相關應用程式。
- 移除或替換 USB裝置、顯示卡、網路介面卡 衝突性的。
- 依靠 事件檢視器、Sysinternals、網路監控和分析工具 更多背景資訊。
許多看似神秘的問題可以透過基本的故障排除步驟解決:查閱文件、檢查文件版本和日期、重新安裝關鍵元件或停用衝突模組。分析轉儲文件可以讓我們明確地找出問題的方向,並且常常節省我們數小時的反覆試驗時間。
同樣重要的是要記住,在類似導致CrowdStrike Falcon事件和其他 EDR 系統故障的環境中,最常見的問題都圍繞著藍屏死機 (BSOD) 的觸發原因以及如何快速識別它。正確配置 WinDbg,使其包含符號並具備清晰的轉儲文件打開和分析流程,可以讓你在幾分鐘內縮小故障範圍,否則可能最終只能“格式化並重新安裝系統”,而無法真正了解故障原因。
簡而言之,結合良好的記憶體轉儲配置、WinDbg、Driver Verifier 和 Sysinternals 等工具的規範使用,以及有條不紊地審查日誌和堆疊的習慣,可以將不可預測的敵人的藍色螢幕變成內核故障的非常準確的資訊來源,幫助我們做出更明智的技術決策。