为什么我的Node.js被“程序终止”而没有错误

NuS*_*ler 4 javascript debugging segmentation-fault node.js

我有一个相当大的Node.js项目,在广泛的开发阶段中一直表现出色。但是,最近-不幸的是无法确切指出更改的时间-我的应用程序program terminated 仅在从node.js调试器中运行时才开始退出。

最大的问题:如何找出导致此错误的原因?

我所知道的细目

  • 似乎只发生在调试器中(例如node debug main.js
  • 与节点4.2.5和4.2.6相同的结果。使用Node 5.5.0时,调试器通常会在这种情况下停止工作。
  • 没有额外的输出如堆栈跟踪或错误消息,只有“程序终止”
  • 的过程中的事件SIGINTexit也不uncaughtException是命中
  • 通过这种方式,console.log()我能够确定在我require使用模块时会发生这种情况(有关此问题的更多信息,请参见下文)
  • require逻辑被包围try/ catch但它不赶
  • 我试着使用domainerror处理程序通过将require部分放入run方法中来捕获此内容,但没有捕获任何内容
  • 我使用了madge之类的工具来确保我没有任何循环依赖(也许有更好的方法可以做到这一点)

关于要求

我的程序有一个“插件”类型的系统,其中的模块可以require在运行时根据需要添加。但是,根据require我的判断,这种冒犯性并不是确定的:可以require连续成功几次的模块有时会失败。

同样,这是已经使用了几个月的代码。require当我开始注意到这一点时,我一直在进行一些相当广泛的更改(但没有对上面提到的代码区域进行更改)。由于在看到这一点之前,尽管可以通过许多不同的代码路径运行我通常可以几分钟没有问题,所以很难说是什么触发了这一点。

我还能在这里做什么?

作为参考,代码(不是很及时,因为我还没有推送更改)在Github上,如果有帮助的话。

NuS*_*ler 7

经过更多的挖掘和询问后,我得到了一些答案,所以我自己回答:

  • 至于特定的错误,似乎是Node.js错误
  • 关于“为什么会出现此错误?”的问题 继续阅读...

原因

当Node.js本身遇到段错误时,该程序(例如.js)将停止。您将不会获得异常,执行错误处理程序等。因为底层node已经死亡。如果您在调试器下运行,则只会看到消息program terminated

找出原因

要找出为什么node终止几个选项效果很好:

  1. 安装node-segfault-handler
  2. 使用 gdb

节点段故障处理程序

node-segfault-handler是模块中的一个分支,当发生爆炸时,它将为您提供基本的调用堆栈。简单地将require其初始化在您index.js或您的等效物的顶部:

var SegfaultHandler = require('segfault-handler');
SegfaultHandler.registerHandler("crash.log");
Run Code Online (Sandbox Code Playgroud)

有关其他信息和用法,请参见作者页面

gdb

有了它,gdb您可以获得更多可读的堆栈信息,并根据需要进行真正的调试。请注意,导致Node.js分段错误的常见原因是您可能使用的本机模块。如果是这种情况,最好用调试符号(重新)构建它们,这样您的堆栈跟踪就很有用了。本机模块通常使用node-gyp。在这种情况下,找到modules binding.gyp文件的cflags成员并将其添加-g。来自sqlite3包的示例:

 "cflags": [ "-include ../src/gcc-preinclude.h", "-g" ],
Run Code Online (Sandbox Code Playgroud)

接下来重建您更新的模块:

npm rebuild --build-from-source sqlite3
Run Code Online (Sandbox Code Playgroud)

最后,在node您的程序下执行gdb或附加它。要调试调试器(如我的情况),步骤将如下所示:

  1. 在外壳程序中,运行您的节点应用程序gdb --args,例如gdb --args node debug main.js
  2. 在gdb提示符下,输入 run
  3. 等待崩溃。按下后,键入bt以获取堆栈信息,或进行调试!