调试
你可以在Visual Studio Code中使用Microsoft C#扩展来调试C#应用程序。
运行与调试
C# 扩展和 C# 开发工具包提供了多种方式来运行和调试你的 C# 应用。
要在没有 C# Dev Kit 的情况下运行和调试,请参见 Microsoft C# 扩展的 GitHub 页面上的文档。
用F5调试
安装了 C# Dev Kit 扩展,且调试视图中没有调试配置,你可以通过设置.cs打开文件,然后按F5。调试器会自动找到你的项目并开始调试。如果你有多个项目,它会提示你想开始调试哪个项目。
你也可以从VS Code侧边栏的运行和调试视图开始调试会话。更多内容请参见“VS Code调试”。

使用解决方案管理器调试
安装了 C# Dev Kit 扩展后,在解决方案资源管理器中右键点击项目时会有一个调试上下文菜单。
有三种选择:
- 启动新实例——这会让你的项目开始时附带一个调试器。
- 开始时不调试——这样可以运行你的项目,不绑定调试器。
- 进入新实例——这会让你的项目开始时附带一个调试器,但会在代码的入门点停止。

使用命令调色板进行调试
安装了 C# 开发套件扩展后,你还可以通过 Debug: Select 和 Start Debugging 命令从 Command Palette ⇧⌘P(Windows,Linux Ctrl+Shift+P)开始调试。
注意:这会在你的调试下拉列表中添加启动配置条目。

使用动态(内存内)启动配置进行调试
安装了 C# 开发套件扩展后,你可以创建动态启动配置。如何创建配置取决于你的项目是否有现有配置launch.json档案。
现有launch.json
如果你已经有launch.json你可以进入调试视图,选择下拉菜单,然后选择C#选项。这应该会给你一个可以添加到下拉列表的发射目标选择。选中后,你可以按F5或使用新生成的配置开始调试。

没有launch.json
如果你没有launch.json在你的项目中,你可以在调试视图中的“显示所有自动调试配置”中添加并访问这些动态配置。

移除动态(内存内)启动配置
你可以用命令面板 ⇧⌘P(Windows,Linux Ctrl+Shift+P)和命令 Debug: Select and Start Debugging 来移除生成的配置。
在下拉菜单里,它列出了你所有现有的调试配置。如果你将鼠标悬停在动态配置上,右侧会出现一个可点击的垃圾桶图标。你可以选择那个图标来移除动态配置。

用编辑器的调试/运行按钮调试
当.cs文件在编辑器中打开,运行和调试选项可通过编辑器窗口右上角的按钮访问。这些作将使用当前文件查询项目系统,并确定要启动的关联项目。
有两种选择:
-
运行与此文件关联的项目:这将启动你的节目noDebug:真使用调试适配器。 -
与此文件相关的调试项目: 这会在调试器下启动你的程序。

用launch.json调试
如果你使用的是 C# 开发套件,我们建议不要使用这个选项。不过,如果你需要直接修改调试配置,请参见 C# 调试的配置launch.json。
附加到进程
你可以使用命令面板 ⇧⌘P(Windows,Linux Ctrl+Shift+P)并运行 Debug: Attach to .NET 5+ 或 .NET Core 进程命令,连接到 C# 进程。

配置选项
调试器有许多选项和设置可供配置。你可以使用launchSettings.json, VS Code 用户设置以修改你的调试选项,或直接修改你的launch.json.
launchSettings.json
如果你有launchSettings.json在Visual Studio里,你应该会看到通过“从F5运行”或“从命令调色板运行”来显示你的配置文件。

详情请参见配置 C# 调试。
用户设置
如果你在使用 C# 调试器时有想更改的设置,可以在 File > 偏好设置>设置(⌘,(Windows, Linux Ctrl+,))中找到这些选项,并搜索这些选项。
csharp.debug.stopAtEntry(查普.调试.stopAtEntry)- 如果为真,调试器应在目标的入口点停止。该选项默认为错误.csharp.debug.console- 启动控制台项目时,表示目标程序应启动到哪个控制台。注:该选项仅用于“dotnet”调试配置类型。内部控制台[默认] - VS Code 的调试控制台。该模式允许您在同一地点同时查看来自调试器和目标程序的消息。详情请参阅完整文档。integratedTerminal- VS Code的集成终端。外部终端- 可通过用户设置配置的外部终端。
csharp.debug.sourceFileMap- 绘制构建时间路径至本地源点的地图。所有构建时间路径实例将被本地源路径替代。
示例:
{\“<build-path>\”:\“<local-source-path>\”}csharp.debug.justMyCode- 启用时(默认情况下),调试器仅显示并步入用户代码(“我的代码”),忽略系统代码及其他优化代码或无调试符号的代码。更多信息。csharp.debug.requireExactSource- 标记要求当前源代码与 pdb 匹配。该选项默认为确实如此.csharp.debug.enableStepFiltering- 标志用于启用跨步覆盖属性和作符。该选项默认为确实如此.csharp.debug.logging.exceptions- 标志用于判断异常消息是否应记录到输出窗口。该选项默认为确实如此.csharp.debug.logging.moduleLoad- 标志用于判断模块加载事件是否应记录到输出窗口。该选项默认为确实如此.csharp.debug.logging.programOutput- 标志用于判断程序输出是否应在未使用外部控制台时记录到输出窗口。该选项默认为确实如此.csharp.debug.logging.diagnosticsLog- 用于诊断调试器问题的各种设置。csharp.debug.logging.browserStdOut- 标志用于判断浏览器启动时的标准输出文本是否应被记录到输出窗口。该选项默认为确实如此.csharp.debug.logging.elapsedTiming- 如果为真,发动机日志包括适配器经过时间以及engine经过时间属性表示请求所耗时的时间(以微秒计)。该选项默认为错误.csharp.debug.logging.threadExit- 控制目标进程中线程退出时是否记录消息。该选项默认为错误.csharp.debug.logging.processExit- 控制目标进程退出或停止调试时是否记录消息。该选项默认为确实如此.csharp.debug.suppressJITptimizations- 如果成立,当目标进程加载优化模块(.dll在发布配置中编译)时,调试器会要求即时编译器生成禁用优化的代码。更多信息csharp.debug.symbolOptions.searchPaths- 符号服务器URL数组(例如:http://MyExampleSymbolServer)或目录(例如:/build/symbols)用于搜索.pdb文件。这些目录除了模块旁的默认位置和pdb最初丢弃路径外,还会被搜索。csharp.debug.symbolOptions.searchMicrosoftSymbolServer- 如果确实如此Microsoft Symbol服务器(https://msdl.microsoft.com/download/symbols)被添加到符号的搜索路径中。如果未指定,该选项默认为错误.csharp.debug.symbolOptions.searchNuGetOrgSymbolServer- 如果确实如此NuGet.org 符号服务器(https://symbols.nuget.org/download/symbols)被添加到符号的搜索路径中。如果未指定,该选项默认为错误.csharp.debug.symbolOptions.cachePath- 从符号服务器下载的符号应缓存的目录。如果未指定,Windows上的调试器默认为%TEMP%\\SymbolCache,在Linux和macOS上,调试器默认为~/.dotnet/symbolcache.csharp.debug.symbolOptions.moduleFilter.mode- 控制模块滤波器在两种基本工作模式下工作的哪一种。loadAllButExcluded- 所有模块的加载符号,除非模块属于exclusiondModules阵列。loadOnlyIncluded- 除非模块在包含模块数组,或者通过includeSymbolsNextToModules环境。
csharp.debug.symbolOptions.moduleFilter.excludedModules- 调试器不应加载符号的模块数组。支持通配符(例如:MyCompany.*.dll)。除非模式设置为loadAllButExcluded.csharp.debug.symbolOptions.moduleFilter.includedModules- 调试器应加载符号的模块数组。支持万用符(例如:MyCompany.*.dll)。除非模式设置为loadOnlyIncluded.csharp.debug.symbolOptions.moduleFilter.includeSymbolsNextToModules- 如果成立,对于任意不属于包含模块数组,调试器仍会检查模块本身和启动可执行文件,但不会检查符号搜索列表上的路径。该选项默认为确实如此. 除非模式设置为loadOnlyIncludedcsharp.debug.allowFastEvatu(快速评估)- 当为真(默认状态)时,调试器将通过模拟简单属性和方法的执行来尝试更快的求值。csharp.experimental.debug.hotReload- 当为真时,如果目标应用程序支持热重载,调试器将在调试时启用应用变更。csharp.debug.hotReloadOnSave(保存)- 当 true(默认状态)时,调试器在保存文件时会自动应用代码更改。csharp.debug.hotReloadVerbosity- 控制 C# 热装载输出窗口的日志冗长度。它可以从极简(默认),详细情况或诊断.如果热装填开始异常,建议提高冗长度。
断点
C# 调试器支持多种断点,如源行断点、条件断点和日志点。
断点 - 条件断点
借助表达式求值,调试器还支持条件断点。当表达式值为真时,你可以设置断点为断点。

断点 - 函数断点
调试器还支持功能性断点。你可以在调试面板的断点部分点击断点,将断点设置为在特定函数上中断。+

断点 - 对数点
Logpoints(在Visual Studio中也称为Tracepoints)允许你在不修改代码的情况下将输出发送到调试控制台。它们和断点不同,因为它们不会阻止你应用的执行流程。
要添加Logpoint,请右键点击代码行旁最左边距。选择添加Logpoint,输入你想记录的消息。任何夹在大括号之间的表达式('{'和'}')在被击中对数点时都会被评估。
日志消息中也支持以下令牌:
| 代币 | 描述 | 示例输出 |
|---|---|---|
| $FILEPOS | 当前源文件位置 | C:\sources\repos\Project\Program.cs:4 |
| $FUNCTION | 当前功能名称 | 程序.<主> |
| $ADDRESS | 现行教学 | 0x00007FFF83A54001 |
| $TID | 线程ID | 20668 |
| $PID | 进程ID | 10028 |
| $TNAME | 线程名称 | <无线程名> |
| $PNAME | 工艺名称 | C:\sources\repos\Project\bin\Debug\net7.0\console.exe |
| $CALLER | 调用函数名称 | 虚无console.dll!程序.Foo() |
| $CALLSTACK | 呼叫堆栈 | 虚无console.dll!Program.Bar() 虚无console.dll!程序。Foo() 虚无console.dll!Program.<Main>$(string[] args) [外部代码] |
| $TICK | Tick 计数(来自 Windows GetTickCount) | 28194046 |
| $HITCOUNT | 该断点被击中次数 | 5 |

断点 - 触发断点
触发断点是指一旦触发另一个断点时自动启用的断点。它们在诊断代码中仅在某个前提条件之后才发生的失败案例时非常有用。
触发断点可以通过右键点击字形边缘,选择添加触发断点,然后选择启用该断点的其他断点来设置。
在例外情况下停止
C# 调试器支持在抛出或捕获异常时停止的配置选项。这通过运行视图断点部分中的两个不同条目实现:

注意,BREAKPOINTS 部分在用 C# 调试器第一次调试该文件夹之前,将缺少这些条目。
“检查所有异常”会让调试器在抛出异常时停止。如果启用了 Just My Code(默认是),调试器在库代码中被内部抛出异常并捕获时不会出故障。然而,如果库代码中抛出异常并返回给用户代码,调试器就会出问题。
检查用户未处理异常将配置调试器在异常被非用户代码捕获时停止,该异常已被抛入用户代码或通过用户代码传输。变成用户未处理的异常不一定是调试过程中的错误——可能是用户代码实现了API,预期会触发异常。在许多情况下确实存在问题,因此默认情况下,当异常变为用户未处理时,调试器会停止。
例外条件
这两个复选框都支持只在特定例外类型上破坏条件。要编辑条件,选择铅笔图标(见上图)或右键点击条目并调用编辑条件。该条件是一个逗号分隔的异常类型列表,用于中断,或者如果列表以“!”开头,则是一个需要忽略的异常类型列表。
示例条件:
| 示例条件值 | 结果 |
|---|---|
| System.NullReferenceException | 这只有在空引用例外时才会出错。 |
| System.NullReferenceException, System.InvalidOperationException | 这会在空引用异常和无效作异常上都会出现故障。 |
| !System.Threading.Tasks.TaskCanceledException | 除了任务取消外,所有例外都会出错。 |
| !System.Threading.Tasks.TaskCanceledException, System.NotImplementedException | 除了任务取消且未实现外,所有异常都会出错。 |
表达式评估
调试器还允许你在WATCH窗口和调试控制台中评估表达式。
热装填
安装了 C# 开发工具包扩展后,调试器允许你在调试时应用 C# 代码修改。

为了启用热装填,csharp.experimental.debug.hotReload必须设置为 true,更多信息请参见用户设置。热重载会话只有在目标调试器引擎支持应用代码更改时才会启动。
支持的项目与场景
C# 开发工具包支持“经典”热加载体验,也称为编辑和继续。无论你是否停在断点或程序正在运行,都可以在调试时应用代码修改。
截至2023年11月,一些功能如MetadataUpdateHandler目前尚未提供 ASP.NET Core 应用在更改后自动刷新浏览器的功能。不支持在不调试的情况下应用代码更改。
运行时增加了在 .NET 8 中 Linux/macOS 调试时应用更改的支持,因此在为运行在这些作系统上的 .NET 应用应用代码变更时,需要运行时版本的 .NET 8+。
| 应用类型 | 支持C#开发套件的热重载 | .NET 8+ 必修 |
|---|---|---|
| 控制台 | ✅ | 仅限Linux/macOS |
| 测试项目 | ✅ | 仅限Linux/macOS |
| 班级图书馆项目 | ✅ | 仅限Linux/macOS |
| ASP.NET 核心 | ⚠️*目前只支持更改.cs文件 |
仅限Linux/macOS |
| 毛伊岛 | ❌ * 即将上线 | -- |
| Unity | ❌ | -- |
有关目前由 C# 开发套件支持的项目的更多信息,请参见支持项目。另请参阅 C# 开发工具包常见问题,了解更多关于排查其他未受支持场景的信息。
如何应用代码变更
一旦热重载会话开始并做出新更改,您可以通过以下任一作将这些更改应用应用:
| 行动 | 解释 |
|---|---|
| 热装填 Ctrl+Shift+Enter |
应用代码变更,可从调试工具栏中获得。 |
| 存档 ⌘S(Windows,Linux Ctrl+S) |
如果csharp.debug.hotReloadOnSave(保存)设置为 true。更多信息请参见用户设置。 |
| 继续 / 步入 / 步出 F5 / F10 / F11 / ⇧F11(Windows,Linux Shift+F11) |
当更改发生在断裂状态(例如停在断点时),这些命令会自动应用。 |

下一步
继续阅读,了解:
- 调试——了解如何在VS Code中使用任何语言的调试器配合你的项目。