Visual Studio調試器指南---異常處理(調試)


異常是在程序運行時發生的不正常情況。 異常通常表示有需要調試的問題。 發生異常時,調試器將向“輸出”窗口中寫入一條異常消息,但在““選項”對話框 ->“調試”->“常規””對話框中禁用了該選項的情況除外。

發生異常時,調試器不一定會中斷執行。

  • 如果發生了非 ASP.NET 異常並且沒有進行處理,調試器總是會中斷執行。

  • 您可以讓調試器在引發異常時立即中斷執行(在調用任何處理程序之前)。

  • 如果使用 如何:單步執行“僅我的代碼” 進行調試,您還有第三個選項。 您可以讓調試器在遇到任何未由用戶代碼(“我的代碼”)中的處理程序處理的異常時中斷執行。 有關更多信息,請參見如何:在遇到用戶未經處理的異常時中斷。

  • ASP.NET 有一個頂級異常處理程序,該處理程序在對異常進行處理時向瀏覽器用戶顯示錯誤頁面。 該頂級異常處理程序會阻止未經處理的異常中斷到調試器中,除非打開了“僅我的代碼”。 請確保對 ASP.NET 調試啟用“僅我的代碼”。

    請記住,如果發生了異常但根本沒有進行處理,調試器總是會中斷執行。 用戶未處理的設置不會更改這一行為。

Visual Studio 調試器識別下列類別的異常:

  • C++ 異常

  • 公共語言運行時異常

  • 托管調試助手

  • 本機運行時檢查

  • Win32 異常

大多數異常都有相應的處理程序,用於在異常發生時做出響應。 這樣程序便有可能從異常狀況中恢復過來。 本機運行時檢查沒有處理程序。在 Visual Basic 應用程序中,調試器將所有錯誤都表示為異常,即使使用 On Error 樣式的錯誤處理程序。對於 Visual Basic 和 C#,調試器現在具備了一項新增的異常助手功能,此功能可在發生異常時提供更多信息。

在引發異常時中斷

調試器可以在發生異常時立即中斷應用程序的執行,使您有機會在調用處理程序之前對異常進行調試。

如果您在啟用 如何:單步執行“僅我的代碼” 的情況下進行調試,行為會略有不同。 啟用“僅我的代碼”時,調試器將忽略在“我的代碼”以外引發並且不通過“我的代碼”的最可能的公共語言運行時 (CLR) 異常。 但是,如果該異常完全未進行處理,調試器將始終中斷。

如果將調試器設置為在引發 CLR 異常時中斷且調試器在發生 CLR 異常時中斷,則某些情況下調試器突出顯示的行可能會稍有偏差。 例如,如果從托管代碼的 if 語句內部引發異常,就可能發生這種情況。 調試器突出顯示要執行的下一個 CLR 指令所在的行,即 throw 之后的行,而不是 throw 語句所在的行。

默認情況下,“異常”對話框列出每一類別中最常見的異常。 您可以添加自己的異常和刪除所添加的異常。 Visual Studio 將添加的異常的列表與解決方案數據保存在一起,這樣在下一次打開和運行項目時這些異常將可用。

設置在引發異常時中斷執行

  1. 在“調試->窗口”菜單中,單擊“異常”。

  2. 在“異常”對話框中,為整個類別的異常(如“公共語言運行時異常”)選擇“引發”。

    - 或 -

    展開一個類別的異常(如“公共語言運行時異常”)的節點,並為該類別中的特定異常選擇“引發”。

在“調試”菜單中添加“異常”命令

  1. 在“工具”菜單上,單擊“自定義”。

    出現“自定義”對話框。

  2. 單擊“命令”選項卡,在“菜單欄”列表中,單擊“調試”。

  3. 單擊“添加命令”。

  4. 在“添加命令”對話框的“類別”中,單擊“調試”。

  5. 在“命令”中,單擊“異常設置”,然后單擊“確定”。

  6. (可選)可以單擊“下移”以調整“異常”命令在“調試”菜單中的位置。

  7. 單擊“關閉”。

在遇到用戶未經處理的異常時中斷

如果使用 如何:單步執行“僅我的代碼” 調試,可以讓調試器在發生任何沒有由用戶代碼(“我的代碼”)中的處理程序進行處理的異常時中斷。 下面的過程顯示了如何使用“異常”對話框來確定要在發生哪些用戶未經處理的異常時中斷。

默認情況下,“異常”對話框列出每一類別中最常見的異常。 您可以添加自己的異常和刪除所添加的異常。 Visual Studio 將添加的異常的列表與解決方案數據保存在一起,這樣在下一次打開和運行項目時這些異常將可用。

  1. 在“調試”菜單中,單擊“異常設置”。

  2. 在“異常”對話框中,為整個類別的異常(如“公共語言運行時異常”)選擇“用戶未處理的”。

    - 或 -

    展開某種異常類別(如“公共語言運行時異常”)的節點,並為該類別中的特定異常選擇“用戶未處理的”。

  3. 單擊“確定”。

在出現異常之后繼續執行

由於出現異常而執行調試器中斷時,會顯示一個對話框。 對於 Visual Basic 或 C#,在默認情況下,您將看到異常助手對話框。 對於 C++,您將看到早期的 “異常” 對話框。 如果您使用的是 Visual Basic 或 C#,但在“選項”對話框中禁用了“異常助手”,您將看到“異常”對話框。

出現“異常助手”或“異常”對話框時,可嘗試對導致異常的問題進行修復。

托管代碼

在托管代碼中,您可以在出現了未經處理的異常后在同一線程內繼續執行。 “異常助手”將調用堆棧回退到引發異常的點。

本機代碼

在本機 C/C++ 中,您有兩個選項:

  • 您可以單擊“中斷”並嘗試修復問題。 在中斷模式下,可右擊“調用堆棧”窗口中的幀並選擇快捷菜單中的“展開到此幀”來展開調用堆棧。 如果未能修復問題,則繼續調試時,“異常”對話框將再次顯示。 否則,“異常”對話框將不會再次出現。

  • 您可以單擊“繼續”繼續執行,而不嘗試修復問題。 “異常”對話框隨即重新出現。

混合模式

如果在調試本機和托管混合的代碼時遇到未經處理的異常,操作系統約束將會阻止調用堆棧展開。 如果嘗試使用快捷菜單來展開調用堆棧,則會出現一個錯誤消息,告訴您在混合代碼調試期間,調試器無法在異常未得到處理的情況下展開調用堆棧。

在發生異常后檢查系統代碼

發生異常時,您可能需要檢查系統調用內部的代碼,以確定該異常的起因。 如果您沒有為系統代碼加載符號,或者啟用了“僅我的代碼”,則下面的步驟說明了如何執行此操作。

在發生異常后檢查系統代碼

  1. 在“調用堆棧”窗口中右擊,然后單擊“顯示外部代碼”。

    如果未啟用“僅我的代碼”,則快捷菜單中不提供此選項,默認情況下顯示系統代碼。

  2. 右擊此時顯示在“調用堆棧”窗口中的外部代碼幀。

  3. 指向“加載符號”,然后單擊“Microsoft 符號服務器”。

    1. 如果啟用了“僅我的代碼”,則將顯示一個對話框。 它指出“僅我的代碼”現在已禁用。 要單步執行系統調用,必須這樣做。

    2. 將出現“正在下載公共符號”對話框。 下載完畢后會自動關閉該對話框。

  4. 現在即可在“調用堆棧”窗口和其他窗口中檢查系統代碼。 例如,您可以雙擊調用堆棧幀在源窗口或“反匯編”窗口中查看代碼。

使用本機運行時檢查

在 Visual C++ 中,可以使用本機 runtime_checks 捕捉常見的運行時錯誤,例如:

  • 堆棧指針損壞。

  • 本地數組溢出。

  • 堆棧損壞。

  • 未初始化的局部變量上的依賴項。

  • 較短變量賦值的數據丟失。

如果使用帶有優化 (/O) 版本的 /RTC,將導致編譯器錯誤。 如果在優化版本中使用 runtime_checks 雜注,則該雜注無效。

調試啟用了運行時檢查的程序時,如果出現運行時錯誤,該程序的默認操作是停止並切換到調試器。 可以更改任何運行時檢查的此默認行為。 有關更多信息,請參見 異常處理(調試)。

在調試版本中啟用本機運行時檢查

  • 使用 /RTC 選項,並與 C 運行庫(如 /MDd)調試版鏈接。

使用無 C 運行庫的運行時檢查

如果鏈接程序而不鏈接 C 運行庫(使用 /NODEFAULTLIB)並希望使用運行時檢查,則必須鏈接 RunTmChk.lib。

_RTC_Initialize 為運行時檢查初始化程序。 如果未鏈接 C 運行庫,必須在調用 _RTC_Initialize 之前檢查是否用運行時錯誤檢查編譯了程序:

 
#ifdef __MSVC_RUNTIME_CHECKS
    _RTC_Initialize();
#endif

如果不鏈接 C 運行庫,還必須定義一個稱為 _CRT_RTC_INITW 的函數。 _CRT_RTC_INITW 將用戶定義的函數安裝為默認的錯誤報告函數,如下所示:

 
// C version:
_RTC_error_fnW __cdecl _CRT_RTC_INITW(
        void *res0, void res1, int res2, int res3, int res4)
{
    // set the error handler.
    return &MyErrorFunc; 
}

// C++ version:
extern "C" _RTC_error_fnW __cdecl _CRT_RTC_INITW(
       void *res0, void res1, int res2, int res3, int res4)
{
    // set the error handler:
    return &MyErrorFunc;
}

安裝了默認錯誤報告函數后,可以使用 _RTC_SetErrorFuncW 安裝附加錯誤報告函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM