调试
Visual Studio Code 的关键功能之一是其强大的调试支持。VS Code 的内置调试器可帮助您加速编辑、编译和调试循环。
用户界面
下图显示了调试用户界面的主要组件
- 运行和调试视图:显示与运行、调试和管理调试配置设置相关的所有信息。
- 调试工具栏:包含用于最常见调试操作的按钮。
- 调试控制台:使您能够查看和交互在调试器中运行的代码的输出。
- 调试侧边栏:在调试会话期间,使您能够与调用堆栈、断点、变量和监视变量进行交互。
调试器扩展
VS Code 内置支持调试 Node.js 运行时,可以调试 JavaScript、TypeScript 或任何其他编译为 JavaScript 的语言。
要调试其他语言和运行时(包括 PHP、Ruby、Go、C#、Python、C++、PowerShell 和 许多其他语言),请在 VS Code 扩展市场 中查找 调试器
扩展,或在顶层“运行”菜单中选择“安装其他调试器”。
以下是一些包含调试支持的流行扩展
提示:上面显示的扩展是动态查询的。选择上面的扩展磁贴以阅读描述和评论,以决定哪个扩展最适合您。
开始调试
以下文档基于内置的 Node.js 调试器,但大多数概念和功能也适用于其他调试器。
在阅读有关调试的信息之前,最好先创建一个示例 Node.js 应用程序。您可以按照 Node.js 演练 安装 Node.js 并创建一个简单的“Hello World”JavaScript 应用程序 (app.js
)。设置好简单的应用程序后,此页面将带您了解 VS Code 调试功能。
运行和调试视图
要调出运行和调试视图,请在 VS Code 侧面的活动栏中选择运行和调试图标。您也可以使用键盘快捷键 ⇧⌘D (Windows、Linux Ctrl+Shift+D).
运行和调试视图显示与运行和调试相关的所有信息,并带有一个包含调试命令和配置设置的顶栏。
如果尚未配置运行和调试(尚未创建 launch.json
),VS Code 将显示“运行开始”视图。
运行菜单
顶层运行菜单包含最常见的运行和调试命令
启动配置
要在 VS Code 中运行或调试简单应用程序,请在调试开始视图中选择运行和调试,或按 F5,VS Code 将尝试运行您当前的活动文件。
但是,对于大多数调试场景,创建启动配置文件都是有益的,因为它允许您配置和保存调试设置详细信息。VS Code 将调试配置信息保存在 launch.json
文件中,该文件位于工作区(项目根文件夹)的 .vscode
文件夹中,或位于 用户设置 或 工作区设置 中。
要创建 launch.json
文件,请在“运行开始”视图中选择“创建 launch.json 文件”。
VS Code 将尝试自动检测您的调试环境,但如果失败,您将需要手动选择它
以下是为 Node.js 调试生成的启动配置
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}\\app.js"
}
]
}
如果您返回“文件资源管理器”视图(⇧⌘E (Windows、Linux Ctrl+Shift+E)),您会发现 VS Code 创建了一个 .vscode
文件夹,并将 launch.json
文件添加到您的工作区。
注意:即使您在 VS Code 中没有打开文件夹,您也可以调试简单的应用程序,但无法管理启动配置并设置高级调试。如果您没有打开文件夹,VS Code 状态栏将显示紫色。
请注意,启动配置中可用的属性因调试器而异。您可以使用 IntelliSense 建议(⌃Space (Windows、Linux Ctrl+Space))查找特定调试器存在的属性。所有属性都提供悬停帮助。
不要假设一个调试器可用的属性也适用于其他调试器。如果您在启动配置中看到红色波浪线,请将鼠标悬停在它们上面以了解问题所在,并在启动调试会话之前尝试解决它们。
检查所有自动生成的数值,并确保它们对您的项目和调试环境有意义。
启动配置与附加配置
在 VS Code 中,有两种核心调试模式,启动和附加,它们处理两种不同的工作流和开发人员群体。根据您的工作流,可能很难区分哪种配置适合您的项目。
如果您来自浏览器开发者工具背景,您可能不习惯“从工具启动”,因为您的浏览器实例已经打开。当您打开开发者工具时,您只是将开发者工具附加到您打开的浏览器选项卡。另一方面,如果您来自服务器或桌面背景,在编辑器启动您的进程并让编辑器自动将调试器附加到新启动的进程非常常见。
解释启动和附加之间区别的最佳方法是将启动配置视为在 VS Code 附加到它之前如何在调试模式下启动应用程序的配方,而附加配置则是如何在 VS Code 的调试器连接到已经运行的应用程序或进程的配方。
VS Code 调试器通常支持以调试模式启动程序或以调试模式附加到正在运行的程序。根据请求(attach
或 launch),需要不同的属性,VS Code 的 launch.json
验证和建议将对此有所帮助。
添加新的配置
要将新的配置添加到现有的 launch.json
中,请使用以下技术之一
- 如果光标位于配置数组内部,请使用 IntelliSense。
- 按下 添加配置 按钮以在数组开头调用代码片段 IntelliSense。
- 在“运行”菜单中选择 添加配置 选项。
VS Code 还支持用于同时启动多个配置的复合启动配置;有关更多详细信息,请阅读此 部分。
要开始调试会话,请首先在 运行和调试 视图的 配置下拉菜单 中选择名为 启动程序 的配置。设置好启动配置后,使用 F5 开始调试会话。
或者,您可以通过 命令面板 (⇧⌘P(Windows、Linux Ctrl+Shift+P)) 运行您的配置,方法是筛选 调试:选择并开始调试 或键入 'debug '
并选择要调试的配置。
调试会话开始后,将显示 调试控制台 面板,并显示调试输出,状态栏的颜色也会改变(对于默认颜色主题,将变为橙色)。
此外,调试状态 会出现在状态栏中,显示活动的调试配置。通过选择调试状态,用户可以更改活动的启动配置并开始调试,而无需打开 运行和调试 视图。
调试操作
调试会话开始后,调试工具栏 将出现在窗口顶部。
操作 | 解释 |
---|---|
继续/暂停 F5 |
继续:恢复正常程序/脚本执行(直到下一个断点)。 暂停:检查当前行正在执行的代码并逐行调试。 |
步过 F10 |
将下一个方法作为单个命令执行,而无需检查或跟踪其组件步骤。 |
步入 F11 |
进入下一个方法以逐行跟踪其执行。 |
步出 ⇧F11(Windows、Linux Shift+F11) |
当位于方法或子例程内部时,通过将当前方法的剩余行完成为单个命令,返回到较早的执行上下文。 |
重启 ⇧⌘F5(Windows、Linux Ctrl+Shift+F5) |
终止当前程序执行,并使用当前运行配置再次开始调试。 |
停止 ⇧F5(Windows、Linux Shift+F5) |
终止当前程序执行。 |
提示:使用设置 debug.toolBarLocation 控制调试工具栏的位置。它可以是默认的
floating
、docked
到 运行和调试 视图,或者hidden
。floating
调试工具栏可以水平拖动,也可以拖动到编辑器区域(距离顶部边缘一定距离)。
运行模式
除了调试程序之外,VS Code 还支持 运行 程序。调试:无调试启动 操作由 ⌃F5(Windows、Linux Ctrl+F5) 触发,并使用当前选定的启动配置。许多启动配置属性在“运行”模式中受支持。VS Code 在程序运行期间维护调试会话,按下 停止 按钮将终止程序。
提示:“运行”操作始终可用,但并非所有调试器扩展都支持“运行”。在这种情况下,“运行”将与“调试”相同。
断点
通过单击 编辑器边距 或在当前行使用 F9 可以切换断点。可以在 运行和调试 视图的 断点 部分中进行更精细的断点控制(启用/禁用/重新应用)。
- 编辑器边距中的断点通常显示为红色实心圆圈。
- 禁用的断点具有一个填充的灰色圆圈。
- 当调试会话启动时,无法在调试器中注册的断点将变为灰色空心圆圈。如果在没有实时编辑支持的调试会话运行期间编辑了源代码,则也可能会发生这种情况。
如果调试器支持在不同类型的错误或异常上断点,那么这些错误或异常也将出现在 断点 视图中。
重新应用所有断点 命令将所有断点重新设置到其原始位置。这在您的调试环境“懒惰”并将断点“放错位置”到尚未执行的源代码中时很有用。
可以选择通过启用设置 debug.showBreakpointsInOverviewRuler 将断点显示在编辑器的概览标尺中。
日志点
日志点是断点的一种变体,它不会“中断”到调试器,而是将消息记录到调试控制台。日志点使您能够在调试时注入日志记录,而无需修改源代码。当您调试无法暂停或停止的生产服务器时,它们特别有用。日志点还可以通过避免在代码中添加或删除日志语句来帮助您节省时间。
日志点由一个“菱形”图标表示。日志消息是纯文本,但可以包含在花括号 ('{}') 内评估的表达式。
使用左侧编辑器边距上下文菜单中的 添加日志点 命令或使用 调试:添加日志点... 命令添加日志点。您还可以配置设置 debug.gutterMiddleClickAction 以在按编辑器边距中的鼠标中键时切换日志点。
与普通断点一样,日志点可以启用或禁用,也可以通过条件和/或命中次数控制。
注意:日志点受 VS Code 的内置 Node.js 调试器支持,但可以由其他调试扩展实现。例如,Python 和 Java 扩展支持日志点。
数据检查
可以在 运行和调试 视图的 变量 部分中或通过将鼠标悬停在编辑器中的源代码上检查变量。变量值和表达式求值相对于 调用堆栈 部分中选定的堆栈帧。
可以使用变量上下文菜单中的 设置值 操作修改变量值。此外,您可以使用 复制值 操作复制变量的值,或使用 复制为表达式 操作复制访问变量的表达式。
变量和表达式也可以在 运行和调试 视图的 监视 部分中求值和监视。
当焦点位于 变量 部分时,可以通过键入来筛选变量名称和值。
launch.json 属性
有许多 launch.json
属性可帮助支持不同的调试器和调试场景。如上所述,您可以使用 IntelliSense (⌃Space(Windows、Linux Ctrl+Space)) 在指定了 type
属性的值后查看可用属性列表。
以下属性对于每个启动配置都是必需的
type
- 要用于此启动配置的调试器类型。每个安装的调试扩展都引入了类型:例如,内置 Node 调试器的node
或 PHP 和 Go 扩展的php
和go
。request
- 此启动配置的请求类型。目前,支持 launch 和attach
。name
- 在调试启动配置下拉菜单中显示的可读名称。
以下是一些所有启动配置都可用的可选属性
presentation
- 使用presentation
对象中的order
、group
和hidden
属性,您可以在调试配置下拉菜单和调试快速选择中对配置和复合进行排序、分组和隐藏。preLaunchTask
- 要在调试会话开始之前启动任务,请将此属性设置为 tasks.json(在工作区的.vscode
文件夹中)中指定的任务的标签。或者,可以将其设置为${defaultBuildTask}
以使用您的默认构建任务。postDebugTask
- 要在调试会话结束时启动任务,请将此属性设置为 tasks.json(在工作区的.vscode
文件夹中)中指定的任务的名称。internalConsoleOptions
- 此属性控制调试会话期间调试控制台面板的可见性。debugServer
- 仅供调试扩展作者使用:此属性允许您连接到指定的端口,而不是启动调试适配器。serverReadyAction
- 如果您希望在调试下的程序将特定消息输出到调试控制台或集成终端时在 Web 浏览器中打开 URL。有关详细信息,请参阅以下部分 调试服务器程序时自动打开 URI。
许多调试器支持以下一些属性
program
- 启动调试器时要运行的可执行文件或文件args
- 传递给要调试的程序的参数env
- 环境变量(值null
可用于“取消定义”变量)envFile
- 包含环境变量的 dotenv 文件的路径cwd
- 用于查找依赖项和其他文件的当前工作目录port
- 附加到正在运行的进程时的端口stopOnEntry
- 程序启动时立即中断console
- 要使用的控制台类型,例如internalConsole
、integratedTerminal
或externalTerminal
变量替换
VS Code 将常用路径和其他值作为变量提供,并在 launch.json
中支持字符串内的变量替换。这意味着您无需在调试配置中使用绝对路径。例如,${workspaceFolder}
提供工作区文件夹的根路径,${file}
提供活动编辑器中打开的文件,而 ${env:Name}
提供环境变量“Name”。
您可以在 变量参考 中查看预定义变量的完整列表,或者在 launch.json
字符串属性内调用 IntelliSense。
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"cwd": "${workspaceFolder}",
"args": ["${env:USERNAME}"]
}
平台特定属性
Launch.json
支持定义依赖于运行调试器的操作系统的值(例如,要传递给程序的参数)。为此,请将特定于平台的文字放入 launch.json
文件中,并在该文字内指定相应的属性。
以下是一个在 Windows 上以不同方式将 "args"
传递给程序的示例。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulpfile.js",
"args": ["myFolder/path/app.js"],
"windows": {
"args": ["myFolder\\path\\app.js"]
}
}
]
}
有效的操作系统属性是 "windows"
(用于 Windows)、"linux"
(用于 Linux)和 "osx"
(用于 macOS)。在特定于操作系统范围内的定义的属性将覆盖在全局范围内的定义的属性。
请注意,type
属性不能放置在特定于平台的部分内,因为 type
在远程调试场景中会间接确定平台,这将导致循环依赖。
在以下示例中,调试程序始终在入口处停止,除了在 macOS 上。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulpfile.js",
"stopOnEntry": true,
"osx": {
"stopOnEntry": false
}
}
]
}
全局启动配置
VS Code 支持在您的用户 设置 中添加 "launch"
对象。此 "launch"
配置将与您的工作区共享。例如
"launch": {
"version": "0.2.0",
"configurations": [{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${file}"
}]
}
高级断点主题
条件断点
一个强大的 VS Code 调试功能是能够基于表达式、命中次数或两者的组合设置条件。
- 表达式条件:当表达式计算结果为
true
时,将命中断点。 - 命中次数:命中次数 控制断点需要命中多少次才会中断执行。是否遵守命中次数以及表达式的确切语法可能在调试器扩展之间有所不同。
您可以在创建源断点(使用添加条件断点操作)或修改现有断点(使用编辑条件操作)时添加条件和/或命中次数。在这两种情况下,都会打开一个带有下拉菜单的内联文本框,您可以在其中输入表达式。
条件和命中次数编辑支持也适用于 函数 和异常断点。您可以从上下文菜单或新的内联编辑条件操作启动条件编辑。
断点视图中条件编辑的一个示例:
如果调试器不支持条件断点,则添加条件断点和编辑条件操作不可用。
触发断点
触发断点是一种在命中另一个断点后自动启用的断点。它们在诊断仅在满足特定先决条件后才会发生的代码中的故障情况时非常有用。
可以通过右键单击字形边距,选择添加触发断点,然后选择哪个其他断点启用断点来设置触发断点。
触发断点适用于所有语言,条件断点也可以用作触发器。
内联断点
内联断点仅在执行到达与内联断点关联的列时才会命中。这在调试包含单行中多个语句的压缩代码时特别有用。
可以使用 ⇧F9 (Windows、Linux Shift+F9) 或在调试会话期间通过上下文菜单设置内联断点。内联断点在编辑器中内联显示。
内联断点也可以有条件。可以通过编辑器左边缘的上下文菜单编辑一行上的多个断点。
函数断点
调试器可以支持通过指定函数名称来创建断点,而不是将断点直接放置在源代码中。这在源代码不可用但知道函数名称的情况下很有用。
通过按下断点部分标题中的+按钮并输入函数名称来创建函数断点。函数断点在断点部分中以红色三角形显示。
数据断点
如果调试器支持数据断点,则可以从变量视图的上下文菜单中设置它们。断点值更改/读取/访问命令将添加一个数据断点,该断点将在底层变量的值更改/被读取/被访问时命中。数据断点在断点部分中以红色六边形显示。
调试控制台 REPL
可以使用调试控制台 REPL (Read-Eval-Print Loop) 功能来评估表达式。要打开调试控制台,请使用调试窗格顶部的调试控制台操作,或使用视图:调试控制台命令 (⇧⌘Y (Windows、Linux Ctrl+Shift+Y))。
在您按下 Enter 键后,将评估表达式,调试控制台 REPL 会在您键入时显示建议。如果您需要输入多行,请在各行之间使用 Shift+Enter 键,然后使用 Enter 键发送所有行以进行评估。
调试控制台输入使用活动编辑器的模式,这意味着调试控制台输入支持语法着色、缩进、引号自动关闭以及其他语言功能。
注意:您必须处于正在运行的调试会话中才能使用调试控制台 REPL。
将输入/输出重定向到调试目标或从调试目标重定向
重定向输入/输出是特定于调试器/运行时的,因此 VS Code 没有适用于所有调试器的内置解决方案。
以下两种方法您可能想要考虑。
-
在终端或命令提示符中手动启动要调试的程序(“调试目标”)并根据需要重定向输入/输出。确保将适当的命令行选项传递给调试目标,以便调试器可以附加到它。创建并运行一个附加到调试目标的“附加”调试配置。
-
如果您使用的调试器扩展可以在 VS Code 的集成终端(或外部终端)中运行调试目标,您可以尝试将 shell 重定向语法(例如,“<” 或“>”)作为参数传递。
以下是一个
launch.json
配置示例。{ "name": "launch program that reads a file from stdin", "type": "node", "request": "launch", "program": "program.js", "console": "integratedTerminal", "args": ["<", "in.txt"] }
这种方法要求调试器扩展传递“<”语法,并在集成终端中保持不变。
多目标调试
对于涉及多个进程(例如,客户端和服务器)的复杂场景,VS Code 支持多目标调试。在启动第一个调试会话后,您可以启动另一个调试会话。一旦第二个会话启动并运行,VS Code UI 将切换到多目标模式。
-
各个会话现在将在调用堆栈视图中显示为顶级元素。
-
调试工具栏显示当前活动会话(所有其他会话在下拉菜单中可用)。
-
调试操作(例如,调试工具栏中的所有操作)在活动会话上执行。可以通过使用调试工具栏中的下拉菜单或选择调用堆栈视图中的不同元素来更改活动会话。
复合启动配置
启动多个调试会话的另一种方法是使用复合启动配置。您可以在 launch.json
文件的 compounds
属性中定义复合启动配置。使用 configurations
属性来列出应该并行启动的两个或多个启动配置的名称。可选地,可以指定一个 preLaunchTask
,该任务将在启动各个调试会话之前运行。布尔标志 stopAll
控制是否手动终止一个会话将停止所有复合会话。
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Server",
"program": "${workspaceFolder}/server.js"
},
{
"type": "node",
"request": "launch",
"name": "Client",
"program": "${workspaceFolder}/client.js"
}
],
"compounds": [
{
"name": "Server/Client",
"configurations": ["Server", "Client"],
"preLaunchTask": "${defaultBuildTask}",
"stopAll": true
}
]
}
复合启动配置在启动配置下拉菜单中显示。
远程调试
VS Code 不支持在所有语言中内置的远程调试。远程调试是您使用的调试扩展的功能,您应该查看 Marketplace 中扩展的页面以获取支持和详细信息。
但是,有一个例外:VS Code 中包含的 Node.js 调试器支持远程调试。请参阅 Node.js 调试 主题以了解如何配置此功能。
调试服务器程序时自动打开 URI
开发 Web 程序通常需要在 Web 浏览器中打开特定 URL,以便在调试器中命中服务器代码。VS Code 具有一个内置功能“serverReadyAction”来自动执行此任务。
以下是一个简单的 Node.js Express 应用程序示例。
var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.send('Hello World!');
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
});
此应用程序首先为“/”URL 安装一个“Hello World”处理程序,然后开始监听端口 3000 上的 HTTP 连接。端口在调试控制台中宣布,通常情况下,开发人员现在会在其浏览器应用程序中键入 https://127.0.0.1:3000
。
serverReadyAction 功能使您可以将结构化属性 serverReadyAction
添加到任何启动配置中,并选择要执行的“操作”。
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/app.js",
"serverReadyAction": {
"pattern": "listening on port ([0-9]+)",
"uriFormat": "https://127.0.0.1:%s",
"action": "openExternally"
}
}
这里,pattern
属性描述了用于匹配程序输出字符串的正则表达式,该字符串宣布了端口。端口号的模式放在括号中,以便它可用作正则表达式捕获组。在这个示例中,我们只提取端口号,但也可以提取完整的 URI。
uriFormat
属性描述了如何将端口号转换为 URI。第一个 %s
将被匹配模式的第一个捕获组替换。
然后,生成的 URI 将在 VS Code 之外(“外部”)使用为 URI 方案配置的标准应用程序打开。
通过 Edge 或 Chrome 触发调试
或者,action
可以设置为 debugWithEdge
或 debugWithChrome
。在这种模式下,可以添加一个 webRoot
属性,该属性将传递给 Chrome 或 Edge 调试会话。
为了简化,大多数属性都是可选的,我们使用以下回退值。
- pattern:
"listening on.* (https?://\\S+|[0-9]+)"
,它匹配常用的消息“listening on port 3000”或“Now listening on: https://127.0.0.1:5001”。 - uriFormat:
"https://127.0.0.1:%s"
- webRoot:
"${workspaceFolder}"
触发任意启动配置
在某些情况下,您可能需要为浏览器调试会话配置其他选项,或者完全使用不同的调试器。您可以通过将 action
设置为 startDebugging
,并使用 name
属性设置为匹配 pattern
时要启动的启动配置的名称来实现。
命名启动配置必须与包含 serverReadyAction
的配置位于同一个文件或文件夹中。
这里是serverReadyAction 功能的实际操作示例。
后续步骤
要了解有关 VS Code 的 Node.js 调试支持的信息,请查看以下内容。
- Node.js - 描述 VS Code 中包含的 Node.js 调试器。
- TypeScript - Node.js 调试器还支持 TypeScript 调试。
要观看有关调试基础的教程,请查看此视频
- VS Code 调试入门 - 了解 VS Code 中的调试。
要了解通过 VS Code 扩展对其他编程语言的调试支持
要了解 VS Code 的任务运行支持,请转到
- 任务 - 描述如何使用 Gulp、Grunt 和 Jake 运行任务以及如何显示错误和警告。
要编写自己的调试器扩展,请访问
- 调试器扩展 - 使用模拟示例说明创建 VS Code 调试扩展所需的步骤。
常见问题
支持哪些调试场景?
基于 Node.js 的应用程序的调试在 Linux、macOS 和 Windows 上开箱即用地受 VS Code 支持。许多其他场景都由 VS Code 扩展 支持,这些扩展可在 Marketplace 中找到。
在“运行和调试”视图下拉菜单中,我未看到任何启动配置。这是怎么回事?
最常见的问题是您没有设置 launch.json
或该文件中存在语法错误。或者,您可能需要打开一个文件夹,因为无文件夹调试不支持启动配置。