12個Visual Studio調試效率技巧

在這篇文章中,我們假定讀者瞭解VS基本的調試知識,如:

  • F5 開始使用調試器運行程序
  • F9 在當前行設置斷點
  • F10 運行到下一個斷點處
  • F5 從被調試的已停止程序恢復執行
  • F11 步進到函數內(如果當前程序指針指向一個函數)
  • F10 步過函數(如果當前程序指針指向一個函數)
  • Shift+F11 步出執行的函數
  • 暫停執行
  • 附加到進程
  • 鼠標懸停時快速查看源代碼中的元素
  • 調試窗口:局部變量、監視、即時窗口、模塊、調用堆棧、異常設置

許多開發人員使用這個功能強大的工具包來處理調試會話。然而,Visual Studio調試工具提供了更多的功能。下面是一系列Visual Studio調試效率技巧。注意,這些提示和快捷方式已經在的Visual studio 2019 16.6 EN-US版本中進行了驗證,驗證時Visual studio沒有安裝擴展。

1、運行到光標位置

使用快捷鍵**Ctrl+F10**,您可以讓調試器運行到光標所在行位置。

運行到光標位置

2、通過點擊鼠標,運行到當前位置

在調試運行的程序時,通過鼠標懸停在當前行的代碼上時,出現綠色的符號,可以點擊此符號,直接讓斷點運行到此處。
通過點擊鼠標,運行到當前位置

3、在此處作爲下一條要執行的語句

在調試運行的程序時,通過鼠標懸停在當前行的代碼上時,通過按住Ctrl鍵轉換爲將此處作爲下一條要執行的語句。它與通過綠色箭頭符號運行到這裏不同,此功能將會跳過中間的語句,直接將斷點跳轉到此處。因此,在下面的動圖中,我們可以在監視窗口中引用obj仍然爲null,中間的MyClass構造函數並沒有被執行。
在此處作爲下一條要執行的語句

4、數據斷點:當值發生變化時,觸發中斷(值更改時中斷)

當你設置一個非靜態的設置器爲斷點時,當所有對象的屬性的值發生更改時觸發斷點。通過局部窗口(監視器窗口)右鍵點擊:值更改時中斷菜單,單個對象也可以獲得相同的行爲。

下面的動畫說明了這個功能,只有當obj2.Prop發生變化時,命中斷點,而obj1.Prop發生變化時沒有命中斷點。

注意:數據斷點綁定到活動對象時,旨在調試期間起作用。因此,一旦調試過程停止,設置的斷點就會丟失,在以後的調試過程中不能重用它。

數據斷點:值更改時中斷

5、條件斷點

可以將條件附加到斷點中,以便盡在特定場景中觸發中斷。在下面的動圖中,我們在循環中定義條件i>6的斷點。然後點擊繼續,可以看到一旦斷點停止,i的值實際上變成了7

6、跟蹤斷點

在遇到斷點時,停止程序執行時最常見的操作。但是,你可以選擇在輸出窗口中不終止(或帶終止)打印一些跟蹤信息。下面的動圖說明了這種可能性。我們在輸出窗口中跟蹤i從0到9的值。注意:跟蹤斷點在編輯器的斷點顯示位置顯示爲菱形形狀。

注意,條件和跟蹤操作都可以在斷點上指定。
跟蹤斷點

7、跟蹤超出作用域的對象

在監視窗口中,通過當前執行範文內引用的名稱來跟蹤對象。但是,當這樣的跟蹤引用超出作用域時,即使在引用對象仍處於活動狀態時,它在監視窗口的上下文也不安的毫無意義並且被禁用。

在許多情況下,我們想繼續跟蹤作用域外對象的狀態。爲此,請在監視窗口中右鍵單擊此類引用,單擊菜單[Make Object ID] 創建對象ID(M),並要在監視器中添加$1(或者$2,$3,…,取決於你已經創建了多個對象ID)。

下面的動圖演示瞭如何跟蹤作用域外對象的屬性獲取器的狀態,該屬性獲取器以字符串的形式返回實際的日期時間。它很好地顯示了當引用objFct()上下文中超出作用域時,要觀看的obj項將被禁用,而$1仍然會獲得更新。
跟蹤超出作用域的對象

8、查看函數返回的值

函數返回的值有時在源代碼中被忽略,或者有時這個值在調試時無法被顯示的訪問。

這樣的返回值可以顯示在調試->窗口->自動窗口中。僞變量$ReturnValue也可以在即時窗口和監視窗口中使用,以方便查看最後一個函數調用的返回值。

注意,菜單調試->窗口->自動窗口僅在Visual Studio調試器附加到進程並且程序被調試器暫停時可用。

查看函數返回的值

9、重新附加到進程

Visual Studio 2017開始,重新附加到進程Shift+Alt+P工具被提出,並且非常方便。將調試器附加到某個進程後,Visual Studio會記住它,並建議將調試器重新附加到同一進程。斜體也一樣,因爲這裏有一個關於進程標識的啓發式方法:

  • 如果已附加的進程仍然運行着,重新附加到進程,重新附加到它。
  • 否則,Visual Studio將嘗試查找和前一個進程名具有相同名稱的單進程,並將調試器重新附加到該進程。
  • 如果找到幾個使用此名稱的進程,則打開“附加到進程”對話框,只顯示名稱相同的進程
  • 如果找不到具有此名稱的進程,則顯示“附加到進程”對話框

重新附加到進程

重新附加到進程也適用於涉及多個進程的調試會話。在這種情況下,Visual Studio會嘗試使用上述相同的啓發式方法來查找它附加到的所有進程。

10、在即時窗口和在觀察窗口的No-Side-Effect評估

有時,在即時窗口或監視窗口中評估表達式時,某些狀態會更改。這種行爲通常時不希望發生的。你不想僅僅因爲需要評估表達式的值而破壞調試程序的狀態。這種情況被稱爲Heisenbug,該術語時物理學家Werner Heisenberg的雙關語,它首先斷言了量子力學的觀察者效應,該現象指出,觀察系統的行爲不可避免的會改變器狀態。

爲了避免更改任何狀態,你可以在表達式後面加上nse(No-Side-Effect)。下面的動圖說明了這種可能性(在監視窗口中監視State的值是否有變化)。

在即時窗口和在觀察窗口的評估

下面這種動圖是nse在監視窗口的使用。由於SideEffectFct()所觀察的項中有Refresh評估按鈕,所以此示例比前一個示例更簡單。

11、在源碼中顯示線程

調試多線程應用程序是有名的複雜。希望在源碼中顯示線程按鈕能提供很大的幫助。它在編輯器的左側邊欄引入標記圖標,以跟蹤其他線程被暫停的位置。這個標記可以用來顯示線程ID,並最終切換到另一個線程。注意:如果至少兩個線程在同一位置暫停,則會顯示不同的標記符號。
在源碼中顯示線程

更多調試多線程應用程序的技巧可以在這個微軟文檔中找到:Get started debugging multithreaded applications (C#, Visual Basic, C++)

https://docs.microsoft.com/en-us/visualstudio/debugger/get-started-debugging-multithreaded-apps?view=vs-2019

下面是這個演示的源代碼,如果你想演示它,可以進行參考:

using System;
using System.Threading;
 
class Program {
   static void Main() {
      for (int i=0; i< 5; i++) {
         // Avoid capturing a loop variable in the lambda below
         int j = i;
         // So 2 thread are blocked on '0' case
         if (j == 1) { j = 0; } 
         ThreadPool.QueueUserWorkItem(delegate { Method(j); });
      }
      Thread.Sleep(60000);
   }
   static void Method(int id) {
      switch(id) {
         case 0:
            Thread.Sleep(60000); break;
         case 1:
            Thread.Sleep(60000); break;
         case 2:
            Thread.Sleep(60000); break;
         case 3:
            Thread.Sleep(60000); break;
         case 4:
            Thread.Sleep(60000); break;
      }
   }
}

12、從反編譯的IL代碼中調試源代碼

我們經常依賴一些黑盒組件:我們沒有源代碼的組件。

但是,在調試複雜行爲時,觀察甚至調試引用的黑盒組件引用的邏輯。這就是爲什麼從16.5版本開始,Visual Studio 2019可以從編譯好的程序中生成一些源代碼。這樣的源代碼是可以調試的。這個特性是基於開源軟件(OSS)工程:ILSpy(https://github.com/icsharpcode/ILSpy)。

反編譯菜單可以在模塊窗口的組件右鍵菜單(如下面的動圖所示)和Source Not FoundNo Symbols Loaded對話框中給出。

IL代碼反編譯爲源代碼不可能是完美的,因爲一些源代碼信息在編譯時丟失了。因此,這個特性有一些限制,在這個官方文檔的最後會解釋:Generate source code from .NET assemblies while debugging

https://docs.microsoft.com/en-us/visualstudio/debugger/decompilation?view=vs-2019

從反編譯的IL代碼中調試源代碼

結尾

Visual Studio非常出色,在調試方面尤其出色。 在這裏,我試圖選擇一些既隱藏又經常有用的技巧,希望它們能幫助您提高生產率。

如果你感覺有用,請關注一下我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章