我有一个相当大的Node.js项目,该项目在很长一段时间内都很有效。然而,最近 - 并且遗憾的是无法准确指出它何时发生变化 - 我的应用程序仅在从node.js调试器中运行时才开始退出program terminated
。
最大的问题:如何找出导致此错误的原因?
细分我所知道的:
node debug main.js
)SIGINT
,exit
和uncaughtException
的流程事件console.log()
,当我require
一个模块时,我已经确定会发生这种情况(有关此内容的更多信息)require
逻辑被try
/ catch
包围,但没有抓住domain
的{{1}}处理程序通过将error
部分放在require
方法中来捕捉到这一点,但是没有任何内容, 关于要求:
我的程序有一个"插件"类型系统,其中模块在运行时根据需要run
。然而,违反require
并不是我所知道的确定性:连续几次可以require
成功的模块会失败。
同样,这是已经工作了几个月的代码。当我开始注意到这一点时,我一直在进行一些相当广泛的更改(但不是使用上面提到的require
代码区域)。由于在看到这个之前我经常可以运行几分钟但没有问题,但是很难说是什么触发了这个。
我还能在这做什么?!
作为参考,(如果我没有推动我的更改,则不是最新的)代码is on Github,如果有帮助的话。
答案 0 :(得分:4)
经过更多的挖掘和询问后,我得到了一些答案,所以我自己回答:
原因
当Node.js本身遇到段错误时,程序(例如.js)将停止。 您不会收到异常,执行错误处理程序等。因为潜在的node
已经死亡。如果您在调试器下运行,则您将看到的唯一消息是program terminated
。
找出原因
要找出为什么node
终止两个选项的效果很好:
gdb
<强>节点段错误处理程序强>
node-segfault-handler
是一个下拉模块,当爆炸时会给你一个基本的调用堆栈。只需require
并将其添加到index.js
或等效的顶部:
var SegfaultHandler = require('segfault-handler');
SegfaultHandler.registerHandler("crash.log");
有关其他信息和用法,请参阅authors page。
<强> GDB 强>
使用gdb
,您可以获得更多可读的堆栈信息,并在需要时进行真正的调试。请注意,Node.js分段错误的常见原因是您可能正在使用的本机模块。如果是这种情况,那么(重新)使用调试符号构建它们可能是个好主意,因此堆栈跟踪有一些用处。本机模块通常使用node-gyp。在这种情况下,找到模块binding.gyp
文件的cflags
成员并向其添加-g
。 sqlite3包中的示例:
"cflags": [ "-include ../src/gcc-preinclude.h", "-g" ],
接下来重建您更新的模块:
npm rebuild --build-from-source sqlite3
最后,在node
下执行gdb
和您的程序或附加它。要调试调试器(就像我的情况一样),步骤将是这样的:
node debug main.js
ps aux | grep node
查找运行调试器的node
进程的PID(在命令行中将有--debug-brk main.js
)gdb
然后attach THEPID
将THEPID
替换为步骤2中的PID。继续并等待崩溃。点击它后,输入bt
以获取堆栈信息,或调试掉!