调试
您可以使用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
文件时,可以通过编辑器窗口右上角的按钮访问运行和调试选项。这些操作将使用当前文件查询项目系统,并确定要启动的相关项目。
这两个选项是:
-
Run project associated with this file
: 这将使用调试适配器启动您的程序,并设置noDebug: true
。 -
Debug project associated with this file
: 这将在调试器下启动您的程序。
使用 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文件)时,调试器会要求即时编译器生成禁用优化的代码。更多信息csharp.debug.symbolOptions.searchPaths
- 符号服务器URL数组(例如:http://MyExampleSymbolServer
)或目录(例如:/build/symbols),用于搜索.pdb文件。除了模块旁边的默认位置和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
。如果热重载开始表现异常,建议增加详细程度级别。
断点
C# 调试器支持各种断点,例如源代码行断点、条件断点和日志点。
断点 - 条件断点
借助表达式评估,调试器还支持条件断点。您可以将断点设置为在表达式评估为真时中断。
断点 - 函数断点
调试器还支持功能断点。您可以通过点击调试窗格中断点部分的+
来设置断点,以便在特定函数上中断。
断点 - 日志点
日志点(在Visual Studio中也称为跟踪点)允许您在不编辑代码的情况下将输出发送到调试控制台。它们与断点不同,因为它们不会停止应用程序的执行流程。
要添加日志点,请在代码行旁边的左侧边距中右键单击。选择添加日志点并输入您想要记录的日志消息。当触发日志点时,任何在大括号('{' 和 '}')之间的表达式都将被评估。
日志消息中也支持以下令牌:
Token | Description | Example Output |
---|---|---|
$FILEPOS | Current source file location | C:\sources\repos\Project\Program.cs:4 |
$FUNCTION | Current function name | Program.<Main>$ |
$ADDRESS | Current instruction | 0x00007FFF83A54001 |
$TID | Thread ID | 20668 |
$PID | Process ID | 10028 |
$TNAME | Thread name | <No Thread Name> |
$PNAME | Process name | C:\sources\repos\Project\bin\Debug\net7.0\console.exe |
$CALLER | Calling function name | void console.dll!Program.Foo() |
$CALLSTACK | Call stack | void console.dll!Program.Bar() void console.dll!Program.Foo() void console.dll!Program.<Main>$(string[] args) [External Code] |
$TICK | Tick count (from Windows GetTickCount) | 28194046 |
$HITCOUNT | Number of times this breakpoint has been hit | 5 |
断点 - 触发的断点
触发的断点是在另一个断点被命中后自动启用的断点。在诊断仅在特定前提条件下发生的代码故障时,它们非常有用。
可以通过右键单击符号边距,选择添加触发断点,然后选择启用该断点的其他断点来设置触发断点。
在异常时停止
C# 调试器支持配置选项,用于在抛出或捕获异常时停止调试器。这是通过在运行视图的断点部分中的两个不同条目来完成的:
请注意,在第一次使用C#调试器调试文件夹之前,BREAKPOINTS部分将缺少这些条目。
检查所有异常将配置调试器在抛出异常时停止。如果启用了仅我的代码(默认情况下是启用的),调试器不会在库代码内部抛出并捕获异常时中断。但是,如果异常在库代码中抛出并返回到用户代码,调试器将中断。
检查用户未处理的异常将配置调试器在非用户代码中捕获到异常时停止,该异常在用户代码中抛出或经过用户代码。成为用户未处理的异常并不总是被调试进程中的错误——可能是用户代码正在实现一个API并预期会引发异常。在许多情况下,确实存在实际问题,因此,默认情况下,当异常成为用户未处理时,调试器将停止。
异常条件
两个复选框都支持仅在选定的异常类型上中断的条件。要编辑条件,请选择铅笔图标(见上图)或右键单击条目并调用编辑条件。条件是一个以逗号分隔的异常类型列表,用于中断,或者如果列表以'!'开头,则是要忽略的异常类型列表。
示例条件:
Example condition value | Result |
---|---|
System.NullReferenceException | This will only break on null reference exceptions. |
System.NullReferenceException, System.InvalidOperationException | This will break on both null reference exceptions and invalid operation exceptions. |
!System.Threading.Tasks.TaskCanceledException | This will break on all exceptions except for task canceled. |
!System.Threading.Tasks.TaskCanceledException, System.NotImplementedException | This will break on all exceptions except for task canceled and not implemented. |
表达式评估
调试器还允许您在WATCH窗口以及调试控制台中评估表达式。
热重载
安装了C# Dev Kit扩展后,调试器允许您在调试时应用C#代码更改。
为了启用热重载,必须将csharp.experimental.debug.hotReload
设置为true,更多信息请参见用户设置。热重载会话仅在目标调试引擎支持应用代码更改时才会启动。
支持的项目和场景
C# Dev Kit 支持“经典”的热重载体验,也称为编辑并继续。无论您是在断点处停止还是程序正在运行,都可以在调试时应用代码更改。
截至2023年11月,一些功能如MetadataUpdateHandler
,它使ASP.NET Core应用程序能够在更改后自动刷新浏览器,目前还不可用。不支持在不调试的情况下应用代码更改。
运行时增加了在Linux/macOS上调试时应用更改的支持,因此在为运行在这些操作系统上的.NET应用程序应用代码更改时,需要.NET 8+的运行时版本。
Application Type | Supports Hot Reload with C# Dev Kit | .NET 8+ Required |
---|---|---|
Console | ✅ | Linux/macOS Only |
Test Projects | ✅ | Linux/macOS Only |
Class Library Projects | ✅ | Linux/macOS Only |
ASP.NET Core | ⚠️* Currently only supports changes on .cs files |
Linux/macOS Only |
MAUI | ❌* Available soon | -- |
Unity | ❌ | -- |
查看支持的项目以获取有关C# Dev Kit当前支持的项目的更多信息。另请参阅C# Dev Kit FAQ以获取有关解决其他不受支持场景的更多信息。
如何应用代码更改
一旦热重载会话开始并进行了新的更改,您可以通过以下任一操作将这些更改应用到您的应用程序中:
Action | Explanation |
---|---|
Hot Reload Ctrl+Shift+Enter |
Apply code changes, available from the Debug Toolbar. |
Save File ⌘S (Windows, Linux Ctrl+S) |
Start applying code changes if csharp.debug.hotReloadOnSave is set to true. See User settings for more information. |
Continue / Step Over / Step Into / Step Out F5 / F10 / F11 / ⇧F11 (Windows, Linux Shift+F11) |
When changes were made while on a break state (for example, while stopped at a breakpoint), these commands will automatically apply them. |
下一步
继续阅读以了解以下内容:
- 调试 - 了解如何在VS Code中使用调试器与您的项目进行任何语言的调试。