Jak radzić sobie z awarią silnika V8, gdy zabraknie pamięci w procesie
Obiewęzeł konsola i oparte na V8 Qt5QJSEngine
może zostać rozbity przez następujący kod:
a = []; for (;;) { a.push("hello"); }
wyjście węzła przed awarią:
FATAL ERROR: JS Allocation failed - process out of memory
QJSEngine
wyjście przed awarią:
#
# Fatal error in JS
# Allocation failed - process out of memory
#
Jeśli uruchomię mójQJSEngine
aplikacja testowa (patrz poniżej) pod debuggerem, pokazuje av8::internal::OS::DebugBreak
zadzwoń do kodu V8. Jeśli otworzę wywołanie koduQJSEngine::evaluate
w__try-__except
(SEH), wtedy aplikacja nie ulegnie awarii, ale to rozwiązanie jest specyficzne dla systemu Windows.
Pytanie: Czy istnieje sposób, aby sobie z tym poradzićv8::internal::OS::DebugBreak
w sposób niezależny od platformy w aplikacjach węzłowych i Qt?
=== Kod testu QJSEngine ===
Środowisko programistyczne: QtCreator z Qt5 i Windows SDK 7.1, w systemie Windows XP SP3
QJSEngineTest.pro:
TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest
main.cpp bez SEH (spowoduje to awarię):
#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 z SEH (to się nie zawiedzie, wyświetla „wyjątek krytyczny”):
#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;
}