在 VS Code 中试用

调试

你可以使用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 中的调试

Debugging using Run and Debug

使用解决方案资源管理器调试

如果已安装 C# Dev Kit 扩展,右键单击解决方案资源管理器中的项目时,会显示“调试”上下文菜单。

有三个选项

  • 启动新实例 - 这会启动附加了调试器的项目。
  • 不调试启动 - 这会在不附加调试器的情况下运行项目。
  • 单步调试进入新实例 - 这会启动附加了调试器的项目,但在代码的入口点停止。

Debugging using Solution Explorer

使用命令面板调试

如果已安装 C# Dev Kit 扩展,还可以使用“调试: 选择并开始调试”命令从命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 开始调试。

注意: 这会在调试下拉列表中添加一个启动配置条目。

Debugging using Command Palette

使用动态(内存中)启动配置调试

如果已安装 C# Dev Kit 扩展,可以创建动态启动配置。创建它们的方式取决于你的项目是否有现有的 `launch.json` 文件。

现有 launch.json

如果你有现有的 `launch.json`,可以转到“调试”视图,选择下拉菜单,然后选择“C#”选项。这会为你提供一些启动目标,你可以将它们添加到下拉列表中。选择后,你可以按 F5 或使用新生成的配置单击“开始调试”。

Add Dynamic C# Configuration

没有 launch.json

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

Debug with Show all automatic debug configurations

移除动态(内存中)启动配置

你可以使用命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 并使用“调试: 选择并开始调试”命令来移除生成的配置。

在下拉列表中,会列出所有现有的调试配置。将鼠标悬停在动态配置上时,右侧会显示一个可单击的垃圾桶图标。你可以单击该图标来移除动态配置。

Remove dynamic configuration

使用编辑器调试/运行按钮调试

在编辑器中打开 `.cs` 文件时,可以通过编辑器窗口右上角的按钮访问运行和调试选项。这些操作将使用当前文件查询项目系统并确定要启动的关联项目。

这两个选项是

  • 运行与此文件关联的项目: 这将使用调试适配器以 `noDebug: true` 启动程序。
  • 调试与此文件关联的项目: 这将在调试器下启动程序。

Editor Run or Debug

使用 launch.json 调试

如果你正在使用 C# Dev Kit,我们不建议使用此选项。但是,如果你需要直接修改调试配置,请参阅配置 launch.json 进行 C# 调试

附加到进程

你可以使用命令面板 ⇧⌘P (Windows, Linux Ctrl+Shift+P) 并运行“调试: 附加到 .NET 5+ 或 .NET Core 进程”命令来附加到 C# 进程。

Attach to a C# process

配置选项

有许多选项和设置可用于配置调试器。可以使用 `launchSettings.json`、VS Code 用户设置来修改调试选项,或者直接修改你的 `launch.json`。

launchSettings.json

如果你有来自 Visual Studio 的 `launchSettings.json`,你应该可以使用通过 F5 运行通过命令面板运行看到列出的配置文件。

Debugging using launchSettings.json

有关详细信息,请参阅配置 C# 调试

用户设置

如果你在使用 C# 调试器时希望更改某些设置,可以在文件 > 首选项 > 设置 (⌘, (Windows, Linux Ctrl+,)) 下找到这些选项并搜索这些选项。

  • `csharp.debug.stopAtEntry` - 如果为 true,则调试器应在目标的入口点停止。此选项默认为 `false`。
  • `csharp.debug.console` - 启动控制台项目时,指示目标程序应启动到哪个控制台。注意: 此选项仅用于“dotnet”调试配置类型。
    • `internalConsole` [默认] - VS Code 的“调试控制台”。此模式允许你在一个位置看到来自调试器和目标程序的消息。有关详细信息,请参阅完整文档
    • `integratedTerminal` - VS Code 的集成终端。
    • `externalTerminal` - 可通过用户设置配置的外部终端。
  • `csharp.debug.sourceFileMap` - 将构建时路径映射到本地源位置。构建时路径的所有实例都将被本地源路径替换。
    示例
        {"<build-path>":"<local-source-path>"}
  • `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# 调试器支持各种断点,例如源行断点、条件断点和日志点。

断点 - 条件断点

借助表达式求值,调试器还支持条件断点。可以将断点设置为在表达式求值为 true 时中断。

Conditional Breakpoints

断点 - 函数断点

调试器还支持函数断点。可以通过单击“调试”面板的“断点”部分中的“+”来设置断点,以便在特定函数处中断。

Function Breakpoints

断点 - 日志点

日志点(在 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

LogMessage Breakpoint

断点 - 触发断点

触发断点是一种断点,当另一个断点被命中后会自动启用。它们在诊断仅在满足特定前置条件后才发生的故障代码时非常有用。

可以通过右键单击字形边距,选择“添加触发断点”,然后选择哪个其他断点启用该断点来设置触发断点。

在异常时停止

C# 调试器支持配置选项,用于控制调试器在抛出或捕获异常时何时停止。这通过“运行”视图中**断点**部分的两个不同条目来完成

Exceptions settings in BREAKPOINTS Run View

请注意,在首次使用 C# 调试器对文件夹进行调试之前,“**断点**”部分将缺少这些条目。

选中**所有异常**将配置调试器在抛出异常时停止。如果启用了仅我的代码(默认情况下启用),则如果在库代码中内部抛出并捕获了异常,调试器将不会中断。但是,如果异常在库代码中抛出并返回到用户代码,则调试器将中断。

选中**用户未处理的异常**将配置调试器在异常在用户代码中抛出或经过用户代码后在非用户代码中捕获时停止。成为用户未处理的异常并不总是被调试进程中的 bug -- 可能是用户代码正在实现一个 API 并预期会引发异常。在许多情况下,确实存在实际问题,因此,默认情况下,当异常成为用户未处理时,调试器将停止。

异常条件

两个复选框都支持仅在选定的异常类型上中断的条件。要编辑条件,请选择铅笔图标(参见上图)或右键单击条目并调用“编辑条件”。该条件是逗号分隔的要中断的异常类型列表,或者如果列表以“!”开头,则是要忽略的异常类型列表。

示例条件

示例条件值 结果
System.NullReferenceException 这将仅在 null 引用异常时中断。
System.NullReferenceException, System.InvalidOperationException 这将在 null 引用异常和无效操作异常时中断。
!System.Threading.Tasks.TaskCanceledException 这将中断除任务取消异常以外的所有异常。
!System.Threading.Tasks.TaskCanceledException, System.NotImplementedException 这将中断除任务取消和未实现异常以外的所有异常。

表达式求值

调试器还允许你在**监视**窗口以及“调试控制台”中求值表达式。

热重载

如果已安装 C# Dev Kit 扩展,调试器允许你在调试时应用 C# 代码更改。

Hot Reload displayed in the debugging toolbar

要启用热重载,必须将 `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)
在中断状态下(例如,在断点处停止时)进行更改后,这些命令将自动应用更改。

Hot Reload demonstrated on ASP.NET

后续步骤

继续阅读以了解

  • 调试 - 了解如何在 VS Code 中使用调试器调试任何语言的项目。