node控制台和Qt5的基于V8的
QJSEngine
都可以通过以下代码崩溃:
a = []; for (;;) { a.push("hello"); }
崩溃前节点的输出:
Fatal error: JS Allocation Failed - process out of memory
# # Fatal error in JS # Allocation Failed - process out of memory #
如果我在调试器下运行我的qjsengine测试应用程序(见下文),它会在V8代码中显示v8::internal::OS::DebugBreak
调用.如果我将调用qjsengine :: evaluate的代码包装到__try -__(SEH)之外,那么应用程序不会崩溃,但此解决方案是特定于Windows的.
问题:有没有办法在节点和Qt应用程序中以独立于平台的方式处理v8 :: internal :: OS :: DebugBreak?
开发环境:QtCreator,Qt5和Windows SDK 7.1,在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致命错误,但即使有,或者如果有某种方法将它们捕获到你关心的所有平台上,我也不确定那会给你带来什么.
问题是V8使用global flag来记录是否发生了致命错误.一旦设置了该标志,V8将拒绝任何创建新JavaScript上下文的尝试,因此无论如何都没有必要继续.在捕获最初的致命错误后尝试执行一些良性JavaScript代码.如果我是对的,你马上就会得到另一个致命的错误.
在我看来,正确的是Node和Qt将V8配置为不首先引发致命错误.既然V8支持隔离和内存约束,那么杀死致命错误的进程就不再合适了.不幸的是,看起来V8的错误处理代码还没有完全支持这些较新的功能,并且仍然假设内存不足的情况总是无法恢复的.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。