如何调试Node.js的二进制模块?

23

我有一个用C++编写的node.js模块,提供了一些与C++库相关的绑定。该库会导致SIGSEGV崩溃,因此我需要使用GDB进行调试,找出问题所在。

我已经拥有了模块的源代码,在./node_modules/somelib/文件夹中,如果我进入该文件夹并输入npm install,则该库将被编译,并可以通过require('somelib')从node.js中使用。我可以附加gdb到node,并重现错误,但在堆栈跟踪中,我只看到 node_modules/somelib/Release/somelib.node

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

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

答案1: 在gdb中使用命令"dir"指定源代码路径或者使用"gdb -ex 'set args ' -ex 'directory /path/to/source'"来指定源代码路径。
答案2:在binding.gyp文件中添加" 'cflags!': ['-fno-omit-frame-pointer'], 'ldflags': ['-g'] ",然后重新运行"node-gyp rebuild --debug"来生成带有调试符号的二进制文件。

这篇博客文章涵盖了很多内容,包括需要将你的 require 调用从 .../Release/... 修改为 require('./ObjModule/build/Debug/objModule'),以及在此处提到的步骤:node-gyp configure --debug 然后是 node-gyp build --debug -j 8 - Peter Cordes
4个回答

20

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


5
在JS中,如何使用调试模块?我尝试使用require('./node_module/xxx/Debug/test.node')进行引入。 - zwb

6

这段文字是从@Peter Cordes提供的(现已失效)链接的存档中无耻地复制而来的

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

$ node-gyp --debug configure rebuild

其次,如果你像我一样仍处于“游乐场”模式中,那么你可能正在使用以下方式加载你的模块:

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

然而,当您使用node-gyp在调试模式下进行重建时,node-gyp会丢弃Release版本并创建一个Debug版本。因此,请更新模块路径:

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

好的,现在我们准备调试C++插件。使用gdb运行node二进制文件,它是一个C++应用程序。现在,node本身不知道你的插件,因此当你尝试在插件函数上设置断点(在这种情况下是StringReverse)时,它会抱怨该特定函数未定义。不要担心,你的插件是“未来共享库加载”中的一部分,并且一旦你在JavaScript中require()你的插件,它就会被加载。

$ 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

非常感谢!这非常有用。毫不羞耻地复制吧! - bmacnaughton

1

如果您是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 Code中一样设置断点。

愉快的调试!

如果您想要更详细的解释,我还在这里发布了一篇详细的博客。

https://medium.com/@atulanand94/debugging-nodejs-c-addons-using-vs-code-27e9940fc3ad


0

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

(gdb) directory /path/to/source

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

此外,要获取node-gyp的调试符号,请安装node-gyp-dbg/dev或等效版本,或使用-g进行编译。


谢谢回复,但那不是答案。不过我已经在node-gyp文档中找到了解决方案。 - lanoxx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接