Beide node Konsole und QT5 V8-basierte QJSEngine
durch den folgenden Code zum Absturz gebracht werden kann:Wie V8-Motor Absturz zu handhaben, wenn Prozess
a = []; for (;;) { a.push("hello"); }
Ausgang des Knotens vor Absturz:
FATAL ERROR: JS Allocation failed - process out of memory
QJSEngine
‚s Ausgabe vor dem Absturz:
#
# Fatal error in JS
# Allocation failed - process out of memory
#
Wenn Ich starte meine QJSEngine
Test-App (siehe unten) unter einem Debugger, es zeigt einen v8::internal::OS::DebugBreak
Aufruf innerhalb des V8-Codes. Wenn ich den Code, der QJSEngine::evaluate
aufruft, in __try-__except
(SEH) verpacken, wird die App nicht abstürzen, aber diese Lösung ist Windows-spezifisch.
Frage: Gibt es eine Möglichkeit v8::internal::OS::DebugBreak
in einer Plattform-unabhängigen Weise in Knoten- und Qt-Anwendungen zu behandeln?
=== QJSEngine Testcode ===
Entwicklungsumgebung: QtCreator mit QT5 und Windows SDK 7.1, auf Windows XP SP3
QJSEngineTest.pro:
TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest
Haupt .cpp ohne SEH (dies stürzt ab):
#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;
}
main.cpp mit SEH (dies wird nicht abstürzen, gibt „Fatal Exception“):
#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;
}
Beachten Sie außerdem, dass Sie einen Rückruf kurz vor dem Abbruch mithilfe von V8 :: SetFatalErrorHandler() registrieren können. Dies bietet Ihnen jedoch weiterhin nicht die Möglichkeit, den v8-Stapel abzuwickeln. Sie können OS :: Abort() auch mit --no-hard_abort steuern, damit der Prozess ruhig (SIGABRT) und nicht mit einer Zugriffsverletzung (V8_IMMEDIATE_CRASH()) beendet wird. (Ich bin mir nicht sicher, unter welchen Umständen DebugBreak() aufgerufen wird - möglicherweise nur, wenn ein Debugger angehängt ist.) –