如何调试nodejs的二进制模块?

Posted

技术标签:

【中文标题】如何调试nodejs的二进制模块?【英文标题】:How to debug binary module of nodejs? 【发布时间】:2014-06-07 09:00:35 【问题描述】:

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

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

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

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

【问题讨论】:

This blog post 涵盖了一些东西,包括需要将你的require 调用从.../Release/... 修改为require('./ObjModule/build/Debug/objModule'),以及这里提到的步骤:node-gyp configure --debug 然后node-gyp build --debug -j 8 【参考方案1】:

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

【讨论】:

在JS中,如何要求调试模块?我尝试要求('./node_module/xxx/Debug/test.node');【参考方案2】:

无耻地从@Peter Cordes 提供的(现已损坏的)链接的archive 复制

首先,使用带有 --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,这是一个 C++ 应用程序。现在,节点本身并不知道您的插件,因此当您尝试在插件函数(在本例中为 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

【讨论】:

非常感谢!这非常有用。无耻地抄袭!【参考方案3】:

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

(gdb) directory /path/to/source

见:http://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html

另外,要获取node-gyp 调试符号,请安装node-gyp-dbg/dev 或等效项,或使用-g 编译它

【讨论】:

感谢您的回复,但事实并非如此。但是我已经在 node-gyp 文档中找到了解决方案。【参考方案4】:

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

基本步骤是:

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

    将您的 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

【讨论】:

以上是关于如何调试nodejs的二进制模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何编译nodejs的二进制模块

NodeJs tcp/udp如何以十六进制的方式发送data,例如网络调试助手中按十六进制发送。

NodeJS学习指南

NodeJS中Buffer模块详解

nodejs加密模块使用

nodejs的require模块及路径