使用 Node.js 内置调试器进行调试

发布时间 2023-05-08 13:56:04作者: 癫狂编程

使用 Node.js 内置调试器进行调试

调试是一个多阶段的过程,通常遵循以下步骤:

  1. 识别程序中的 bug。
  2. 查找 bug 在代码中的位置。
  3. 分析 bug 发生的原因。
  4. 修复 bug。
  5. 验证修复是否有效。

在 Node.js 程序中发现错误后,你面临的第一个挑战就是在代码中找到错误所在的位置。 为实现这一点,最有效的方法之一就是分步运行代码,找出开始出错的位置。

断点

如果程序有成千上万行代码,那么逐步运行所有代码可能效率非常低。 在这种情况下,可以使用断点。 使用它可以在代码中的给定点中断程序正常执行并暂停。

使用断点,可以使程序正常运行,直到到达怀疑错误所在的关键代码部分。 然后可以切换到逐步执行。

根据调试器和代码编辑器,可以通过多种方式在代码中定义断点。 有一种通用的方法可以强制任何 JavaScript 调试器在给定的点暂停。 使用 debugger 语句。

可以在代码中的任意位置添加此语句,例如:

Javascript
function addToBasket(product) {
    // Use "debugger" statement to pause at start of this function
    debugger;
  
    const basket = getCurrentBasket();
    basket.add(product);
  }

Node.js 检查模式

由于调试器拥有对执行环境的完全访问权限,恶意行动者还可以使用它在你的 Node.js 进程中注入任意代码。 因此,Node.js 默认不允许调试正在运行的程序。 必须启用一种称为检查器模式的特殊模式才能允许调试。

需使用 --inspect 选项来允许 Node.js 进程侦听调试器客户端,该调试器将自己附加到进程并控制程序执行。

默认情况下,使用 --inspect 选项启动 Node.js 时,它将在端口 9229 上侦听主机 127.0.0.1。 还可以使用语法 --inspect=<HOST>:<PORT> 指定自定义主机和端口。

 重要

避免将 Node.js 调试器端口绑定到公共 IP 地址或 0.0.0.0。 否则,可以连接到 IP 地址的任何客户端都可能连接并控制 Node.js 进程。 这样一来,攻击者就可以在你的执行环境中远程运行任意代码。 此操作可能导致潜在的严重安全漏洞。

作为替代方法,可以使用 --inspect-brk 选项。 该选项的工作方式与 --inspect 相同,但会在代码开始之前中断代码执行。

在启用了检查模式的情况下启动 Node.js 后,可以使用任何兼容的调试器客户端连接到 Node.js 进程。

节点检查中的超时错误

如果 node inspect 或 node --inspect 命令返回超时错误,可以尝试为系统全局安装检查模式以便解决问题。 有关安装选项,请参阅如何安装 Node.js

内置调试器

例如,可以使用 node-inspect。 此命令行调试器与 Node.js 捆绑在一起。 可以通过按如下所述运行程序来使用它:

Bash
node inspect <YOUR_SCRIPT>.js

node-inspect 调试器将在启用检查模式的情况下运行 Node.js,同时启动集成的交互式调试器。 它将在代码开始之前暂停执行。 应会看到调试器提示,指出它已成功启动。

Bash
node inspect myscript.js
< Debugger listening on ws://127.0.0.1:9229/ce3689fa-4433-41ee-9d5d-98b5bc5dfa27
< For help, see: https://nodejs.org/en/docs/inspector
< Debugger attached.
Break on start in myscript.js:1
> 1 const express = require('express');
  2
  3 const app = express();
debug>

你现在可以使用多个命令来控制程序的执行:

  • cont 或 c:继续。 继续执行到下一个断点或程序末尾。
  • next 或 n:执行下一行。 执行当前上下文中的下一行代码。
  • step 或 s:单步执行。 与 next 相同,不同之处在于如果下一行代码是函数调用,则转到此函数代码的第一行。
  • out 或 o:单步跳出。如果当前执行上下文在函数的代码内,请执行该函数的其余代码,然后跳回到最初调用该函数的代码行。
  • restart 或 r:重启。 重启程序,并在代码开始之前暂停执行。

若要在代码中设置或清除断点,使用以下命令:

  • setBreakpoint() 或 sb():在当前行上添加断点。
  • setBreakpoint(<N>) 或 sb(<N>):在行号 N 上添加一个断点。
  • clearBreakpoint('myscript.js', <N>) 或 cb('myscript.js', <N>):清除行号 N 处文件 myscript.js 中的断点。

若要获取有关当前执行点的信息,运行以下命令:

  • list(<N>):列出包含当前执行点之前和之后 N 行的源代码。
  • exec <EXPR>:在当前执行上下文中计算表达式。 此命令有助于获取有关当前状态的信息。 例如,可以通过使用 exec i 获取名为 i 的变量的值。

要记住的命令很多。 值得庆幸的是,还可以使用 help 命令显示可用命令的完整列表。 若要随时退出调试器,请按 Ctrl+D 或选择命令 .exit


下一单元: 练习 - 使用 Node.js 内置调试器

https://learn.microsoft.com/zh-cn/training/paths/build-javascript-applications-nodejs/