Visual Studio 調試系列3 斷點

斷點是開發人員的工具箱中最重要的調試技術之一。 若要暫停調試程序執行所需的位置設置斷點。 例如,你可能想要查看代碼變量的狀態或查看調用堆棧的某些斷點。html

01 在源代碼中設置斷點

能夠在任意可執行代碼行上設置斷點。 例如,在如下 C# 代碼,能夠設置斷點在變量聲明for循環中或內的任何代碼for循環。 命名空間或類聲明或方法簽名,沒法設置斷點。express

若要在源代碼中設置斷點,請單擊代碼行旁邊的最左側邊距中。 您還能夠選擇行,而後按F9,選擇調試 > 切換斷點,或右鍵單擊並選擇斷點 > 插入斷點。 斷點顯示爲左邊距中的一個紅點。編程

調試時,執行的斷點處暫停,在執行該行上的代碼以前。 斷點符號顯示黃色箭頭。windows

當調試器在斷點處中止時,您能夠查看應用程序,包括變量值和調用堆棧的當前狀態。 有關調用堆棧的詳細信息,請參閱如何:使用調用堆棧窗口安全

  • 斷點是一個觸發器。 您能夠單擊它,請按F9,或使用調試 > 切換斷點刪除或從新插入。編程語言

  • 若要禁用斷點而不刪除它,將鼠標懸停或右鍵單擊它,而後選擇禁用斷點。 已禁用的斷點顯示爲左邊距中的空點或斷點窗口。 若要從新啓用斷點,請將鼠標懸停或右鍵單擊它,而後選擇啓用斷點。編輯器

  • 設置條件和操做、 添加和編輯標籤,或將斷點導出,右鍵單擊該和選擇合適的命令,或將鼠標懸停其上,而後選擇設置圖標。函數

02 調用堆棧窗口中設置斷點

若要中斷的指令或調用函數返回到的行處,能夠設置斷點調用堆棧窗口。工具

在調用堆棧窗口中設置斷點:visual-studio

  1. 若要打開調用堆棧窗口中,您必須在調試期間暫停。 選擇調試 > Windows > 調用堆棧,或按Ctrl + Alt+C。

  2. 在中調用堆棧窗口中,右鍵單擊調用函數,而後選擇斷點 > 插入斷點,或按F9.

    調用堆棧的左邊距中的函數調用名稱旁邊會顯示一個斷點符號。

調用堆棧斷點顯示在斷點窗口具備對應於在函數中的下一步可執行指令的內存位置的地址。

調試器在指令處中斷。

03 在反彙編窗口中設置斷點
  1. 若要打開反彙編窗口中,您必須在調試期間暫停。 選擇調試 > Windows > 反彙編,或按Alt + 8。

  2. 在中反彙編窗口中,單擊想要中斷的指令的左邊距中。 此外能夠選擇它,而後按F9,或右鍵單擊並選擇斷點 > 插入斷點。

04 設置函數斷點

當調用函數,能夠中斷執行。

若要設置函數斷點:

  1. 選擇調試 > 新斷點 > 函數斷點,或按Alt +F9 > Ctrl+B。

    您還能夠選擇新建 > 函數斷點中斷點窗口。

  2. 在中新函數斷點對話框中,輸入中的函數名稱函數名稱框。

    若要縮小範圍的函數規範:

    • 使用徹底限定的函數名稱。

      示例:Namespace1.ClassX.MethodA()

    • 添加劇載函數的參數類型。

      示例:MethodA(int, string)

    • 使用 ! 符號指定模塊。

      示例:App1.dll!MethodA

    • 在本機中使用上下文運算符C++。

      {function, , [module]} [+<line offset from start of method>]

      示例:{MethodA, , App1.dll}+2

  3. 在中語言下拉列表中,選擇該函數的語言。

  4. 選擇 肯定。查看編輯器,全部 Draw() 方法處都以自動插入了斷點。

05 設置數據斷點 (.NET Core 3.0 或更高版本)

爲特定對象的屬性發生更改時,數據斷點中斷執行。

若要設置數據斷點

  1. 在.NET Core 項目中,開始調試,並等待,直到到達一個斷點。

  2. 在自動,監視,或局部變量窗口中,右鍵單擊一個屬性,而後選擇值更改時中斷的上下文菜單中。

    管理數據斷點

在.NET Core 中的數據斷點不適用於:

  • 不是可擴展的工具提示中,局部變量,自動或監視窗口屬性
  • 靜態變量
  • 使用 DebuggerTypeProxy 特性類
  • 在結構內的字段

 

06 在「斷點」窗口中管理斷點

可使用斷點窗口來查看和管理你的解決方案中的全部斷點。 此集中的位置是在大型解決方案中,或對於複雜斷點很是關鍵的調試方案尤爲有用。

在斷點窗口中,您能夠搜索、 排序、 篩選、 啓用/禁用或刪除斷點。 您還能夠設置條件和操做,或添加新的函數或數據斷點。

若要打開斷點窗口中,選擇調試 > Windows > 斷點,或按Alt+F9或Ctrl+Alt+B。

 若要選擇要在列表中顯示的列斷點窗口中,選擇顯示列。 選擇一個列標題以對斷點列表,可按該列進行排序。

斷點標籤

可使用標籤進行排序和篩選列表中的斷點斷點窗口。

一、若要將標籤添加到斷點中,右鍵單擊該斷點的源代碼中或斷點窗口中,並選擇編輯標籤。 添加新標籤或選擇一個現有證書,而後選擇肯定。

二、對在斷點列表進行排序斷點經過選擇窗口標籤,條件,或其餘列標題。 能夠選擇要經過選擇顯示的列顯示列工具欄中。

07 斷點條件

能夠經過設置條件來控制在什麼時候何處執行斷點。 條件能夠是調試器可以識別任何有效表達式。 有關有效表達式的詳細信息,請參見調試器中的表達式

若要設置斷點條件:

  1. 右鍵單擊斷點符號,而後選擇條件。 或懸停在斷點符號,選擇設置圖標,並選擇條件中斷點設置窗口。

    您還能夠在設置條件斷點窗口中的右鍵單擊斷點並選擇設置,而後選擇條件。

  1. 在下拉列表中,選擇條件表達式,命中計數,或篩選器,並相應地設置值。

  2. 選擇關閉或按Ctrl+Enter關閉斷點設置窗口。 或者,從斷點窗口中,選擇肯定關閉對話框。

 

條件表達式

當選擇條件表達式,能夠選擇兩個條件:爲 true或發生更改時。 選擇如此時,知足表達式時中斷或發生更改時表達式的值已更改時中斷。

一、示例1,設置條件表達式爲 true, index == 1

按下F5,啓動調試,因爲第一次 index 等於0,因此37行斷點沒有命中,直接走到43行的正常斷點處。

第一次循環結束後,index的值增長了1,等於1。進入到第二次循環時,按下F5,因爲 index = 1,知足設置的表達式,因此命中了37行的斷點。

第二次循環結束後,index的值增長了1,等於2。進入到第三次循環時,按下F5,因爲 index = 2,不知足設置的表達式,因此沒有命中37行的斷點,直接走到43行的正常斷點處。

二、示例2:設置條件表達式爲 更改時, index 

按下F5,啓動調試,因爲第一次 index 等於0,第一次進入循環,結束前 index的值未改變仍然爲0,沒有改變,因此37行斷點沒有命中,直接走到43行的正常斷點處。

第一次循環結束後,index的值增長了1,等於1。進入到第二次循環時,按下F5,因爲 index = 1,值更改了,知足設置的條件,因此命中了37行的斷點。

第二次循環結束後,index的值增長了1,等於2。進入到第三次循環時,按下F5,因爲 index = 2,值更改了,知足設置的條件,因此命中了37行的斷點。

 若是使用無效語法設置斷點條件,則會顯示警告消息。 若是在指定斷點條件時使用的語法有效但語義無效,則在第一次命中斷點將出現警告消息。 在任一狀況下,調試器將中斷時它會命中斷點無效。 僅在條件有效且計算結果爲 false時纔會跳過斷點。

不一樣編程語言的「更改時」字段的行爲不一樣 :

對於本機代碼,調試器不會考慮更改,所以不會命中第一次計算斷點條件的第一次計算。

對於託管代碼,調試器命中斷點後第一次計算髮生更改時處於選中狀態。

在條件表達式中使用對象 Id (C#和F#僅)

有些的時候,當你想要觀察特定對象的行爲。 例如,你可能想要找出爲何對象插入到集合一次以上。 在 C# 和 F# 中,能夠建立引用類型的特定實例的對象 ID,並在斷點條件下使用它們。 對象 ID 由公共語言運行時 (CLR) 調試服務生成並與該對象關聯。

建立對象 ID

一、設置斷點在代碼中的某個位置後建立對象。

二、開始調試,並在斷點處暫停執行,選擇調試 > Windows > 局部變量Alt+ 4以打開局部變量窗口。

      查找特定對象實例在局部變量窗口中,右鍵單擊它,而後選擇建立對象 ID

      應該會在「局部變量」 $ 窗口中看到, 窗口中設置斷點來中斷調用函數返回到的指令或行處的執行。 這就是對象 ID。

展開名稱,看到 $1 與 tri 對象徹底相同

以一樣的方式給 rec、cir、shapes 對象分別建立對象ID,分別對應 $2  $3  $4 

三、在該對象添加到集合處, 右鍵單擊該斷點並選擇「條件」 。

四、在「條件表達式」字段中使用對象 ID 。 例如,若是變量item是要添加到集合中,選擇的對象爲 true並鍵入item == $<n > ,其中<n > 的對象 ID 號.

     會在將該對象添加到集合中時中斷執行。

tri 對象添加到集合處,設置條件爲 tri == $1

rec 對象添加到集合處,設置條件爲 rec == $2

 cir 對象添加到集合處,設置條件爲 rec == $3

按下F5繼續運行,

代碼走到61行時,斷點變成黃色箭頭,鼠標懸浮在黃色箭頭上,提示以下,條件表達式計算結果爲 true。因此命中61行的斷點。

按下F5繼續運行,

代碼走到62行時,斷點變成黃色箭頭,鼠標懸浮在黃色箭頭上,提示以下,條件表達式計算結果爲 true。因此命中62行的斷點。

按下F5繼續運行,

代碼走到63行時,斷點變成黃色箭頭,鼠標懸浮在黃色箭頭上,提示以下,條件表達式計算結果爲 true。因此命中63行的斷點。

 

 

若是將61行的條件設置爲 tri == $2。根據上述的生成的對象ID,該表達式返回false。

再次F5,運行到61行時,提示報錯。由於 tri 是 Triangle 類的對象,$2 是 Rectangle 類的對象建立的ID,因此沒法進行 == 運算符的比較。調試器報錯。

可是按下F5,仍然能夠繼續運行。

 

若是把61行的條件表達式修改成 tri.Equals($2),再次調試時,因爲該表達式返回false,因此沒有命中61行的斷點。直接跳到62行。

 

     若要刪除對象 ID,請右鍵單擊中的變量局部變量窗口,而後選擇刪除對象 ID。

對象 ID 建立弱引用,且不會阻止對象被垃圾回收。 它們僅對當前調試會話有效。

命中次數

若是你懷疑你的代碼中的循環開始產生錯誤行爲在必定數量的迭代後,能夠設置一個斷點以中止執行的命中數,而無需重複按該數後F5來訪問該迭代。

下列條件中斷點設置窗口中,選擇命中計數,而後指定迭代數。 在如下示例中,斷點設置爲其餘每次迭代命中:

 F5調試,第一次 i = 0,不是 testInt 的2倍整數,因此沒有命中74行的斷點,直接跳到76行。

當 testInt的值爲 二、四、1六、2二、46時,都能命中74行的斷點。

 

篩選器

能夠將斷點限制爲僅在指定設備上或在指定進程和線程中觸發。

下條件中斷點設置窗口中,選擇篩選器,而後輸入一個或多個如下表達式:

  • MachineName = "name"
  • ProcessId = value
  • ProcessName = "name"
  • ThreadId = value
  • ThreadName = "name"

將字符串值放在雙引號內。 可使用 & (AND)、 || (OR)、 ! (NOT) 和括號合併子句。

提醒:斷點條件 模式下進行調試,不能按F10,只能按F5進行調試才能看到實際效果。

08 斷點操做和跟蹤點

「跟蹤點」是將消息打印到「輸出」窗口的斷點 。 跟蹤點的做用像這種編程語言中的一個臨時跟蹤語句。

若要設置跟蹤點:

  1. 右鍵單擊斷點並選擇操做。 或者,在斷點設置窗口中,懸停在所需斷點,選擇設置圖標,,而後選擇操做。

  2. 輸入中的消息將消息記錄到輸出窗口字段。 消息能夠包含通用文本字符串,值的變量或表達式括在大括號和格式說明符 ( C#  C++ ) 的值。

    此外能夠在消息中使用如下特殊關鍵字:

    • $ADDRESS -當前指令
    • $CALLER -調用函數名
    • $CALLSTACK -調用堆棧
    • $FUNCTION -當前函數名
    • $PID -進程 id
    • $PNAME -進程名稱
    • $TID -線程 id
    • $TNAME -線程名稱
    • $TICK -選中計數 (從 Windows GetTickCount)
  3. 若要打印到的消息輸出但不會中斷,選擇窗口繼續執行復選框。 若要打印在跟蹤點的消息和中斷執行,請清除該複選框。

跟蹤點顯示爲紅色方塊中的源代碼的左邊距和斷點windows。

按下F5,運行結束後,查看【輸出】窗口

09 斷點警告

斷點在調試時,有兩個可能的可視狀態: 一個實心的紅色圓和 (白色填充) 空心圓。 若是調試器可以成功在目標進程中設置斷點,它將保持一個實心的紅色圓。 若是斷點是空心圓,禁用斷點,或嘗試設置斷點時出現警告。 若要肯定的不一樣,斷點上懸停並查看是否存在一條警告。

如下兩個部分介紹重要警告以及如何解決這些問題。

「還沒有爲此文檔加載任何符號」

轉到模塊窗口 (調試 > Windows > 模塊) 並檢查是否爲你的模塊加載。

 

  • 若是加載你的模塊,則檢查符號狀態列,以查看是否已加載符號。

    • 若是還未加載符號,檢查符號狀態來診斷問題。 從上下文菜單中的模塊上模塊窗口中,單擊符號加載信息... 若要查看其中調試器嘗試並加載符號。 有關加載符號的詳細信息,請參閱指定符號 (.pdb) 和源文件
    • 若是已加載符號,PDB 不包含有關源文件的信息。 如下是幾個可能的緣由:
      • 若是最近添加的源文件,確認正在加載的模塊的最新版本。
      • 能夠建立使用去除的 Pdb /PDBSTRIPPED連接器選項。 去除的 Pdb 不包含源文件信息。 確認你正在使用完整 PDB 和不去除的 PDB。
      • PDB 文件部分已損壞。 刪除文件,並執行乾淨的生成的模塊來嘗試解決此問題。
  • 若是你的模塊未加載,請檢查如下內容來查找緣由:

    • 確認您正在調試的正確過程。
    • 請檢查你正在調試的代碼正確的類型。 您能夠了解哪一種代碼將調試器配置爲在調試進程窗口 (調試 > Windows > 進程)。 若是想要調試 C# 代碼,例如,確認是否爲適當類型的.NET Framework 配置您的調試器 (例如,託管 (v4*) 與託管 (v2*/v3*) 與託管 (CoreCLR))。

 

"… 當前源代碼是從...中內置的版本不一樣"

若是源文件已更改,而且源與正在調試的代碼再也不匹配,調試器不會設置斷點在代碼中默認狀況下。 一般狀況下,此問題發生時更改源文件,但不從新生成的源代碼。 若要解決此問題,從新生成項目。 若是生成系統認爲該項目已是最新但沒有,能夠強制項目系統在從新生成經過再次保存源文件或經過清除項目的生成輸出生成前。

在極少數狀況下,你可能想要調試而無需匹配的源代碼。 調試沒有匹配的源代碼能夠使人混淆的潛在顧客調試體驗,所以請確保這是你想要繼續操做。

若要禁用這些安全檢查,請執行如下操做:

  • 若要修改單個斷點,請將鼠標懸停在編輯器中的斷點圖標,而後單擊設置 (齒輪) 圖標。 查看窗口添加到在編輯器中。 在查看窗口頂部,沒有指示的斷點的位置的超連接。 單擊超連接,以容許修改的斷點位置,而後檢查容許源代碼與原始不一樣。
  • 若要修改此設置對全部斷點,請轉到調試 > 選項和設置。 在 「調試」/「常規」 頁上,清除 「要求源文件與原始版本徹底匹配」 選項。 請務必從新啓用此選項,在完成時調試。

 

10 斷點已成功設置 (無警告),但未命中

本部分提供信息以對問題進行故障排除時調試器未顯示任何警告 – 斷點是一個實心的紅色圓時主動進行調試,但未命中斷點。

下面是要檢查的幾個事項:

  1. 若是在多個進程或多臺計算機運行你的代碼,請確保你正在調試的正確的進程或計算機。
  2. 確認你的代碼正在運行。 若要測試你的代碼運行,將調用添加到System.Diagnostics.Debugger.Break(C#/VB) 或__debugbreak(C++) 到在您嘗試設置了斷點,而後從新生成你的項目的代碼行。
  3. 若是你正在調試優化的代碼,請確保在其中設置斷點的函數不被內聯到另外一個函數。Debugger.Break如何工做的上一個檢查中所述的測試,測試以及此問題。

 

11 刪除了斷點,但在再次啓動調試時繼續命中該斷點
若是在調試時刪除了斷點,可能在下一步啓動調試的時再次命中該斷點。 要中止命中此斷點,請確保從 「斷點」 窗口刪除該斷點的全部實例。
相關文章
相關標籤/搜索