Added more debug info to crash with signals

This commit is contained in:
ksuprynowicz 2023-01-29 21:39:41 +01:00
parent 3e692a60b4
commit b786ffccd5
2 changed files with 45 additions and 29 deletions

View file

@ -393,7 +393,13 @@ ScriptEngineV8::ScriptEngineV8(ScriptManager* scriptManager) :
// //
// Based on that, going with 256K for stacks for now. That seems like a reasonable value. // Based on that, going with 256K for stacks for now. That seems like a reasonable value.
// We'll probably need a more complex system on the longer term, with configurable limits. // We'll probably need a more complex system on the longer term, with configurable limits.
// Flags to try:
// V8TODO --single-threaded is to check if it fixes random crashes
// --jitless - might improve debugging performance due to no JIT?
// --assert-types
v8::V8::SetFlagsFromString("--stack-size=256"); v8::V8::SetFlagsFromString("--stack-size=256");
//v8::V8::SetFlagsFromString("--stack-size=256 --single-threaded");
v8::Platform* platform = getV8Platform(); v8::Platform* platform = getV8Platform();
v8::V8::InitializePlatform(platform); v8::V8::InitializePlatform(platform);
v8::V8::Initialize(); qCDebug(scriptengine) << "V8 platform initialized"; v8::V8::Initialize(); qCDebug(scriptengine) << "V8 platform initialized";

View file

@ -673,7 +673,7 @@ void ScriptMethodV8Proxy::callback(const v8::FunctionCallbackInfo<v8::Value>& ar
v8::Locker locker(arguments.GetIsolate()); v8::Locker locker(arguments.GetIsolate());
v8::Isolate::Scope isolateScope(arguments.GetIsolate()); v8::Isolate::Scope isolateScope(arguments.GetIsolate());
v8::HandleScope handleScope(arguments.GetIsolate()); v8::HandleScope handleScope(arguments.GetIsolate());
Q_ASSERT(!arguments.GetIsolate()->GetCurrentContext().IsEmpty()); //Q_ASSERT(!arguments.GetIsolate()->GetCurrentContext().IsEmpty());
v8::Context::Scope contextScope(arguments.GetIsolate()->GetCurrentContext()); v8::Context::Scope contextScope(arguments.GetIsolate()->GetCurrentContext());
if (!arguments.Data()->IsObject()) { if (!arguments.Data()->IsObject()) {
arguments.GetIsolate()->ThrowError("Method value is not an object"); arguments.GetIsolate()->ThrowError("Method value is not an object");
@ -1082,40 +1082,50 @@ int ScriptSignalV8Proxy::qt_metacall(QMetaObject::Call call, int id, void** argu
args[arg] = _engine->castVariantToValue(argValue).get(); args[arg] = _engine->castVariantToValue(argValue).get();
} }
QList<Connection> connections; /*QList<Connection> connections;
withReadLock([&]{ withReadLock([&]{
connections = _connections; connections = _connections;
}); });*/
for (ConnectionList::iterator iter = connections.begin(); iter != connections.end(); ++iter) { withReadLock([&]{
Connection& conn = *iter; //for (ConnectionList::iterator iter = connections.begin(); iter != connections.end(); ++iter) {
Q_ASSERT(!conn.callback.get().IsEmpty()); for (ConnectionList::iterator iter = _connections.begin(); iter != _connections.end(); ++iter) {
Q_ASSERT(!conn.callback.get()->IsUndefined()); Connection& conn = *iter;
Q_ASSERT(conn.callback.get()->IsFunction()); {
{ //auto functionContext = callback->CreationContext();
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(conn.callback.get()); auto functionContext = _v8Context.Get(_engine->getIsolate());
//auto functionContext = callback->CreationContext(); _engine->pushContext(functionContext);
auto functionContext = _v8Context.Get(_engine->getIsolate()); v8::Context::Scope functionContextScope(functionContext);
_engine->pushContext(functionContext);
v8::Context::Scope functionContextScope(functionContext);
v8::Local<v8::Value> v8This; Q_ASSERT(!conn.callback.get().IsEmpty());
if (conn.thisValue.get()->IsObject()) { Q_ASSERT(!conn.callback.get()->IsUndefined());
v8This = conn.thisValue.get(); Q_ASSERT(!conn.callback.get()->IsNull());
} else { if (!conn.callback.get()->IsFunction()) {
v8This = functionContext->Global(); auto stringV8 = conn.callback.get()->ToDetailString(functionContext).ToLocalChecked();
QString error = *v8::String::Utf8Value(_engine->getIsolate(), stringV8);
qDebug() << error;
Q_ASSERT(false);
}
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(conn.callback.get());
v8::Local<v8::Value> v8This;
if (conn.thisValue.get()->IsObject()) {
v8This = conn.thisValue.get();
} else {
v8This = functionContext->Global();
}
v8::TryCatch tryCatch(isolate);
callback->Call(functionContext, v8This, numArgs, args);
if (tryCatch.HasCaught()) {
qCDebug(scriptengine) << "Signal proxy " << fullName() << " connection call failed: \""
<< _engine->formatErrorMessageFromTryCatch(tryCatch)
<< "\nThis provided: " << conn.thisValue.get()->IsObject();
}
_engine->popContext();
} }
v8::TryCatch tryCatch(isolate);
callback->Call(functionContext, v8This, numArgs, args);
if (tryCatch.HasCaught()) {
qCDebug(scriptengine) << "Signal proxy " << fullName() << " connection call failed: \""
<< _engine->formatErrorMessageFromTryCatch(tryCatch)
<< "\nThis provided: " << conn.thisValue.get()->IsObject();
}
_engine->popContext();
} }
} });
return -1; return -1;
} }