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