您可以透過各種方法來攔截和處理使用者模式和內核模式應用程式中的例外狀況。 使用中的調試程式、驗屍調試程式或內部錯誤處理例程都是處理例外狀況的常見方式。
如需了解這些例外處理程序的優先順序詳細資訊,請參閱 啟用後期偵錯。
當 Microsoft Windows 作業系統允許偵錯工具處理例外狀況時,產生例外狀況的應用程式會進入偵錯工具。 也就是說,應用程式會停止,而除錯工具會啟動。 然後調試程式就可以以某種方式處理例外狀況,或分析情況。 然後調試程式可以結束進程,或讓它繼續執行。
如果調試程式忽略例外狀況並讓應用程式繼續執行,作系統會尋找其他例外狀況處理程式,就好像沒有調試程序一樣。 如果已處理例外狀況,應用程式會繼續執行。 不過,如果例外狀況仍然未處理,調試程式就會獲得第二次處理情況的機會。
使用調試程式分析例外狀況
當例外狀況或事件進入偵錯工具時,您可以使用偵錯工具來檢查正在執行的程式碼,以及應用程式所使用的記憶體。 藉由改變特定數量或跳到應用程式中的不同點,您或許可以移除例外狀況的原因。
您可以發出 gh (已處理例外的 Go) 或 gn (未處理例外的 Go) 命令,以繼續執行。
如果您在調試程式第二次處理例外狀況的機會中發出 gn 命令,應用程式就會結束。
Kernel-Mode 例外狀況
內核模式程式代碼中發生的例外狀況比使用者模式例外狀況更為嚴重。 如果未處理內核模式例外狀況,則會發出 錯誤檢查 ,並停止系統。
如同使用者模式例外狀況,如果內核模式調試程式附加至系統,調試程式會在 錯誤檢查畫面 出現之前收到通知(也稱為 藍色畫面)。 如果沒有附加調試程式,就會顯示錯誤檢查畫面。 在此情況下,作業系統可能會建立 崩潰傾印檔案。
從調試程式控制例外狀況和事件
您可以設定除錯程式以特定方式回應指定的例外狀況和事件。
除錯程式可以設定每個例外狀況或事件的中斷狀態:
事件發生時,事件可能會造成調試程式中斷(「第一次機會」)。
在其他錯誤處理程式獲得回應的機會之後,事件可能會中斷(「第二次機會」)。
事件也可以傳送訊息給調試程式,但繼續執行。
調試程式可以忽略 事件。
調試程式也可以設定每個例外狀況和事件的處理狀態。 調試程式可以將事件視為已處理的例外狀況或未處理的例外狀況。 當然,實際上不是錯誤的事件不需要任何處理。
您可以執行下列其中一項動作來控制中斷狀態和處理狀態:
(CDB 和 NTSD)在命令行上使用 -x、-xe、-xd、-xn 或 -習 選項。
(CDB、NTSD 和 KD)在 Tools.ini 檔案中使用 sxe 或 sxd 關鍵詞。
(僅限 WinDbg)在 [偵錯] 功能選取 [事件篩選] 以開啟 [事件篩選] 對話框,然後選擇您想要的選項。
SX\* 命令、-x\* 命令行選項和 sx\* Tools.ini 關鍵詞通常會設定指定事件的中斷狀態。 您可以新增 -h 選項,以設定處理狀態。
有四個特殊事件代碼(cc、 hc、 bpec 和 ssec)一律指定處理狀態,而不是中斷狀態。
您可以使用 .lastevent (顯示最後一個事件) 命令來顯示最新的例外狀況或事件。
控制中斷狀態
當您設定例外狀況或事件的中斷狀態時,可以使用下列選項。
| 指令 | 狀態名稱 | 說明 |
|---|---|---|
| SXE 或 -xe | 中斷 (已啟用) |
發生此例外狀況時,目標會立即進入除錯器。 此中斷會在啟動任何其他錯誤處理程式之前發生。 這個方法稱為 第一次機會處理。 |
| SXD 或 -xd | 第二次機會休息 (停用) |
調試程式不會針對這類第一次發生例外狀況而中斷(雖然會顯示訊息)。 如果其他錯誤處理程式無法解決此例外狀況,執行會停止,且目標會進入偵錯工具。 這個方法稱為 第二次機會處理。 |
| SXN 或 -xn | 輸出 (通知) |
發生此例外狀況時,目標應用程式不會啟動偵錯工具。 不過,會顯示通知使用者此例外狀況的訊息。 |
| SXI 或 -xi | Ignore |
發生此異常時,目標應用程式不會進入調試器,也不會顯示任何訊息。 |
如果 SX* 設定未預期例外狀況,目標應用程式在第二次機會中斷調試程式。 本主題的下列「事件定義和預設值」一節會列出事件的默認狀態。
若要使用 WinDbg 圖形化介面設定事件狀態,請在 [偵錯] 功能表上選擇 [事件篩選],從對話框中的清單選擇您想要的事件,然後選取 [已啟用]、[已停用]、[輸出] 或 [忽略]。
控制處理狀態
除非您使用 gh (Go with Exception Handled) 命令,否則所有事件都會被視為未處理。
除非您搭配 -h 選項使用 * 命令,否則所有例外狀況都會被視為未處理。
此外, SX* 選項可以設定無效句柄的處理狀態、STATUS_BREAKPOINT中斷指示,以及單一步驟例外狀況。 (此組態與其中斷設定不同。當您設定其中斷狀態時,這些事件會分別命名為 ch、 bpe和 sse。 當您設定其處理狀態時,這些事件會分別命名為 hc、 bpec 和 ssec。 (如需事件的完整清單,請參閱下列「事件定義和預設」一節。)
您可以設定 CTRL+C 事件 (cc) 的處理狀態,但無法設定其中斷狀態。 如果應用程式收到 CTRL+C 事件,應用程式一律會進入偵錯器。
當您在cc、hc、bpec和ssec事件上使用 SX* 命令,或當您搭配例外狀況上的 -h 選項使用 SX* 命令時,會發生下列動作。
| 指令 | 狀態名稱 | 說明 |
|---|---|---|
SXE |
處理 |
當執行繼續時,該事件被視為已處理。 |
SXD、SXN、SXI |
未處理 |
執行繼續時,事件會被視為未處理。 |
若要使用 WinDbg 圖形化介面來設定處理狀態,請在 [偵錯] 功能選取 [事件篩選],從 [事件篩選] 對話框中的清單選取您想要的事件,然後選取 [已處理] 或 [未處理]。
自動命令
調試程式也可讓您設定當事件或例外狀況造成調試程式中斷時自動執行的命令。 您可以為第一次中斷設定命令字串,並為第二次中斷設定命令字串。 您可以使用 SX\* 命令或 偵錯 | 事件篩選 命令來設定這些字串。 每個命令字串可以包含多個以分號分隔的命令。
不論中斷狀態為何,都會執行這些命令。 也就是說,如果中斷狀態為 「忽略」,命令仍會執行。 如果中斷狀態為「第二次機會中斷」,則第一次機會命令會在例外狀況第一次發生時執行,在涉及任何其他例外狀況處理程式之前。 命令字串可以結束執行命令,例如 g (Go)、gh (已處理例外狀況的 Go),或 gn (不處理例外狀況的 Go)。
事件定義和預設值
您可以變更下列例外狀況的中斷狀態或處理狀態。 預設的中斷狀態已被顯示。
下列例外狀況的默認處理狀態一律為「未處理」。 請小心變更此狀態。 如果您將此狀態變更為 「已處理」,則會將此類型的所有第一次機會和第二次例外狀況視為已處理,而且此設定會略過所有例外狀況處理例程。
| 事件代碼 | 意義 | 默認中斷狀態 |
|---|---|---|
asrt |
斷言失敗 |
休息 |
av |
存取違規 |
休息 |
分米 |
數據不對齊 |
休息 |
dz |
整數除以零 |
休息 |
c000008e |
浮點除以零 |
休息 |
啊 |
C++ EH 例外狀況 |
第二次機會中斷 |
gp |
保護頁錯誤 |
休息 |
Ⅱ |
非法的指令 |
第二次機會中斷 |
iov |
整數溢位 |
休息 |
ip |
頁面內 I/O 錯誤 |
休息 |
isc |
無效的系統呼叫 |
休息 |
lsq |
無效的鎖定順序 |
休息 |
sbo |
堆疊緩衝區溢位 |
休息 |
蘇聯 |
堆疊溢位 |
休息 |
wkd |
喚醒調試程式 |
休息 |
aph |
程式卡死 如果 Windows作系統得出結論,進程已停止回應,就會觸發此例外狀況(也就是 已停止回應)。 |
休息 |
3c |
子應用程式終止 |
第二次機會中斷 |
ch |
無效的句柄 |
休息 |
Number |
任何編號的例外狀況 |
第二次機會中斷 |
注意您可以使用 ah(判斷提示處理) 命令,覆寫特定地址的 asrt 中斷狀態。 ch 和 hc 事件代碼會參考相同的例外狀況。 當您控制其中斷狀態時,請使用 sx* ch。 當您控制其處理狀態時,請使用 sx* hc。
您可以變更下列例外狀況的中斷狀態或處理狀態。 預設的中斷狀態已被顯示。
下列例外狀況的默認處理狀態一律為 「已處理」。 由於這些例外狀況是用來與調試程序通訊,您通常不應該將其狀態變更為「未處理」。 如果調試程式忽略例外狀況,此狀態會導致其他例外狀況處理程式攔截例外狀況。
應用程式可以使用 DBG_COMMAND_EXCEPTION (dbce) 與調試程序通訊。 此例外狀況類似於斷點,但您可以使用 SX* 命令,以特定方式回應此例外狀況。
| 事件代碼 | 意義 | 默認中斷狀態 |
|---|---|---|
dbce |
特殊調試程式命令例外狀況 |
忽視 |
vcpp |
特殊的Visual C++例外狀況 |
忽視 |
wos |
WOW64 單一步驟例外狀況 |
休息 |
wob |
WOW64 斷點例外狀況 - |
休息 |
上證 |
單一步驟例外狀況 |
休息 |
BPE |
斷點例外狀況 |
休息 |
CCE |
CTRL+C 或 CTRL+BREAK 如果目標為主控台應用程式,並將 CTRL+C 或 CTRL+BREAK 傳遞給它,就會觸發此例外狀況。 |
休息 |
注意 上表的最後三個例外狀況有兩個不同的事件代碼。 當您控制其中斷狀態時,請使用 sse、bpe 和 cce。 當您控制其處理狀態時,請使用 ssec、 bpec和 cc。
當您偵錯 Managed 程式代碼時,下列例外狀況很有用。
| 事件代碼 | 意義 | 預設狀態 |
|---|---|---|
clr |
共通語言執行階段例外狀況 |
第二次機會中斷 未處理 |
clrn |
Common Language Runtime 通知例外狀況 |
第二次機會中斷 已處理 |
您可以變更下列事件的中斷狀態。 因為這些事件不是例外狀況,因此其處理狀態無關緊要。
| 事件代碼 | 意義 | 默認中斷狀態 |
|---|---|---|
伺服器 (if referring to "server") |
系統錯誤 |
忽視 |
cpr[:Process] |
程序創建 設定此事件的中斷狀態僅適用於使用者模式偵錯。 此事件不會在核心模式中發生。 只有當您已透過 -o命令行選項 或 .childdbg (偵錯子進程) 命令啟動子進程偵錯時,才能控制此事件。 進程名稱可以包含可選的檔案名稱副檔名,並使用星號()或問號(?)作為萬用字元。 調試程式只會記住最新的 cpr 設定。 不支援個別進程的個別設定。 包含 cpr 和 Process 之間的冒號或空格。 如果省略 Process ,此設定會套用至任何子進程建立。 |
忽視 |
epr[:Process] |
進程結束 設定此事件的中斷狀態僅適用於使用者模式偵錯。 此事件不會在核心模式中發生。 只有當您已透過 -o命令行選項 或 .childdbg (偵錯子進程) 命令啟動子進程偵錯時,才能控制此事件。 進程名稱可以包含可選的檔案名稱副檔名,並使用星號()或問號(?)作為萬用字元。 調試程式只會記住最新的 epr 設定。 不支援個別進程的個別設定。 在 epr 和 Process 之間包含冒號或空格。 如果省略 Process ,此設定會套用至任何子進程結束。 |
忽視 |
ct |
執行緒建立 |
忽視 |
et |
線程結束 |
忽視 |
ld[:模組] |
載入模組 如果您指定 Module,當載入具有此名稱的模組時,就會發生中斷。 模組 可以指定模組的名稱或位址。 如果使用名稱, Module 可能會包含各種通配符和規範。 (如需語法的詳細資訊,請參閱 字串通配符語法。 調試程式只會記住最新的 ld 設定。 不支援個別模組的個別設定。 在 ld 和 Module 之間包含冒號或空格。 如果省略 Module ,則會在載入任何模組時觸發事件。 |
輸出 |
ud[:Module] |
卸除模組 如果您指定 Module,當具有此名稱的模組或在此基位址卸除時,就會發生中斷。 模組 可以指定模組的名稱或位址。 如果使用名稱,Module 可以是確定的名稱,或包含通配符。 如果 Module 是確切的名稱,則會使用目前的調試程式模組清單立即解析為基位址,並儲存為位址。 如果 Module 包含通配符,則當卸除事件發生時,模式字串會保留供稍後比對。 很少發生,偵錯器沒有載入解除事件的名稱資訊,只能透過基位址來匹配。 因此,如果 Module 包含通配符,調試程式就無法在這個特定的卸除案例中執行名稱比對,並在卸除任何模組時中斷。 調試程式只會記住最新的 ud 設定。 不支援個別模組的個別設定。 包含 ud 與 Module 之間的冒號或空格。 如果省略 Module ,則會在載入任何模組時觸發事件。 |
輸出 |
out[:輸出] |
目標應用程式輸出 如果您指定 Output,則只有在收到符合指定模式的輸出時,才會發生中斷。 輸出 可以包含各種通配符和規範。 (如需語法的詳細資訊,請參閱 字串通配符語法。不過, 輸出 不能包含冒號或空格。 比對不區分大小寫。 包含 out 和 Output 之間的冒號或空格。 |
忽視 |
ibp |
初始斷點 (此事件發生在偵錯會話的開頭,以及重新啟動目標計算機之後。 |
在使用者模式中:中斷。 您可以使用 -g命令列選項,將此狀態變更為 [忽略]。 在核心模式中: 忽視。 您可以透過各種方法將此狀態變更為「已啟用」。 如需如何變更此狀態的詳細資訊,請參閱 當機和重新啟動目標計算機。 |
iml |
初始模組載入 (僅限核心模式) |
忽略。 您可以透過各種方法將此狀態變更為「中斷」。 如需如何變更此狀態的詳細資訊,請參閱 當機和重新啟動目標計算機。 |