除錯
你可以使用 Microsoft C# 擴充套件在 Visual Studio Code 中除錯 C# 應用程式。
執行和除錯
C# 擴充套件與 C# Dev Kit 一起,提供了多種方式來執行和除錯你的 C# 應用程式。
要在沒有 C# Dev Kit 的情況下執行和除錯,請參閱 Microsoft C# 擴充套件的 GitHub 頁面上的文件。
使用 F5 除錯
在安裝了 C# Dev Kit 擴充套件且“除錯”檢視中沒有可選擇的除錯配置時,你可以透過開啟一個 .cs
檔案然後按 F5 來開始除錯你的專案。偵錯程式會自動找到你的專案並開始除錯。如果你有多個專案,它會提示你選擇要開始除錯的專案。
你還可以從 VS Code 側邊欄的執行和除錯檢視開始除錯會話。更多資訊請參閱 在 VS Code 中除錯。
使用解決方案資源管理器除錯
安裝了 C# Dev Kit 擴充套件後,當你在解決方案資源管理器中右鍵單擊你的專案時,會出現一個除錯上下文選單。
有三個選項
- 啟動新例項 - 這會啟動你的專案並附加一個偵錯程式。
- 在不除錯的情況下啟動 - 這會執行你的專案但不附加偵錯程式。
- 單步執行到新例項 - 這會啟動你的專案並附加一個偵錯程式,但在程式碼的入口點處停止。
使用命令面板除錯
安裝了 C# Dev Kit 擴充套件後,你還可以透過使用除錯: 選擇並開始除錯命令,從命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 開始除錯。
注意:這會在你的除錯下拉列表中新增一個啟動配置條目。
使用動態(記憶體中)啟動配置進行除錯
安裝了 C# Dev Kit 擴充套件後,你可以建立動態啟動配置。建立它們的方式取決於你的專案是否有一個現有的 launch.json
檔案。
現有的 launch.json
如果你有一個現有的 launch.json
,你可以轉到“除錯”檢視,選擇下拉選單,然後選擇 C#
選項。這應該會給你一個啟動目標的選擇,你可以將它們新增到你的下拉列表中。選擇後,你可以按 F5 或使用新生成的配置點選開始除錯。
沒有 launch.json
如果你的專案中沒有 launch.json
,你可以在“除錯”檢視的顯示所有自動除錯配置中新增和訪問這些動態配置。
移除動態(記憶體中)啟動配置
你可以使用命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 並使用命令除錯: 選擇並開始除錯來移除生成的配置。
在下拉列表中,它會列出你所有現有的除錯配置。如果你將滑鼠懸停在動態配置上,右側會出現一個可點選的垃圾桶圖示。你可以選擇該圖示來移除動態配置。
使用編輯器除錯/執行按鈕進行除錯
當編輯器中開啟一個 .cs
檔案時,可以透過位於編輯器視窗右上角的按鈕來訪問執行和除錯選項。這些操作將使用當前檔案查詢專案系統,並確定要啟動的關聯專案。
兩個選項是
-
執行與此檔案關聯的專案
:這將使用除錯介面卡以noDebug: true
模式啟動你的程式。 -
除錯與此檔案關聯的專案
:這將在偵錯程式下啟動你的程式。
使用 launch.json 除錯
如果你正在使用 C# Dev Kit,我們建議不要使用此選項。但是,如果你需要直接修改除錯配置,請參閱為 C# 除錯配置 launch.json。
附加到程序
你可以使用命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 並執行除錯: 附加到 .NET 5+ 或 .NET Core 程序命令來附加到 C# 程序。
配置選項
有許多選項和設定可用於配置偵錯程式。你可以使用 launchSettings.json
、VS Code 使用者設定來修改你的除錯選項,或者直接修改你的 launch.json
。
launchSettings.json
如果你有來自 Visual Studio 的 launchSettings.json
,你應該會看到你的配置檔案在使用F5 執行或從命令面板執行時列出。
更多詳情請參考配置 C# 除錯。
使用者設定
如果你希望在使用 C# 偵錯程式時更改設定,可以在 檔案 > 首選項 > 設定 (⌘, (Windows, Linux Ctrl+,)) 下找到這些選項,並搜尋它們。
csharp.debug.stopAtEntry
- 如果為 true,偵錯程式應在目標的入口點停止。此選項預設為false
。csharp.debug.console
- 啟動控制檯專案時,指示目標程式應在哪個控制檯中啟動。注意:此選項僅用於 'dotnet' 除錯配置型別。internalConsole
[預設] - VS Code 的除錯控制檯。此模式允許你在一個地方看到來自偵錯程式和目標程式的訊息。更多詳情請參考完整文件。integratedTerminal
- VS Code 的整合終端。externalTerminal
- 可透過使用者設定配置的外部終端。
csharp.debug.sourceFileMap
- 將構建時路徑對映到本地源位置。所有構建時路徑的例項都將被本地源路徑替換。
示例
{\"<構建時路徑>\":\"<本地源路徑>\"}
csharp.debug.justMyCode
- 啟用時(預設),偵錯程式僅顯示和單步進入使用者程式碼(“我的程式碼”),忽略系統程式碼和其他經過最佳化或沒有除錯符號的程式碼。更多資訊。csharp.debug.requireExactSource
- 要求當前原始碼與 pdb 匹配的標誌。此選項預設為true
。csharp.debug.enableStepFiltering
- 啟用跳過屬性和運算子的標誌。此選項預設為true
。csharp.debug.logging.exceptions
- 確定是否應將異常訊息記錄到輸出視窗的標誌。此選項預設為true
。csharp.debug.logging.moduleLoad
- 確定是否應將模組載入事件記錄到輸出視窗的標誌。此選項預設為true
。csharp.debug.logging.programOutput
- 確定在不使用外部控制檯時是否應將程式輸出記錄到輸出視窗的標誌。此選項預設為true
。csharp.debug.logging.diagnosticsLog
- 用於診斷偵錯程式問題的各種設定。csharp.debug.logging.browserStdOut
- 確定是否應將啟動 Web 瀏覽器時的 stdout 文字記錄到輸出視窗的標誌。此選項預設為true
。csharp.debug.logging.elapsedTiming
- 如果為 true,引擎日誌記錄將包括adapterElapsedTime
和engineElapsedTime
屬性,以指示請求所花費的時間(以微秒為單位)。此選項預設為false
。csharp.debug.logging.threadExit
- 控制當目標程序中的執行緒退出時是否記錄訊息。此選項預設為false
。csharp.debug.logging.processExit
- 控制當目標程序退出或除錯停止時是否記錄訊息。此選項預設為true
。csharp.debug.suppressJITOptimizations
- 如果為 true,當最佳化的模組(在 Release 配置中編譯的 .dll)載入到目標程序中時,偵錯程式會要求即時(Just-In-Time)編譯器生成停用最佳化的程式碼。更多資訊csharp.debug.symbolOptions.searchPaths
- 用於搜尋 .pdb 檔案的符號伺服器 URL(例如:http://MyExampleSymbolServer
)或目錄(例如:/build/symbols)的陣列。除了模組旁邊的預設位置和 pdb 最初放置的路徑之外,還會搜尋這些目錄。csharp.debug.symbolOptions.searchMicrosoftSymbolServer
- 如果為true
,Microsoft 符號伺服器 (https://msdl.microsoft.com/download/symbols
) 將被新增到符號搜尋路徑中。如果未指定,此選項預設為false
。csharp.debug.symbolOptions.searchNuGetOrgSymbolServer
- 如果為true
,NuGet.org 符號伺服器 (https://symbols.nuget.org/download/symbols
) 將被新增到符號搜尋路徑中。如果未指定,此選項預設為false
。csharp.debug.symbolOptions.cachePath
- 從符號伺服器下載的符號應快取的目錄。如果未指定,在 Windows 上,偵錯程式預設為%TEMP%\\SymbolCache
,在 Linux 和 macOS 上,偵錯程式預設為~/.dotnet/symbolcache
。csharp.debug.symbolOptions.moduleFilter.mode
- 控制模組篩選器執行的兩種基本操作模式之一。loadAllButExcluded
- 載入所有模組的符號,除非該模組在excludedModules
陣列中。loadOnlyIncluded
- 不嘗試載入任何模組的符號,除非它在includedModules
陣列中,或者透過includeSymbolsNextToModules
設定包含它。
csharp.debug.symbolOptions.moduleFilter.excludedModules
- 偵錯程式不應載入符號的模組陣列。支援萬用字元(例如:MyCompany.*.dll)。除非mode
設定為loadAllButExcluded
,否則此屬性將被忽略。csharp.debug.symbolOptions.moduleFilter.includedModules
- 偵錯程式應載入符號的模組陣列。支援萬用字元(例如:MyCompany.*.dll)。除非mode
設定為loadOnlyIncluded
,否則此屬性將被忽略。csharp.debug.symbolOptions.moduleFilter.includeSymbolsNextToModules
- 如果為 true,對於不在includedModules
陣列中的任何模組,偵錯程式仍會檢查模組本身和啟動可執行檔案旁邊,但不會檢查符號搜尋列表中的路徑。此選項預設為true
。除非mode
設定為loadOnlyIncluded
,否則此屬性將被忽略。csharp.debug.allowFastEvaluate
- 當為 true 時(預設狀態),偵錯程式將透過模擬執行簡單屬性和方法來嘗試更快的求值。csharp.experimental.debug.hotReload
- 當為 true 時,如果目標應用程式支援熱過載,偵錯程式將啟用在除錯時應用更改。csharp.debug.hotReloadOnSave
- 當為 true 時(預設狀態),偵錯程式將在檔案儲存時自動應用程式碼更改。csharp.debug.hotReloadVerbosity
- 控制 C# 熱過載輸出視窗的日誌記錄詳細程度。它可以設定為minimal
(預設)、detailed
或diagnostic
。如果熱過載開始出現意外行為,建議提高詳細程度級別。
Breakpoints
C# 偵錯程式支援各種斷點,例如原始碼行斷點、條件斷點和日誌點。
斷點 - 條件斷點
藉助表示式求值,偵錯程式還支援條件斷點。你可以設定斷點在表示式求值為 true 時中斷。
斷點 - 函式斷點
偵錯程式還支援函式斷點。你可以透過在“除錯”窗格的“斷點”部分單擊 +
來設定斷點以在特定函式上中斷。
斷點 - 日誌點
日誌點(在 Visual Studio 中也稱為跟蹤點)允許你向除錯控制檯傳送輸出而無需編輯程式碼。它們與斷點不同,因為它們不會停止應用程式的執行流。
要新增日誌點,請在程式碼行旁邊的最左側邊距中右鍵單擊。選擇新增日誌點並鍵入你想要記錄的訊息。當命中日誌點時,將對花括號('{' 和 '}')之間的任何表示式進行求值。
日誌訊息中還支援以下令牌
標記 | 描述 | 輸出示例 |
---|---|---|
$FILEPOS | 當前原始檔位置 | C:\sources\repos\Project\Program.cs:4 |
$FUNCTION | 當前函式名 | Program.<Main>$ |
$ADDRESS | 當前指令 | 0x00007FFF83A54001 |
$TID | 執行緒 ID | 20668 |
$PID | 程序 ID | 10028 |
$TNAME | 執行緒名稱 | <無執行緒名稱> |
$PNAME | 程序名稱 | C:\sources\repos\Project\bin\Debug\net7.0\console.exe |
$CALLER | 呼叫函式名稱 | void console.dll!Program.Foo() |
$CALLSTACK | 呼叫堆疊 | void console.dll!Program.Bar() void console.dll!Program.Foo() void console.dll!Program.<Main>$(string[] args) [外部程式碼] |
$TICK | 時鐘週期計數(來自 Windows GetTickCount) | 28194046 |
$HITCOUNT | 此斷點被命中的次數 | 5 |
斷點 - 觸發斷點
觸發斷點是一種在另一個斷點命中後自動啟用的斷點。當代碼中出現僅在特定先決條件發生後才出現的故障情況時,它們非常有用。
可以透過右鍵單擊字形邊距,選擇 新增觸發斷點,然後選擇哪個其他斷點啟用此斷點來設定觸發斷點。
在異常處停止
C# 偵錯程式支援配置選項,用於在丟擲或捕獲異常時偵錯程式停止。這是透過執行檢視的斷點部分中的兩個不同條目完成的
請注意,斷點部分將缺少這些條目,直到該資料夾首次使用 C# 偵錯程式進行除錯。
選中所有異常將配置偵錯程式在丟擲異常時停止。如果啟用了僅我的程式碼(預設啟用),則如果異常在庫程式碼中內部丟擲並捕獲,偵錯程式將不會中斷。但是,如果異常在庫程式碼中丟擲並返回到使用者程式碼,偵錯程式將中斷。
選中使用者未處理的異常將配置偵錯程式在使用者程式碼中丟擲或經過使用者程式碼後,異常在非使用者程式碼中被捕獲時停止。成為使用者未處理的異常並不總是被除錯程序中的錯誤——可能是使用者程式碼正在實現一個 API,並且預期會引發異常。在許多情況下,確實存在問題,因此,預設情況下,當異常成為使用者未處理時,偵錯程式會停止。
異常條件
兩個複選框都支援條件,以便僅在選定的異常型別上中斷。要編輯條件,請選擇鉛筆圖示(見上圖)或右鍵單擊條目並呼叫編輯條件。該條件是一個逗號分隔的異常型別列表,用於中斷,或者如果列表以 '!' 開頭,則是一個要忽略的異常型別列表。
條件示例
條件值示例 | 結果 |
---|---|
System.NullReferenceException | 這隻會對空引用異常中斷。 |
System.NullReferenceException, System.InvalidOperationException | 這會對空引用異常和無效操作異常都中斷。 |
!System.Threading.Tasks.TaskCanceledException | 這會對除任務取消之外的所有異常都中斷。 |
!System.Threading.Tasks.TaskCanceledException, System.NotImplementedException | 這會對除任務取消和未實現之外的所有異常都中斷。 |
Expression evaluation
偵錯程式還允許你在監視視窗以及除錯控制檯中求值表示式。
熱過載
安裝了 C# Dev Kit 擴充套件後,偵錯程式允許你在除錯時應用 C# 程式碼更改。
為了啟用熱過載,必須將 csharp.experimental.debug.hotReload
設定為 true,更多資訊請參閱使用者設定。熱過載會話僅在目標偵錯程式引擎支援應用程式碼更改時才會啟動。
支援的專案和場景
C# Dev Kit 支援“經典”熱過載體驗,也稱為“編輯並繼續”。無論你是在斷點處停止還是程式正在執行,都可以在除錯時應用程式碼更改。
截至 2023 年 11 月,某些功能(例如 MetadataUpdateHandler
,它使 ASP.NET Core 應用程式能夠在做出更改後自動重新整理瀏覽器)尚不可用。還不支援在不除錯的情況下應用程式碼更改。
執行時在 .NET 8 中添加了對在 Linux/macOS 上除錯時應用更改的支援,因此在為在這些作業系統上執行的 .NET 應用應用程式碼更改時,需要 .NET 8+ 的執行時版本。
應用程式型別 | 支援使用 C# Dev Kit 進行熱過載 | 需要 .NET 8+ |
---|---|---|
控制檯 | ✅ | 僅限 Linux/macOS |
測試專案 | ✅ | 僅限 Linux/macOS |
類庫專案 | ✅ | 僅限 Linux/macOS |
ASP.NET Core | ⚠️* 目前僅支援對 .cs 檔案的更改 |
僅限 Linux/macOS |
MAUI | ❌* 即將推出 | -- |
Unity | ❌ | -- |
有關 C# Dev Kit 當前支援的專案的更多資訊,請參閱支援的專案。另請參閱 C# Dev Kit 常見問題解答,瞭解有關排查其他不支援場景的更多資訊。
如何應用程式碼更改
一旦熱過載會話開始並做出新的更改,你可以透過以下任何操作將這些更改應用到你的應用程式中
操作 | 說明 |
---|---|
熱過載 Ctrl+Shift+Enter |
應用程式碼更改,可從除錯工具欄獲得。 |
儲存檔案 ⌘S (Windows, Linux Ctrl+S) |
如果 csharp.debug.hotReloadOnSave 設定為 true,則開始應用程式碼更改。更多資訊請參閱使用者設定。 |
繼續 / 單步跳過 / 單步進入 / 單步跳出 F5 / F10 / F11 / ⇧F11 (Windows, Linux Shift+F11) |
當在中斷狀態下(例如,在斷點處停止時)進行更改時,這些命令將自動應用它們。 |
後續步驟
繼續閱讀以瞭解:
- 除錯 - 瞭解如何在 VS Code 中為任何語言的專案使用偵錯程式。