摘要:Visual Studio的偵錯技巧
[原文發表位置]:Debugging Tips with Visual Studio 2010
[原文發表時間]:2010/8/19 10:48 AM
這是我寫的關於VS2010和.Net4發佈的部落格系列的第26篇。
今天的文章包含了一些有用的能用於VS的偵錯技巧。 我的朋友Scott Cate(他寫了很多很好的關於VS使用技巧和竅門的部落格)最近向我強調了這些很好的技巧,大部分使用VS的開發人員好像不知道這些技巧(即使他們大部分都在產品開發組呆過一陣子)。 如果你還沒有使用過這些技巧,希望這篇文章能幫你發現它們。 它們學起來很容易,能幫你節省很多時間。
執行到游標(Ctrl+ F10)
我經常看見人們是這樣來偵錯應用程式的: 他們在應用程式需要偵錯的程式碼前設定一個中斷點,然後反覆的敲F10/F11來逐步通過程式碼,直到到達他們真正想要研究的確切位置。有些時候他們需要仔細觀察所跨過的每行程式碼,這樣使用F10/F11 就很合理。 但是更普遍的是,他們只想快點進入他們真正關心的那行程式碼——這是使用F10/F11 就不是最好的選擇了。
相反, 你可能想利用偵錯器支持的特性「執行到游標」。 只需簡單地把你的游標放在程式碼中你想程式執行到的那一行,然後同時敲Ctrl+F10。這樣程式就會執行到游標所在的那一行, 然後執行中止,由偵錯器控制——這樣就節約了你反覆敲擊F10/F11到達那裡的時間。即使你想執行到的那行程式碼不在當前偵錯的方法或類裡,而是在一個獨立的方法或類裡,這也同樣奏效。
條件中斷點
我們經常在可用性學習中見到另一個普遍的技巧:開發人員設定中斷點,執行程式,試著輸入一些資料,當到達一個中斷點時,手工檢查某種條件是不是成立,如果成立才決定進一步研究。 如果條件不符合他們想要的, 按F5繼續執行程式,嘗試另外一些輸入,再手工重複同樣的過程。
VS的條件中斷點功能提供了一個更加容易的方法來處理以上情況。 條件中斷點允許你只在某種明確指定的條件成立時才中止執行,由偵錯器控制。這幫你免於手動檢查/恢復你的程式, 使得整個偵錯過程免去許多手工,也不那麼冗長乏味。
設定一個條件中斷點
設定一個條件中斷點十分簡單,在程式碼裡按F9為某一行設定一個中斷點:
然後右擊中斷點——編輯器左邊的紅色圓圈,在右鍵選單中,選擇「條件…」 :
將彈出以下對話框, 允許你指明某種條件,只有當這種條件成立時,中斷點才能達到。 例如:我們可以通過寫下面的運算式來指明,只有當paginatedDinners列表元素的個數小於10時,才中止程式,由偵錯器控制。
現在, 當我重新執行程式來研究一下, 偵錯器只在這個搜尋傳回值小於10時,才中止程式執行。 如果傳回值不小於10 ,將不會觸發中斷點。
命中次數功能
有時你只想在條件第N次成立時中止執行。例如:僅當第5次出現搜尋傳回值小於10時,才中止執行。你這樣啟用這個功能:右擊中斷點, 選擇「命中次數…」選單命令。
將彈出以下對話框, 允許你指明程式中斷的條件:條件被第N次滿足時,或者條件被滿足的次數是N的倍數時,或者條件被滿足的次數大於等於N次時。
機器/執行緒/行程篩選器
你可以右擊中斷點,選擇「篩選器…」選單命令, 來指明中斷點只在某台特定的機器,或某個特定的行程或執行緒中才能被觸發。
跟蹤點——當擊中中斷點時自訂行為
很多人不知道的一個偵錯功能是使用跟蹤點。 跟蹤點是一個中斷點, 當它被擊中時,某種自訂的宏會被觸發執行。當你想研究你的應用程式而又不想中止執行程式時, 這個功能特別有用。
我將用一個簡單的控制台程式來Demo如何使用跟蹤點。 下面是斐波那契數列的遞歸實現:
在上面的應用程式中,針對特定的輸入,我們使用Console.WriteLine()來輸出最後的斐波那契數列。假如我們想在偵錯過程中研究斐波那契的遞歸過程——而不停止偵錯的執行? 跟蹤點能幫我們很輕鬆地做到這一點。
設定跟蹤點
你可以這樣啟用跟蹤點:按F9在程式碼上設定一個中斷點, 右擊中斷點,在右鍵選單中選擇「命中條件…」選單命令:
將彈出以下對話框——允許你指定當中斷點觸發時,進行何種操作:
如上所示,我們指定每次當中斷點的條件成立時,列印跟蹤信息。注意我們指定了想要輸出的局部變數「X」 的值作為輸出信息的一部分。 局部變數能通過{變數名}的語法被引用。 也有內嵌的命令(像$CALLER,$CALLSTACK, $FUNCTION等等)可以用來輸出跟蹤信息中常見的值。
上面對話框的底部, 我們也選中了「繼續執行」單選框——表示我們不希望偵錯器暫停程式。 相反,程式會繼續執行——只是我們自訂的跟蹤信息會在每次中斷點條件滿足時輸出,就這點不同。
現在當我們執行程式時,我們會發現自訂的跟蹤信息會自動出現在VS的輸出視窗中——使我們能看到程式的遞歸過程。
你也可以選擇為你的程式設定一個自訂跟蹤監聽器——這樣跟蹤點的輸出信息就會被重定向到它裡面,而不是VS的輸出視窗裡。
跟蹤點——執行自訂的宏
上周我在倫敦做了一次演講, 聽眾中有個人問了這樣一個問題:有沒有可能當擊中一個跟蹤點時,自動輸出所有的局部變數。
這個功能不是內建在VS中的, 但是可以通過在VS中寫一個自訂的宏來啟用它,然後設定一個跟蹤點,當它被擊中時,叫用這個宏。 為了實現這個目的, 打開VS中的宏視窗(工具->宏->宏選單命令)。然後在專案管理器「MyMacros」結點下面, 選擇模板或者新建一個模板(如:添加一個名為「UsefulThings」的 模板), 再將下面的VB宏程式碼貼到模板裡,並保存它:
Sub DumpLocals()
Dim outputWindow As EnvDTE.OutputWindow
outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object
Dim currentStackFrame As EnvDTE.StackFrame
currentStackFrame = DTE.Debugger.CurrentStackFrame
outputWindow.ActivePane.OutputString("*Dumping Local Variables*" + vbCrLf)
For Each exp As EnvDTE.Expression In currentStackFrame.Locals
outputWindow.ActivePane.OutputString(exp.Name + " = " + exp.Value.ToString() + vbCrLf)
Next
End Sub
上面的宏程式碼依次檢測當前堆疊,獲取所有的局部變數,並將其顯示在輸出視窗。
使用DumpLocals自訂宏
在下面這個簡單的應用程式中,我們可以利用自訂的「DumpLocals」宏:
在上面的Add方法的return語句上,按F9設定一個中斷點。 右擊中斷點,選擇「命中條件…」選單命令:
將彈出以下對話框,上例中,我們選中了「列印信息」的單選框,再手工指定希望輸出的變數, 而這裡, 我們選中「執行宏」的單選框,使它指向我們建立的自訂宏UsefulThings.DumpLocals:
我們仍然選中「繼續執行」單選框,這樣能保證當跟蹤點被擊中時,程式依然能夠繼續執行。
執行程式
現在當我們按F5執行程式,當叫用Add方法時,我們將看見以下輸出出現在VS輸出視窗中。 注意當跟蹤點被擊中時,宏是如何自動列出各個變數名及其值的。
總結
VS偵錯器功能非常豐富。 我強烈建議大家抽出一些時間來學習它的所有功能。 以上的技巧和訣竅只是很多大家沒有真正意識到的功能中的一小部分。
我之前寫過其他一些關於VS2010偵錯器改進的部落格(包括資料標籤固定,中斷點導入導出,保留最後值變數, 等等)。 我將發表更多關於VS2010的智慧跟蹤和轉儲文件偵錯支持的文章。這些技術提供了很多非常酷的新功能,會讓程式(包括產品中的程式)的偵錯變得非常簡單和強大。
也請務必看看Scott Cate很棒的VS2010技巧和訣竅系列,你可以學習如何更好的利用VS。他有一些非常棒的免費影片和部落格。
也要看看Jim Griesmer很棒的VS偵錯技巧和訣竅系列。 他有許多很好的可以利用的技巧和訣竅。
希望這能對您有所幫助。
附:[除了寫部落格以外,我現在也使用推特(Twitter)來及時更新狀態和分享連結,您可以到這個位址「推」我一下:twitter.com/scottgu]