summaryrefslogtreecommitdiffstats
path: root/src/corelib/tracing/qctf.cpp
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2022-10-24 11:30:56 +0300
committerAntti Määttä <antti.maatta@qt.io>2023-01-13 12:43:46 +0200
commite3458aac6406e5b624cd54e28b5784fb09f07bc3 (patch)
tree7d91c7015b03d984a78f6ceb90ae82a89611d887 /src/corelib/tracing/qctf.cpp
parenta37a59eea8b010c45da1722a005946a2450363b3 (diff)
Add CTF tracing backend
Implement platform independent tracing backend in Common trace format. This allows tracing in platforms without own/existing backend and analysing all platforms with the same tooling. The backend is the basis for further work in application level profiling area. The backend is implemented as a plugin that is loaded immediately when the application starts in order to process all trace events. The backend avoids using Qt classes so that it doesn't generate trace events itself. Adds plumbing to configure the new backend. Modifies the tracegen and tracepointgen tools to support the new backend. Task-number: QTBUG-106399 Pick-to: 6.5 Change-Id: I80711be52d4d48e1acbc72edffbdf3f379fce52a Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/corelib/tracing/qctf.cpp')
-rw-r--r--src/corelib/tracing/qctf.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/corelib/tracing/qctf.cpp b/src/corelib/tracing/qctf.cpp
new file mode 100644
index 00000000000..22bb587acd4
--- /dev/null
+++ b/src/corelib/tracing/qctf.cpp
@@ -0,0 +1,119 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#define BUILD_LIBRARY
+
+#include <qthread.h>
+#include <qpluginloader.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+
+#include "qctflib_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static bool s_initialized = false;
+static bool s_triedLoading = false;
+static bool s_prevent_recursion = false;
+static QCtfLib* s_plugin = nullptr;
+
+#if defined(Q_OS_ANDROID)
+static QString findPlugin(const QString &plugin)
+{
+ QString pluginPath = QString::fromUtf8(qgetenv("QT_PLUGIN_PATH"));
+ QDir dir(pluginPath);
+ const QStringList files = dir.entryList(QDir::Files);
+ for (const QString &file : files) {
+ if (file.contains(plugin))
+ return QFileInfo(pluginPath + QLatin1Char('/') + file).absoluteFilePath();
+ }
+ return {};
+}
+#endif
+
+static bool loadPlugin(bool &retry)
+{
+ retry = false;
+#ifdef Q_OS_WIN
+#ifdef QT_DEBUG
+ QPluginLoader loader(QStringLiteral("tracing/QCtfTracePlugind.dll"));
+#else
+ QPluginLoader loader(QStringLiteral("tracing/QCtfTracePlugin.dll"));
+#endif
+#elif defined(Q_OS_ANDROID)
+
+ QString plugin = findPlugin(QStringLiteral("QCtfTracePlugin"));
+ if (plugin.isEmpty()) {
+ retry = true;
+ return false;
+ }
+ QPluginLoader loader(plugin);
+#else
+ QPluginLoader loader(QStringLiteral("tracing/libQCtfTracePlugin.so"));
+#endif
+
+ if (!loader.isLoaded()) {
+ if (!loader.load())
+ return false;
+ }
+ s_plugin = qobject_cast<QCtfLib *>(loader.instance());
+ if (!s_plugin)
+ return false;
+ QObject *obj = loader.instance();
+ if (obj) {
+ QObject::connect(obj, &QObject::destroyed, []() {
+ s_plugin = nullptr;
+ });
+ }
+ return true;
+}
+
+static bool initialize()
+{
+ if (s_prevent_recursion)
+ return false;
+ if (s_initialized || s_triedLoading)
+ return s_initialized;
+ s_prevent_recursion = true;
+ bool retry = false;
+ if (!loadPlugin(retry)) {
+ if (!retry) {
+ s_triedLoading = true;
+ s_initialized = false;
+ }
+ } else {
+ bool enabled = s_plugin->sessionEnabled();
+ if (!enabled) {
+ s_triedLoading = true;
+ s_initialized = false;
+ } else {
+ s_initialized = true;
+ }
+ }
+ s_prevent_recursion = false;
+ return s_initialized;
+}
+
+bool _tracepoint_enabled(const QCtfTracePointEvent &point)
+{
+ if (!initialize())
+ return false;
+ return s_plugin ? s_plugin->tracepointEnabled(point) : false;
+}
+
+void _do_tracepoint(const QCtfTracePointEvent &point, const QByteArray &arr)
+{
+ if (!initialize())
+ return;
+ if (s_plugin)
+ s_plugin->doTracepoint(point, arr);
+}
+
+QCtfTracePointPrivate *_initialize_tracepoint(const QCtfTracePointEvent &point)
+{
+ if (!initialize())
+ return nullptr;
+ return s_plugin ? s_plugin->initializeTracepoint(point) : nullptr;
+}
+
+QT_END_NAMESPACE