从源码了解Node.js(一)开始本地调试

echosoar 原创发表于 2020/03/14 12:14:58
#Node.js
本文以最新的Node.js 14.0.0-pre 进行相关的代码分析。
首先是从github上把node的代码clone到本地,具体的过程不赘述,由于Node.js的部分核心逻辑是使用C++编写的,在开始调试前需要将代码编译构建成二进制文件。

编译

可能很多人都没有自己手动编译过Node.js,其实过程很简单。根目录中有一个 BUILDING.md 文档,可以根据此文档进行编译。在此文档中有罗列支持的编译平台环境、如何进行编译和遇到一些问题该如何解决,以笔者所使用的MacOS为例,大概的讲述一下编译的过程。
通常,对于较为复杂的项目来说,在执行编译前要分析当前所在的系统环境、标准库位置以及编译所需要的一些程序,因此需要去执行根目录下的 configure shell脚本。
./configure
在Node.js中这个脚本主要是去寻找可用的python解释器,找到后使用这个解释器去执行根目录下的 configure.py 脚本,从而完成具体的一些配置工作。
当配置完成之后,就需要执行Makefile去完成具体的编译工作。
make -j4
使用-j4 可以同时运行4个编译作业,能够缩短一些构建时间。
编译需要执行一段时间,在耐心等候之后在根目录就会生成名为 node 的可执行文件。

调试

由于笔者常用的IDE为vscode,如果只是单纯地调试一段c++代码,需要安装c++插件,用来进行代码提示、寻找定义等能力,在插件面板搜索c++就能找到它。
image.png
在xcode中集成了高性能调试器LLDB(Low Level Debuggger),用来调试c、c++和obj-c,具体的介绍可以去其官网了解更多。
因此向本地调试配置(项目根目录的 .vscode/launch.json)文件中添加 lldb 的调试配置:
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(lldb) 启动",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/node",
      "args": [],
      "stopAtEntry": true,
      "cwd": "${workspaceFolder}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "lldb"
    }
}
不过这种方式存在一些问题:
  1. 在MacOS下需要xcode不能高于10.3版本,不然就没法和源文件进行关联,运行后就会发现直接执行结束了。
  2. 因为是lldb启动的调试进程,所以在本地命令行里面看不到,那么就无法随时输入代码进行debug。
因此建议使用 CodeLLDB 这个插件,老好用了!
image.png
不过下载速度感人,建议去github上面下载vsix文件,手动导入到vscode中,手动导入的方式如下:
image.png
待插件导入后,需要重新添加 lldb 的调试配置,还是在项目根目录的 .vscode/launch.json 文件中:
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "Debug",
      "program": "${workspaceFolder}/node",
      "stopOnEntry": true,
      "args": [],
      "cwd": "${workspaceFolder}"
    }
  ]
}
配置完成后,就可以在调试面板点击进行调试了。
image.png
想必学习过c/c++的同学都了解一个程序的入口是main函数,所以在点击Debug前最好在 src/node_main.cc 文件的 99 行添加一个断点,这样就可以在debug执行时断点到入口了。
当然,如果没有任何断点,因为我们在配置 lldb 的时候没有配置参数(args),所以就会按照默认的在命令行中执行 node 一样,执行到REPL,在这里也可以继续手写代码然后进行执行。
image.png