Sia console node e di QT5 V8-based QJSEngine
può essere precipitato dal codice seguente: uscitaCome gestire crash del motore V8 quando processo esaurisce la memoria
a = []; for (;;) { a.push("hello"); }
del nodo prima di schianto:
FATAL ERROR: JS Allocation failed - process out of memory
uscita
QJSEngine
's prima schianto:
#
# Fatal error in JS
# Allocation failed - process out of memory
#
Se Corro la mia app di test QJSEngine
(vedi sotto) sotto un debugger, mostra una chiamata v8::internal::OS::DebugBreak
all'interno del codice V8. Se avvolgo il codice chiamando QJSEngine::evaluate
in __try-__except
(SEH), l'app non si arresta in modo anomalo, ma questa soluzione è specifica per Windows.
Domanda: Esiste un modo per gestire v8::internal::OS::DebugBreak
in un modo indipendente dalla piattaforma in applicazioni nodi e Qt?
=== === codice di prova QJSEngine
Ambiente di sviluppo: QtCreator con QT5 e Windows SDK 7.1, su Windows XP SP3
QJSEngineTest.pro:
TEMPLATE = app
QT -= gui
QT += core qml
CONFIG -= app_bundle
CONFIG += console
SOURCES += main.cpp
TARGET = QJSEngineTest
principale .cpp senza SEH (questo si bloccherà):
#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 con SEH (questo non collasserà, uscite "eccezione irreversibile"):
#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;
}
Si noti inoltre che è possibile registrare una richiamata prima di interrompere utilizzando V8 :: SetFatalErrorHandler(), sebbene questo non permetta di rilassarsi lo stack v8. Puoi anche controllare OS :: Abort() con --no-hard_abort per far uscire il processo in modo silenzioso (SIGABRT) piuttosto che con una violazione di accesso (V8_IMMEDIATE_CRASH()). (Non sono sicuro in quali circostanze viene richiamato DebugBreak() - può essere solo quando è collegato un debugger.) –