diff options
| author | Antti Määttä <antti.maatta@qt.io> | 2022-10-24 11:30:56 +0300 |
|---|---|---|
| committer | Antti Määttä <antti.maatta@qt.io> | 2023-01-13 12:43:46 +0200 |
| commit | e3458aac6406e5b624cd54e28b5784fb09f07bc3 (patch) | |
| tree | 7d91c7015b03d984a78f6ceb90ae82a89611d887 /src/corelib/tracing/qctf.cpp | |
| parent | a37a59eea8b010c45da1722a005946a2450363b3 (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.cpp | 119 |
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 |
