-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Obtain script backtrace when a log event is generated in C++ code #1156
base: master
Are you sure you want to change the base?
Conversation
Okay, less broken attempt. This shouldn't crash anymore. |
The following links are available:
build (macOS-latest, full) build (windows-latest, full) build (ubuntu-18.04, android) |
Suggestions:
|
@@ -7652,6 +7653,9 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine | |||
connect(scriptEngine.data(), &ScriptEngine::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage); | |||
connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, scriptEngines, &ScriptEngines::onClearDebugWindow); | |||
|
|||
|
|||
ScriptEngineLoggingAgent *scriptLogger = new ScriptEngineLoggingAgent(scriptEngine.data()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ScriptEngineLoggingAgent *scriptLogger = new ScriptEngineLoggingAgent(scriptEngine.data()); | |
ScriptEngineLoggingAgent* scriptLogger = new ScriptEngineLoggingAgent(scriptEngine.data()); |
// script-engine/src | ||
// | ||
// Created by Dale Glass on 04/04/2021. | ||
// Copyright 2021 Vircadia Contributors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright 2021 Vircadia Contributors | |
// Copyright 2021 Vircadia contributors. |
void ScriptEngineLoggingAgent::functionEntry(qint64 scriptId) { | ||
if ( scriptId != -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void ScriptEngineLoggingAgent::functionEntry(qint64 scriptId) { | |
if ( scriptId != -1) { | |
void ScriptEngineLoggingAgent::functionEntry(qint64 scriptID) { | |
if (scriptID != -1) { |
void ScriptEngineLoggingAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) { | ||
if ( scriptId != -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void ScriptEngineLoggingAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) { | |
if ( scriptId != -1) { | |
void ScriptEngineLoggingAgent::functionExit(qint64 scriptID, const QScriptValue& returnValue) { | |
if (scriptID != -1) { |
// script-engine/src | ||
// | ||
// Created by Dale Glass on 04/04/2021. | ||
// Copyright 2021 Vircadia Contributors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright 2021 Vircadia Contributors | |
// Copyright 2021 Vircadia contributors. |
QStringList ScriptContextHelper::get() { | ||
QList<QStringList> data = _context.localData(); | ||
|
||
if ( data.isEmpty() ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ( data.isEmpty() ) { | |
if (data.isEmpty()) { |
|
||
//return _context.localData(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//return _context.localData(); |
// shared/src | ||
// | ||
// Created by Dale Glass on 04/04/2021. | ||
// Copyright 2021 Vircadia Contributors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Copyright 2021 Vircadia Contributors | |
// Copyright 2021 Vircadia contributors. |
|
||
class ScriptContextHelper { | ||
public: | ||
static void push(QStringList context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static void push(QStringList context); | |
static void push(const QStringList& context); |
|
||
QThreadStorage<QList<QStringList>> ScriptContextHelper::_context; | ||
|
||
void ScriptContextHelper::push(QStringList context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
void ScriptContextHelper::push(QStringList context) { | |
void ScriptContextHelper::push(const QStringList& context) { |
@@ -7652,6 +7653,9 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine | |||
connect(scriptEngine.data(), &ScriptEngine::infoMessage, scriptEngines, &ScriptEngines::onInfoMessage); | |||
connect(scriptEngine.data(), &ScriptEngine::clearDebugWindow, scriptEngines, &ScriptEngines::onClearDebugWindow); | |||
|
|||
|
|||
ScriptEngineLoggingAgent *scriptLogger = new ScriptEngineLoggingAgent(scriptEngine.data()); | |||
scriptEngine->setAgent(scriptLogger); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with david that it would be good to disable this by default so it doesn’t affect the performance of normal scripts. it seems like it adds overhead to every single function call.
I also wonder, is this agent automatically deleted when the script engine dies? what about the associated thread local storage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I'll look into it.
Okay, finally reviewed this after needing to to so for... a while. My thoughts...
|
I'm still having an eye towards this, especially after #1200 lands (which does use at least part of the technique described here). The only part of the patch I'm interested in here for surviving are the changes to libraries/shared/src/LogHandler.cpp, however I'm unsure how this would work as I'm trying to avoid adding dependencies from shared to script-engine |
Hello! Is this still an issue? |
This is a very, very early prototype and doesn't work. Here's the overall idea:
When a C++ function logs something, such as:
We want to figure out where that came from. Which script resulted in this function being called? And this works to some extent:
The problem is that a problem can be found at any arbitrary depth, not just in whatever QScriptEngine calls directly. So I figured out a way around that. Qt has the
QScriptEngineAgent
, which allows us invoke code at interesting points, such as script function calls, including calls to native code.So the idea is:
Unfortunately it doesn't quite work. Problems:
So far this is extremely half-baked and guaranteed to run out of stack space right on start due to that last problem. Some help here would be extremely appreciated.