如何调试nodejs的二进制模块

How to debug binary module of nodejs?

本文关键字:nodejs 二进制 模块 调试 何调试      更新时间:2023-10-16

我有一个用C++编写的node.js模块,它为C++库提供了一些绑定。该库与SIGSEGV一起崩溃,所以我需要使用GDB对其进行调试,并找出问题所在。

我在./node_modules/somelib/中已经有了模块的源代码,如果我转到那个文件夹并键入npm install,就会编译该库,并且可以通过node.js中的require("somelib")使用。我可以将gdb附加到node并重现错误,但在堆栈中我只看到node_modules/somelib/Release/somelib.node

我不确定这是否重要,但库是使用node-gyp编译的。

  • 问题1:如何加载源代码或将gdb指向源代码
  • 问题2:如何配置node-gyp以生成调试符号

我刚刚在node-gyp文档中找到了答案。解决方案是使用--debug标志来调用构建过程。这意味着调用node-gyp configure --debug和/或node-gyp build --debug。然后将创建Debug文件夹而不是Release文件夹。gdb将自动加载源文件。

从@Peter Cordes提供的(现已断开的)链接档案中可耻地复制

首先,使用带有--debug标志的node-gyp编译插件。

$ node-gyp --debug configure rebuild

其次,如果你仍然像我一样处于"操场"模式,你可能正在用之类的东西加载你的模块

var ObjModule = require('./ObjModule/build/Release/objModule');

但是,当您在调试模式下使用node-gip重建时,node-gip会丢弃Release版本,转而创建debug版本。因此更新模块路径:

var ObjModule = require('./ObjModule/build/Debug/objModule');

好了,现在我们准备调试我们的C++插件了。对节点二进制文件运行gdb,这是一个C++应用程序。现在,节点本身并不知道您的加载项,所以当您试图在加载项函数(在本例中为StringReverse)上设置断点时,它会抱怨没有定义特定的函数。不用担心,您的插件是它所指的"未来共享库加载"的一部分,一旦您需要()JavaScript插件,就会加载它。

$ gdb node
...
Reading symbols from node...done.
(gdb) break StringReverse
Function "StringReverse" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y  

好的,现在我们只需要运行应用程序:

(gdb) run ../modTest.js 
...
Breakpoint 1, StringReverse (args=...) at ../objModule.cpp:49

如果您是VSCode用户,您可能会发现这对调试模块很有帮助。

基本步骤是:

  1. 安装vscode插件https://github.com/vadimcn/vscode-lldb

  2. 将您的launch.json设置为如下所示:

{ "version": "0.2.0", "configurations": [{ "type": "lldb", "request": "launch", "name": "Launch Program", "program": "/absolute/path/to/node", "args": [ "/absolute/path/to/your/index.js" ] }] }

然后像在VS代码中那样设置断点。

调试愉快!

如果你想要更详细的解释,我也在这里发布了一个详细的博客。

https://medium.com/@atulanand94/调试-nodejs-c-addons-using-vs-code-27e9940fc3 ad

您可以将包含模块源的目录添加到gdb的搜索路径:

(gdb) directory /path/to/source

请参阅:http://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html

此外,要获得node-gyp调试符号,请安装node-gyp-dbg/dev或等效程序,或使用-g 编译