Node.js v20.18.0 文档


调试器#

¥Debugger

稳定性: 2 - 稳定的

¥Stability: 2 - Stable

Node.js 包含了一个命令行的调试实用工具。Node.js 调试器客户端不是功能齐全的调试器,但可以进行简单的步进和检查。

¥Node.js includes a command-line debugging utility. The Node.js debugger client is not a full-featured debugger, but simple stepping and inspection are possible.

要使用它,则使用 inspect 参数启动 Node.js,后跟要调试的脚本的路径。

¥To use it, start Node.js with the inspect argument followed by the path to the script to debug.

$ node inspect myscript.js
< Debugger listening on ws://127.0.0.1:9229/621111f9-ffcb-4e82-b718-48a145fa5db8
< For help, see: https://nodejs.cn/docs/inspector
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
 ok
Break on start in myscript.js:2
  1 // myscript.js
> 2 global.x = 5;
  3 setTimeout(() => {
  4   debugger;
debug> 

调试器自动在第一个可执行行中断。要改为运行到第一个断点(由 debugger 语句指定),则将 NODE_INSPECT_RESUME_ON_START 环境变量设置为 1

¥The debugger automatically breaks on the first executable line. To instead run until the first breakpoint (specified by a debugger statement), set the NODE_INSPECT_RESUME_ON_START environment variable to 1.

$ cat myscript.js
// myscript.js
global.x = 5;
setTimeout(() => {
  debugger;
  console.log('world');
}, 1000);
console.log('hello');
$ NODE_INSPECT_RESUME_ON_START=1 node inspect myscript.js
< Debugger listening on ws://127.0.0.1:9229/f1ed133e-7876-495b-83ae-c32c6fc319c2
< For help, see: https://nodejs.cn/docs/inspector
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
< hello
<
break in myscript.js:4
  2 global.x = 5;
  3 setTimeout(() => {
> 4   debugger;
  5   console.log('world');
  6 }, 1000);
debug> next
break in myscript.js:5
  3 setTimeout(() => {
  4   debugger;
> 5   console.log('world');
  6 }, 1000);
  7 console.log('hello');
debug> repl
Press Ctrl+C to leave debug repl
> x
5
> 2 + 2
4
debug> next
< world
<
break in myscript.js:6
  4   debugger;
  5   console.log('world');
> 6 }, 1000);
  7 console.log('hello');
  8
debug> .exit
$ 

repl 命令允许远程评估代码。next 命令步进下一行。键入 help 以查看可用的其他命令。

¥The repl command allows code to be evaluated remotely. The next command steps to the next line. Type help to see what other commands are available.

在不输入命令的情况下按 enter 将重复之前的调试器命令。

¥Pressing enter without typing a command will repeat the previous debugger command.

监视器#

¥Watchers

可以在调试时监视表达式和变量值。在每个断点上,监视器列表中的每个表达式都将在当前上下文中进行评估,并且立即显示在断点的源代码列表之前。

¥It is possible to watch expression and variable values while debugging. On every breakpoint, each expression from the watchers list will be evaluated in the current context and displayed immediately before the breakpoint's source code listing.

要开始监视表达式,则键入 watch('my_expression')。命令 watchers 将打印活动的监视器。要删除监视器,请键入 unwatch('my_expression')

¥To begin watching an expression, type watch('my_expression'). The command watchers will print the active watchers. To remove a watcher, type unwatch('my_expression').

命令参考资料#

¥Command reference

步进#

¥Stepping

  • cont, c:继续执行

    ¥cont, c: Continue execution

  • next, n:单步执行下一行

    ¥next, n: Step next

  • step, s:单步进入

    ¥step, s: Step in

  • out, o:单步退出

    ¥out, o: Step out

  • pause:暂停正在运行的代码(类似于开发者工具中的暂停按钮)

    ¥pause: Pause running code (like pause button in Developer Tools)

断点#

¥Breakpoints

  • setBreakpoint(), sb():在当前行上设置断点

    ¥setBreakpoint(), sb(): Set breakpoint on current line

  • setBreakpoint(line), sb(line):在特定行上设置断点

    ¥setBreakpoint(line), sb(line): Set breakpoint on specific line

  • setBreakpoint('fn()'), sb(...):在函数体的第一条语句上设置断点

    ¥setBreakpoint('fn()'), sb(...): Set breakpoint on a first statement in function's body

  • setBreakpoint('script.js', 1), sb(...):在 script.js 的第一行上设置断点

    ¥setBreakpoint('script.js', 1), sb(...): Set breakpoint on first line of script.js

  • setBreakpoint('script.js', 1, 'num < 4'), sb(...):在 script.js 的第一行上设置条件断点,仅当 num < 4 评估为 true 时才中断

    ¥setBreakpoint('script.js', 1, 'num < 4'), sb(...): Set conditional breakpoint on first line of script.js that only breaks when num < 4 evaluates to true

  • clearBreakpoint('script.js', 1), cb(...):清除 script.js 中第 1 行上的断点

    ¥clearBreakpoint('script.js', 1), cb(...): Clear breakpoint in script.js on line 1

还可以在尚未加载的文件(模块)中设置断点:

¥It is also possible to set a breakpoint in a file (module) that is not loaded yet:

$ node inspect main.js
< Debugger listening on ws://127.0.0.1:9229/48a5b28a-550c-471b-b5e1-d13dd7165df9
< For help, see: https://nodejs.cn/docs/inspector
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
<
Break on start in main.js:1
> 1 const mod = require('./mod.js');
  2 mod.hello();
  3 mod.hello();
debug> setBreakpoint('mod.js', 22)
Warning: script 'mod.js' was not loaded yet.
debug> c
break in mod.js:22
 20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
 21
>22 exports.hello = function() {
 23   return 'hello from module';
 24 };
debug> 

也可以设置条件断点,仅当给定的表达式评估为 true 时才中断:

¥It is also possible to set a conditional breakpoint that only breaks when a given expression evaluates to true:

$ node inspect main.js
< Debugger listening on ws://127.0.0.1:9229/ce24daa8-3816-44d4-b8ab-8273c8a66d35
< For help, see: https://nodejs.cn/docs/inspector
<
connecting to 127.0.0.1:9229 ... ok
< Debugger attached.
Break on start in main.js:7
  5 }
  6
> 7 addOne(10);
  8 addOne(-1);
  9
debug> setBreakpoint('main.js', 4, 'num < 0')
  1 'use strict';
  2
  3 function addOne(num) {
> 4   return num + 1;
  5 }
  6
  7 addOne(10);
  8 addOne(-1);
  9
debug> cont
break in main.js:4
  2
  3 function addOne(num) {
> 4   return num + 1;
  5 }
  6
debug> exec('num')
-1
debug> 

信息#

¥Information

  • backtrace, bt:打印当前执行帧的回溯

    ¥backtrace, bt: Print backtrace of current execution frame

  • list(5):列出脚本源代码的 5 行上下文(前后各 5 行)

    ¥list(5): List scripts source code with 5 line context (5 lines before and after)

  • watch(expr):将表达式添加到监视列表

    ¥watch(expr): Add expression to watch list

  • unwatch(expr):从监视列表中删除表达式

    ¥unwatch(expr): Remove expression from watch list

  • unwatch(index):从监视列表中删除特定索引处的表达式

    ¥unwatch(index): Remove expression at specific index from watch list

  • watchers:列出所有监视器及其值(在每个断点上自动列出)

    ¥watchers: List all watchers and their values (automatically listed on each breakpoint)

  • repl:打开调试器的交互式解释器,以在调试脚本的上下文中进行评估

    ¥repl: Open debugger's repl for evaluation in debugging script's context

  • exec expr, p expr:在调试脚本的上下文中执行表达式并打印它的值

    ¥exec expr, p expr: Execute an expression in debugging script's context and print its value

  • profile:启动 CPU 分析会话

    ¥profile: Start CPU profiling session

  • profileEnd:停止当前 CPU 分析会话

    ¥profileEnd: Stop current CPU profiling session

  • profiles:列出所有已完成的 CPU 分析会话

    ¥profiles: List all completed CPU profiling sessions

  • profiles[n].save(filepath = 'node.cpuprofile'):将 CPU 分析会话以 JSON 格式保存到磁盘

    ¥profiles[n].save(filepath = 'node.cpuprofile'): Save CPU profiling session to disk as JSON

  • takeHeapSnapshot(filepath = 'node.heapsnapshot'):获取堆快照并以 JSON 格式保存到磁盘

    ¥takeHeapSnapshot(filepath = 'node.heapsnapshot'): Take a heap snapshot and save to disk as JSON

执行控制#

¥Execution control

  • run:运行脚本(在调试器启动时自动运行)

    ¥run: Run script (automatically runs on debugger's start)

  • restart:重启脚本

    ¥restart: Restart script

  • kill:杀死脚本

    ¥kill: Kill script

其他#

¥Various

  • scripts:列出所有加载的脚本

    ¥scripts: List all loaded scripts

  • version:显示 V8 的版本

    ¥version: Display V8's version

高级用法#

¥Advanced usage

Node.js 的 V8 检查器集成#

¥V8 inspector integration for Node.js

V8 检查器集成允许将 Chrome 开发者工具绑定到 Node.js 实例以进行调试和分析。它使用 Chrome DevTools 协议

¥V8 Inspector integration allows attaching Chrome DevTools to Node.js instances for debugging and profiling. It uses the Chrome DevTools Protocol.

V8 检查器可以通过在启动 Node.js 应用时传入 --inspect 标志来启用。也可以使用该标志提供自定义的端口,例如 --inspect=9222 将接受端口 9222 上的开发者工具连接。

¥V8 Inspector can be enabled by passing the --inspect flag when starting a Node.js application. It is also possible to supply a custom port with that flag, e.g. --inspect=9222 will accept DevTools connections on port 9222.

使用 --inspect 标志将在连接调试器之前立即执行代码。这意味着代码将在你开始调试之前开始运行,如果你想从一开始就进行调试,这可能并不理想。

¥Using the --inspect flag will execute the code immediately before debugger is connected. This means that the code will start running before you can start debugging, which might not be ideal if you want to debug from the very beginning.

在这种情况下,你有两种选择:

¥In such cases, you have two alternatives:

  1. --inspect-wait 标志:该标志将在执行代码之前等待附加调试器。这允许你从执行一开始就开始调试。

    ¥--inspect-wait flag: This flag will wait for debugger to be attached before executing the code. This allows you to start debugging right from the beginning of the execution.

  2. --inspect-brk 标志:与 --inspect 不同,一旦附加调试器,该标志就会在代码的第一行中断。当你想要从一开始就逐步调试代码而不在调试之前执行任何代码时,这非常有用。

    ¥--inspect-brk flag: Unlike --inspect, this flag will break on the first line of the code as soon as debugger is attached. This is useful when you want to debug the code step by step from the very beginning, without any code execution prior to debugging.

因此,在选择 --inspect--inspect-wait--inspect-brk 时,请考虑是否希望代码立即开始执行、等待调试器连接后再执行,还是在第一行中断以进行逐步调试。

¥So, when deciding between --inspect, --inspect-wait, and --inspect-brk, consider whether you want the code to start executing immediately, wait for debugger to be attached before execution, or break on the first line for step-by-step debugging.

$ node --inspect index.js
Debugger listening on ws://127.0.0.1:9229/dc9010dd-f8b8-4ac5-a510-c1a114ec7d29
For help, see: https://nodejs.cn/docs/inspector 

(在上面的示例中,网址末尾的 UUID dc9010dd-f8b8-4ac5-a510-c1a114ec7d29 是动态生成的,它在不同的调试会话中有所不同。)

¥(In the example above, the UUID dc9010dd-f8b8-4ac5-a510-c1a114ec7d29 at the end of the URL is generated on the fly, it varies in different debugging sessions.)

如果 Chrome 浏览器版本低于 66.0.3345.0,则在上述网址中使用 inspector.html 而不是 js_app.html

¥If the Chrome browser is older than 66.0.3345.0, use inspector.html instead of js_app.html in the above URL.

Chrome DevTools 尚不支持调试 工作线程ndb 可用于调试它们。

¥Chrome DevTools doesn't support debugging worker threads yet. ndb can be used to debug them.

Node.js 中文网 - 粤ICP备13048890号