node.js - 进程内存不足时如何处理V8引擎崩溃

标签 node.js v8 qt5 seh debugbreak

两者都是node控制台和基于 Qt5 的 V8 QJSEngine可以通过以下代码崩溃:

a = []; for (;;) { a.push("hello"); }

Node 崩溃前的输出:

FATAL ERROR: JS Allocation failed - process out of memory

QJSEngine 崩溃前的输出:

#
# Fatal error in JS
# Allocation failed - process out of memory
#

如果我在调试器下运行我的 QJSEngine 测试应用程序(见下文),它会显示 v8::internal::OS::DebugBreak在 V8 代码中调用。如果我将调用 QJSEngine::evaluate 的代码包装到 __try-__except ( SEH ) 中,则应用程序不会崩溃,但此解决方案是特定于 Windows 的。

问题:有没有办法在 Node 和 Qt 应用程序中以平台无关的方式处理 v8::internal::OS::DebugBreak

=== QJSEngine 测试代码===

开发环境:QtCreator with Qt5 and Windows SDK 7.1, on Windows XP SP3

QJSEngineTest.pro:

TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest

没有 SEH 的 main.cpp(这会崩溃):

#include <QtQml/QJSEngine>

int main(int, char**)
{
  try {
    QJSEngine engine;
    QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
    qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
  } catch (...) {
    qDebug("Exception");
  }
  return 0;
}

带有 SEH 的 main.cpp(这不会崩溃,输出“致命异常”):

#include <QtQml/QJSEngine>
#include <Windows.h>

void runTest()
{
  try {
    QJSEngine engine;
    QJSValue value = engine.evaluate("a = []; for (;;) { a.push('hello'); }");
    qDebug(value.isError() ? "Error" : value.toString().toStdString().c_str());
  } catch (...) {
    qDebug("Exception");
  }
}

int main(int, char**)
{
  __try {
    runTest();
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    qDebug("Fatal exception");
  }
  return 0;
}

最佳答案

我不相信有一种跨平台的方法可以捕获 V8 fatal error ,但即使有,或者如果有某种方法可以在您关心的所有平台上捕获它们,我也不确定那是什么会买你。

问题是 V8 使用了 global flag记录是否发生 fatal error 。一旦设置了该标志,V8 将拒绝任何创建新 JavaScript 上下文的尝试,因此继续下去是没有意义的。在捕捉到最初的 fatal error 后尝试执行一些良性的 JavaScript 代码。如果我是对的,您会立即收到另一个 fatal error 。

在我看来,正确的做法是让 Node 和 Qt 将 V8 配置为首先不引发 fatal error 。现在 V8 支持隔离和内存限制,进程终止 fatal error 不再适用。不幸的是,V8 的错误处理代码似乎还不能完全支持这些新功能,并且仍然假设内存不足的情况始终无法恢复。

关于node.js - 进程内存不足时如何处理V8引擎崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16797423/

相关文章:

javascript - Nodejs 在模块之间传递日志实例

javascript - 客户端到客户端 Websocket

javascript - Node.js 中是否有用于情感分析的网络挖掘库?

javascript - 占位符获取第一个单词并忽略其他单词

javascript - 用于 ECMAScript-262 的 IDE,用于 node.js/V8 的 IDE 执行/调试

javascript - Google 的 V8 JavaScript 引擎可用于 iOS 吗?

c++ - QT Clear painter canvas Widget 使用Overlay Widget绘制

c++ - gcc中使用内联汇编的调用方法

c++ - Qt5右上角QMenuBar中如何设置按钮?

qt5 - windows下为android构建qt5.1.1的qt3d