-
Notifications
You must be signed in to change notification settings - Fork 176
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -255,6 +255,7 @@ | |
#include "AboutUtil.h" | ||
#include "ExternalResource.h" | ||
#include <ThreadHelpers.h> | ||
#include "ScriptEngineLoggingAgent.h" | ||
|
||
#if defined(Q_OS_WIN) | ||
#include <VersionHelpers.h> | ||
|
@@ -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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Good point, I'll look into it. |
||
} | ||
|
||
bool Application::canAcceptURL(const QString& urlString) const { | ||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,52 @@ | ||||||||||
// | ||||||||||
// ScriptEngineLoggingAgent.cpp | ||||||||||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
// | ||||||||||
// Distributed under the Apache License, Version 2.0. | ||||||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||||||||||
// | ||||||||||
|
||||||||||
#include "ScriptEngineLoggingAgent.h" | ||||||||||
#include "ScriptContextHelper.h" | ||||||||||
#include <QObject> | ||||||||||
#include <QScriptEngine> | ||||||||||
#include <QDebug> | ||||||||||
#include <QLoggingCategory> | ||||||||||
#include <QScriptContextInfo> | ||||||||||
|
||||||||||
Q_LOGGING_CATEGORY(script_logger, "vircadia.script-engine.logging-agent") | ||||||||||
|
||||||||||
|
||||||||||
ScriptEngineLoggingAgent::ScriptEngineLoggingAgent(QScriptEngine *engine) : QScriptEngineAgent(engine) { | ||||||||||
|
||||||||||
} | ||||||||||
|
||||||||||
void ScriptEngineLoggingAgent::functionEntry(qint64 scriptId) { | ||||||||||
if ( scriptId != -1) { | ||||||||||
Comment on lines
+27
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
// We only care about non-native functions | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
QStringList backtrace; | ||||||||||
if (_lock.try_lock()) { | ||||||||||
// We may end up calling ourselves through backtrace(). In such a case, do nothing to avoid | ||||||||||
// getting into an infinite loop. | ||||||||||
backtrace = engine()->currentContext()->backtrace(); | ||||||||||
_lock.unlock(); | ||||||||||
} | ||||||||||
|
||||||||||
ScriptContextHelper::push( backtrace ); | ||||||||||
} | ||||||||||
|
||||||||||
void ScriptEngineLoggingAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) { | ||||||||||
if ( scriptId != -1) { | ||||||||||
Comment on lines
+44
to
+45
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
// We only care about non-native functions | ||||||||||
return; | ||||||||||
} | ||||||||||
|
||||||||||
ScriptContextHelper::pop(); | ||||||||||
} | ||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,35 @@ | ||||||||||
// | ||||||||||
// ScriptEngineLoggingAgent.h | ||||||||||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
// | ||||||||||
// Distributed under the Apache License, Version 2.0. | ||||||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||||||||||
// | ||||||||||
|
||||||||||
#ifndef vircadia_ScriptEngineLoggingAgent_h | ||||||||||
#define vircadia_ScriptEngineLoggingAgent_h | ||||||||||
|
||||||||||
#include <QObject> | ||||||||||
#include <QStringList> | ||||||||||
#include <QScriptEngineAgent> | ||||||||||
#include <QThreadStorage> | ||||||||||
#include <QLoggingCategory> | ||||||||||
#include <mutex> | ||||||||||
|
||||||||||
Q_DECLARE_LOGGING_CATEGORY(script_logger) | ||||||||||
|
||||||||||
|
||||||||||
|
||||||||||
class ScriptEngineLoggingAgent : public QScriptEngineAgent { | ||||||||||
public: | ||||||||||
ScriptEngineLoggingAgent(QScriptEngine *engine); | ||||||||||
virtual void functionEntry(qint64 scriptId) override; | ||||||||||
virtual void functionExit(qint64 scriptId, const QScriptValue &returnValue) override; | ||||||||||
Comment on lines
+29
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
private: | ||||||||||
std::mutex _lock; | ||||||||||
}; | ||||||||||
|
||||||||||
#endif |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -28,6 +28,7 @@ | |||||
#include <QtCore/QMutexLocker> | ||||||
#include <QtCore/QThread> | ||||||
#include <QtCore/QTimer> | ||||||
#include "ScriptContextHelper.h" | ||||||
|
||||||
QMutex LogHandler::_mutex(QMutex::Recursive); | ||||||
|
||||||
|
@@ -209,6 +210,21 @@ QString LogHandler::printMessage(LogMsgType type, const QMessageLogContext& cont | |||||
fprintf(stdout, "[Previous message was repeated %i times]\n", _repeatCount); | ||||||
} | ||||||
|
||||||
if (context.category && strcmp(context.category, "vircadia.script-engine.logging-agent") != 0 ) { | ||||||
QStringList context = ScriptContextHelper::get(); | ||||||
if ( !context.isEmpty()) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#ifdef Q_OS_WIN | ||||||
OutputDebugStringA(qPrintable(QString("Script context:\n"))); | ||||||
#endif | ||||||
fprintf(stdout, "Script context:\n"); | ||||||
for( auto line : context) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
fprintf(stdout, "\t%s\n", line.toStdString().c_str()); | ||||||
#ifdef Q_OS_WIN | ||||||
OutputDebugStringA(qPrintable(line)); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#endif | ||||||
} | ||||||
} | ||||||
} | ||||||
fprintf(stdout, "%s%s%s", color, qPrintable(logMessage), resetColor); | ||||||
_repeatCount = 0; | ||||||
} else { | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,45 @@ | ||||||
// | ||||||
// ScriptContextHelper.cpp | ||||||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
// | ||||||
// Distributed under the Apache License, Version 2.0. | ||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||||||
// | ||||||
|
||||||
#include "ScriptContextHelper.h" | ||||||
|
||||||
QThreadStorage<QList<QStringList>> ScriptContextHelper::_context; | ||||||
|
||||||
void ScriptContextHelper::push(QStringList context) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
QList<QStringList> data = _context.localData(); | ||||||
|
||||||
data.append(context); | ||||||
|
||||||
_context.setLocalData(data); | ||||||
} | ||||||
|
||||||
QStringList ScriptContextHelper::get() { | ||||||
QList<QStringList> data = _context.localData(); | ||||||
|
||||||
if ( data.isEmpty() ) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
return QStringList(); | ||||||
} else { | ||||||
return data.last(); | ||||||
} | ||||||
|
||||||
//return _context.localData(); | ||||||
Comment on lines
+32
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} | ||||||
|
||||||
void ScriptContextHelper::pop() { | ||||||
QList<QStringList> data = _context.localData(); | ||||||
|
||||||
if (!data.isEmpty()) { | ||||||
data.removeLast(); | ||||||
} | ||||||
|
||||||
_context.setLocalData(data); | ||||||
} | ||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,31 @@ | ||||||
// | ||||||
// ScriptContextHelper.h | ||||||
// 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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
// | ||||||
// Distributed under the Apache License, Version 2.0. | ||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | ||||||
// | ||||||
|
||||||
#ifndef vircadia_ScriptContextHelper_h | ||||||
#define vircadia_ScriptContextHelper_h | ||||||
|
||||||
#include <QObject> | ||||||
#include <QStringList> | ||||||
#include <QThreadStorage> | ||||||
#include <QList> | ||||||
|
||||||
|
||||||
class ScriptContextHelper { | ||||||
public: | ||||||
static void push(QStringList context); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
static QStringList get(); | ||||||
static void pop(); | ||||||
|
||||||
private: | ||||||
static QThreadStorage<QList<QStringList>> _context; | ||||||
}; | ||||||
|
||||||
#endif |
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.