Visual Studio - 調試
異常處理機制
windows預定義了一系列的異常錯誤碼,每種程序異常都有一個對應的錯誤碼,windows系統將這些類似鍵值對關系的數據存儲在異常處理表中(稱為SEH結構化異常處理表)。當CPU執行程序指令時,如果指令出現錯誤,那麽CPU會識別錯誤所對應的錯誤碼,接著執行流程會進入SEH,查找錯誤碼所對應的處理程序,C++、.Net的程序異常都是由RaiseException函數進行處理,異常被處理之後CPU才會繼續執行下一句指令。
異常碼 處理程序0xC0000005 AccessViolationExceptionHandler( )
0x80000003 LaunchOrNotifyDebugger( )
……
比如打開一個編譯後的程序(如:CUI程序MyApp.exe),當程序出現異常後會被CPU掛起,會進入RaiseException,假如代碼具有try、catch塊,則會把異常交給try、catch處理,如果沒有try、catch塊,那麽異常會交給windows自帶的異常處理塊,該異常處理塊會檢查MyApp.exe的程序代碼是否是由某個調試器運行起來的,如果是,就向調試器發出通知,這樣,調試器就會對異常做出處理,比如visual studio自帶的調試器就是在此時拋出異常信息的,但如果MyApp.exe的程序代碼並不是由某個調試器運行起來的,那麽window就要調用內置的Dr Watson調試器對異常代碼進行"屍檢",也即它會通過一個提示框將錯誤信息拋出。
開啟web應用程序的調試
打開web.config,在System.Web配置節將compilation 設為true即可開啟調試
<system.web><compilation debug="false" targetFramework="4.6.1" />
</system.web>
當設為false後:
斷點調試
普通斷點
光標定位到所在行或直接單擊行左側空白處,會顯示一個紅色圖標表示斷點到此處,程序運行時執行到斷點處就會暫停。
斷點後按F5或直接點擊啟動按鈕,當程序執行到斷點處會暫停,此時可以查看變量當前的值。
條件
執行到斷點處並不會暫停,直到滿足預設的條件後才會暫停。右擊斷點的紅圖標 - 條件,可以看到與條件有關的三個下拉選項
條件表達式:可設置一個當前程序所使用的語言的表達式,比如C#的表達式,表達式為true時就會進入斷點,程序會暫停。
命中次數:使循環體循環到某個特定次數的時候才暫停,可設置==、>=或數倍於,可描述為:當前循環次數==或>=或數倍於
篩選器:指定當執行到哪個線程時才會進入斷點
當循環次數>=500時會進入斷點,下圖可以看到c=499時進入中斷模式,因為0-499就是500次。
在斷點模式下可以右擊紅色斷點圖標繼續設置斷點條件,達到條件會再次進入斷點。右擊斷點 - 條件,將命中次數設為800
按繼續,會發現循環只有在前進到800次時才會進入斷點。
操作
下斷點後,右擊斷點,選擇"操作",這種調試方式不會進入中斷模式,但會將指定的變量輸出到輸出窗口,輸入框可填寫由VS提供的變量占位符和你想查看的變量值,當命中斷點後會將輸入框設置的變量當做文本輸出到輸出窗口,變量值應填寫在{}括號中
$FUNCTION:將當前斷點所在的函數的名稱作為字符輸出$CALLER:將正在調用當前函數的函數的名稱作為字符輸出
$ADDRESS:將正在調用當前函數的指令作為字符輸出
$CALLSTACK:將正在執行當前函數的堆棧名稱作為字符輸出
$PID:將正在調用當前函數的進程ID作為字符輸出
$PNAME:將正在調用當前函數的進程名稱作為字符輸出
$TID:將正在調用當前函數的線程ID作為字符輸出
$TNAME:將正在調用當前函數的線程名稱作為字符輸出
如:
可取消勾選繼續執行,這樣當命中斷點後會中斷代碼的執行,否則不會。輸出結果如下圖:
調試快捷鍵
F5:調試的開關(等同於繼續按鈕),按第一次是執行調試,按第二次是結束調試F9:為光標所在行下斷點
F10:逐過程,即逐條執行,遇到函數時會跳過函數的執行過程直。函數包括了方法、屬性、索引器等。但如果為函數體的任何語句下了斷點,F10還是會進入函數的斷點處。
F11:逐語句,即逐條執行,遇到函數時會進入函數體。
調試類(system.diagnostics)
Debug類和Trace類都提供了靜態方法用於調試,區別僅在於Debug只能在調試版本中有效,而Trace類在調試版本或發布版本中都有效。利用這兩個類,你可以將感興趣的變量輸出到指定的窗口,這些窗口稱為偵聽器窗口。當你使用調試時看見的輸出窗口就是一個默認的偵聽器窗口,而所有的偵聽器窗口都從TraceListener派生。
DefaultTraceListener;//調試模式下的Visualt studio輸出窗口
TextWriterTraceListener;
//txt窗口,即一個txt文檔
EventLogTraceListener;
//windows事件日誌窗口,即windows的事件日誌文檔
ConsoleTraceListener;
//控制臺窗口
XmlWriterTraceListener;
//xml窗口,即一個xml文檔
例子
//顯示用戶列表public ActionResult Index()
{
List<UserView> users = new List<UserView>();
foreach (AppUser user in UserManager.Users)
{
users.Add(new UserView { Id = user.Id, Name = user.UserName, Email = user.Email, Password = user.PasswordHash });
}
Debug.Listeners.Add( new TextWriterTraceListener( @"E:\logTest.txt" ) );
Debug.AutoFlush = true;
foreach (var u in users)
{
Debug.WriteLine( $"用戶:{u.Name}" ); //將數據寫入所有的偵聽器窗口
}
Debug.Close( );
return View(users);
}
C# - 學習總目錄
Visual Studio - 調試