summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config_help.txt5
-rw-r--r--mkspecs/features/exclusive_builds.prf4
-rw-r--r--mkspecs/features/qt_build_config.prf1
-rw-r--r--mkspecs/features/qt_tracepoints.prf54
-rw-r--r--src/corelib/configure.json36
-rw-r--r--src/corelib/corelib.pro3
-rw-r--r--src/corelib/global/qconfig-bootstrapped.h2
-rw-r--r--src/corelib/global/qtrace_p.h126
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp10
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp5
-rw-r--r--src/corelib/plugin/qlibrary.cpp6
-rw-r--r--src/corelib/plugin/quuid.cpp4
-rw-r--r--src/corelib/plugin/quuid.h4
-rw-r--r--src/corelib/qtcore.tracepoints5
-rw-r--r--src/gui/gui.pro3
-rw-r--r--src/gui/kernel/qguiapplication.cpp10
-rw-r--r--src/gui/qtgui.tracepoints8
-rw-r--r--src/gui/text/qfontdatabase.cpp10
-rw-r--r--src/src.pro16
-rw-r--r--src/tools/tracegen/etw.cpp228
-rw-r--r--src/tools/tracegen/etw.h48
-rw-r--r--src/tools/tracegen/helpers.cpp92
-rw-r--r--src/tools/tracegen/helpers.h57
-rw-r--r--src/tools/tracegen/lttng.cpp215
-rw-r--r--src/tools/tracegen/lttng.h48
-rw-r--r--src/tools/tracegen/panic.cpp59
-rw-r--r--src/tools/tracegen/panic.h45
-rw-r--r--src/tools/tracegen/provider.cpp304
-rw-r--r--src/tools/tracegen/provider.h95
-rw-r--r--src/tools/tracegen/qtheaders.cpp51
-rw-r--r--src/tools/tracegen/qtheaders.h45
-rw-r--r--src/tools/tracegen/tracegen.cpp109
-rw-r--r--src/tools/tracegen/tracegen.pro21
33 files changed, 1719 insertions, 10 deletions
diff --git a/config_help.txt b/config_help.txt
index 08c2e7627f..5c57e30d63 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -119,6 +119,11 @@ Build options:
-testcocoon .......... Instrument with the TestCocoon code coverage tool [no]
-gcov ................ Instrument with the GCov code coverage tool [no]
+
+ -trace [backend] ..... Enable instrumentation with tracepoints.
+ Currently supported backends are 'etw' (Windows) and
+ 'lttng' (Linux), or 'yes' for auto-detection. [no]
+
-sanitize {address|thread|memory|undefined}
Instrument with the specified compiler sanitizer.
diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf
index f40cc99172..b477cff162 100644
--- a/mkspecs/features/exclusive_builds.prf
+++ b/mkspecs/features/exclusive_builds.prf
@@ -38,5 +38,5 @@ defineTest(addExclusiveBuilds) {
}
# Default directories to process
-QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR
-QMAKE_DIR_REPLACE_SANE += QGLTF_DIR
+QMAKE_DIR_REPLACE = OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR QGLTF_DIR DESTDIR TRACEGEN_DIR
+QMAKE_DIR_REPLACE_SANE += QGLTF_DIR TRACEGEN_DIR
diff --git a/mkspecs/features/qt_build_config.prf b/mkspecs/features/qt_build_config.prf
index 76e1d15319..a2fa1be481 100644
--- a/mkspecs/features/qt_build_config.prf
+++ b/mkspecs/features/qt_build_config.prf
@@ -25,6 +25,7 @@ OBJECTS_DIR = .obj
MOC_DIR = .moc
RCC_DIR = .rcc
UI_DIR = .uic
+TRACEGEN_DIR = .tracegen
intel_icl {
# ICL 14.0 has a bug that makes it not find #includes in dirs starting with .
MOC_DIR = tmp/moc
diff --git a/mkspecs/features/qt_tracepoints.prf b/mkspecs/features/qt_tracepoints.prf
new file mode 100644
index 0000000000..d1b45a47cb
--- /dev/null
+++ b/mkspecs/features/qt_tracepoints.prf
@@ -0,0 +1,54 @@
+# W A R N I N G
+# -------------
+#
+# This file is not part of the Qt API. It exists purely as an
+# implementation detail. It may change from version to version
+# without notice, or even be removed.
+#
+# We mean it.
+#
+
+qtPrepareTool(QMAKE_TRACEGEN, tracegen)
+
+isEmpty(TRACEGEN_DIR): TRACEGEN_DIR = .
+
+PROVIDER_NAME = qt$$lower($$MODULE)
+INCLUDEPATH += $$absolute_path($$TRACEGEN_DIR, $$OUT_PWD)
+HEADER_PATH = $$OUT_PWD/$$TRACEGEN_DIR/$${PROVIDER_NAME}_tracepoints_p$${first(QMAKE_EXT_H)}
+
+!force_bootstrap:if(qtConfig(lttng)|qtConfig(etw)) {
+ SOURCE_PATH = $$OUT_PWD/$$TRACEGEN_DIR/$${PROVIDER_NAME}_tracepoints$${first(QMAKE_EXT_CPP)}
+
+ isEmpty(BUILDS)|build_pass {
+ impl_file_contents = \
+ "$${LITERAL_HASH}define TRACEPOINT_CREATE_PROBES" \
+ "$${LITERAL_HASH}define TRACEPOINT_DEFINE" \
+ "$${LITERAL_HASH}include \"$${HEADER_PATH}\""
+
+ write_file($$SOURCE_PATH, impl_file_contents)|error()
+ }
+
+ GENERATED_SOURCES += $$SOURCE_PATH
+
+ tracegen.input = TRACEPOINT_PROVIDER
+ tracegen.output = $$HEADER_PATH
+ tracegen.variable_out = HEADERS
+ tracegen.depends += $$QMAKE_TRACEGEN_EXE
+ tracegen.CONFIG = target_predeps
+
+ qtConfig(lttng) {
+ tracegen.commands = $$QMAKE_TRACEGEN lttng ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ QMAKE_USE_PRIVATE += lttng-ust
+ } else {
+ tracegen.commands = $$QMAKE_TRACEGEN etw ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
+ }
+
+ QMAKE_EXTRA_COMPILERS += tracegen
+
+ DEFINES += Q_TRACEPOINT
+} else {
+ isEmpty(BUILDS)|build_pass {
+ header_file_contents = "$${LITERAL_HASH}include <private/qtrace_p.h>"
+ write_file($$HEADER_PATH, header_file_contents)|error()
+ }
+}
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 8cd73d6ce4..9f9512942a 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -15,7 +15,8 @@
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
"slog2": "boolean",
- "syslog": "boolean"
+ "syslog": "boolean",
+ "trace": { "type": "optionalString", "values": [ "etw", "lttng", "no", "yes" ] }
}
},
@@ -147,6 +148,18 @@
"-lrt"
]
},
+ "lttng-ust": {
+ "label": "lttng-ust",
+ "test": {
+ "include": "lttng/ust-events.h",
+ "main": "lttng_session_destroy(nullptr);"
+ },
+ "sources": [
+ { "type": "pkgConfig", "args": "lttng-ust" },
+ "-llttng-ust"
+ ],
+ "use": "libdl"
+ },
"pcre2": {
"label": "PCRE2",
"test": {
@@ -858,6 +871,22 @@
"section": "Utilities",
"output": [ "publicFeature" ]
},
+ "lttng": {
+ "label": "LTTNG",
+ "autoDetect": false,
+ "enable": "input.trace == 'lttng' || (input.trace =='yes' && config.linux)",
+ "disable": "input.trace == 'etw' || input.trace =='no'",
+ "condition": "config.linux && libs.lttng-ust",
+ "output": [ "privateFeature" ]
+ },
+ "etw": {
+ "label": "ETW",
+ "autoDetect": false,
+ "enable": "input.trace == 'etw' || (input.trace == 'yes' && config.win32)",
+ "disable": "input.trace == 'lttng' || input.trace == 'no'",
+ "condition": "config.win32",
+ "output": [ "privateFeature" ]
+ },
"topleveldomain": {
"label": "QUrl::topLevelDomain()",
"purpose": "Provides support for extracting the top level domain from URLs.
@@ -908,6 +937,11 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"iconv",
"icu",
{
+ "message": "Tracing backend",
+ "type": "firstAvailableFeature",
+ "args": "etw lttng"
+ },
+ {
"section": "Logging backends",
"entries": [
"journald", "syslog", "slog2"
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 4cce7c0df3..2079d2117f 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -6,6 +6,9 @@ MODULE = core # not corelib, as per project file
MODULE_CONFIG = moc resources
!isEmpty(QT_NAMESPACE): MODULE_DEFINES = QT_NAMESPACE=$$QT_NAMESPACE
+TRACEPOINT_PROVIDER = $$PWD/qtcore.tracepoints
+CONFIG += qt_tracepoints
+
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
diff --git a/src/corelib/global/qconfig-bootstrapped.h b/src/corelib/global/qconfig-bootstrapped.h
index 0df593941d..86ef1a2613 100644
--- a/src/corelib/global/qconfig-bootstrapped.h
+++ b/src/corelib/global/qconfig-bootstrapped.h
@@ -78,6 +78,7 @@
#define QT_FEATURE_cxx11_random (QT_HAS_INCLUDE(<random>) ? 1 : -1)
#define QT_NO_DATASTREAM
#define QT_FEATURE_datetimeparser -1
+#define QT_FEATURE_etw -1
#define QT_FEATURE_getauxval (QT_HAS_INCLUDE(<sys/auxv.h>) ? 1 : -1)
#define QT_FEATURE_getentropy -1
#define QT_NO_GEOM_VARIANT
@@ -92,6 +93,7 @@
#else
# define QT_FEATURE_linkat -1
#endif
+#define QT_FEATURE_lttng -1
#define QT_NO_QOBJECT
#define QT_FEATURE_process -1
#define QT_FEATURE_regularexpression -1
diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h
new file mode 100644
index 0000000000..ab8fc14af5
--- /dev/null
+++ b/src/corelib/global/qtrace_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTRACE_P_H
+#define QTRACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+/*
+ * The Qt tracepoints API consists of only three macros:
+ *
+ * - Q_TRACE(tracepoint, args...)
+ * Fires 'tracepoint' if it is enabled.
+ *
+ * - Q_UNCONDITIONAL_TRACE(tracepoint, args...)
+ * Fires 'tracepoint' unconditionally: no check is performed to query
+ * whether 'tracepoint' is enabled.
+ *
+ * - Q_TRACE_ENABLED(tracepoint)
+ * Returns 'true' if 'tracepoint' is enabled; false otherwise.
+ *
+ * When using LTTNG, Q_TRACE, Q_UNCONDITIONAL_TRACE and Q_TRACE_ENABLED map
+ * ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
+ * respectively, described on the lttng-ust manpage (man 3 lttng-ust).
+ *
+ * On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
+ * amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
+ * wraps around TraceLoggingProviderEnabled().
+ *
+ * A tracepoint provider is defined in a separate file, that follows the
+ * following format:
+ *
+ * tracepoint_name(arg_type arg_name, ...)
+ *
+ * For instance:
+ *
+ * qcoreapplication_ctor(int argc, const char * const argv)
+ * qcoreapplication_foo(int argc, const char[10] argv)
+ * qcoreapplication_baz(const char[len] some_string, unsigned int len)
+ * qcoreapplication_qstring(const QString &foo)
+ * qcoreapplication_qrect(const QRect &rect)
+ *
+ * The provider file is then parsed by src/tools/tracegen, which can be
+ * switched to output either ETW or LTTNG tracepoint definitions. The provider
+ * name is deduced to be basename(provider_file).
+ *
+ * To use the above (inside qtcore), you need to include
+ * <providername_tracepoints_p.h>. After that, the following call becomes
+ * possible:
+ *
+ * Q_TRACE(qcoreapplication_qrect, myRect);
+ *
+ * Currently, all C++ primitive non-pointer types are supported for
+ * arguments. Additionally, char * is supported, and is assumed to
+ * be a NULL-terminated string. Finally, the following subset of Qt types also
+ * currently supported:
+ *
+ * - QString
+ * - QByteArray
+ * - QUrl
+ * - QRect
+ *
+ * Dynamic arrays are supported using the syntax illustrated by
+ * qcoreapplication_baz above.
+ */
+
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
+# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
+# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
+# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
+#else
+# define Q_TRACE(x, ...)
+# define Q_UNCONDITIONAL_TRACE(x, ...)
+# define Q_TRACE_ENABLED(x) false
+#endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
+
+QT_END_NAMESPACE
+
+#endif // QTRACE_P_H
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e93a14c116..4bab0b9f01 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -116,6 +116,12 @@
# include <taskLib.h>
#endif
+#ifdef QT_BOOTSTRAPPED
+#include <private/qtrace_p.h>
+#else
+#include <qtcore_tracepoints_p.h>
+#endif
+
#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -790,6 +796,8 @@ QCoreApplication::QCoreApplication(int &argc, char **argv
void QCoreApplicationPrivate::init()
{
+ Q_TRACE(qcoreapplicationprivate_init_entry);
+
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
#endif
@@ -873,6 +881,8 @@ void QCoreApplicationPrivate::init()
#ifndef QT_NO_QOBJECT
is_app_running = true; // No longer starting up.
#endif
+
+ Q_TRACE(qcoreapplicationprivate_init_exit);
}
/*!
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 0cc193c325..a4be18a67f 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -54,6 +54,8 @@
#include "qjsonobject.h"
#include "qjsonarray.h"
+#include <qtcore_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
class QFactoryLoaderPrivate : public QObjectPrivate
@@ -142,6 +144,9 @@ void QFactoryLoader::update()
if (qt_debug_component()) {
qDebug() << "QFactoryLoader::QFactoryLoader() looking at" << fileName;
}
+
+ Q_TRACE(qfactoryloader_update, fileName);
+
library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
if (!library->isPlugin()) {
if (qt_debug_component()) {
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index ebad7f1751..bca6918b4a 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -64,6 +64,8 @@
#include "qelfparser_p.h"
#include "qmachparser_p.h"
+#include <qtcore_tracepoints_p.h>
+
QT_BEGIN_NAMESPACE
#ifdef QT_NO_DEBUG
@@ -535,6 +537,8 @@ bool QLibraryPrivate::load()
if (fileName.isEmpty())
return false;
+ Q_TRACE(qlibraryprivate_load_entry, fileName);
+
bool ret = load_sys();
if (qt_debug_component()) {
if (ret) {
@@ -551,6 +555,8 @@ bool QLibraryPrivate::load()
installCoverageTool(this);
}
+ Q_TRACE(qlibraryprivate_load_exit, ret);
+
return ret;
}
diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp
index 3a1c0495fe..5dfbf23c33 100644
--- a/src/corelib/plugin/quuid.cpp
+++ b/src/corelib/plugin/quuid.cpp
@@ -143,7 +143,6 @@ static QUuid _q_uuidFromHex(const char *src)
return QUuid();
}
-#ifndef QT_BOOTSTRAPPED
static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCryptographicHash::Algorithm algorithm, int version)
{
QByteArray hashResult;
@@ -166,7 +165,6 @@ static QUuid createFromName(const QUuid &ns, const QByteArray &baseData, QCrypto
return result;
}
-#endif
/*!
\class QUuid
@@ -488,12 +486,12 @@ QUuid QUuid::createUuidV3(const QUuid &ns, const QByteArray &baseData)
{
return createFromName(ns, baseData, QCryptographicHash::Md5, 3);
}
+#endif
QUuid QUuid::createUuidV5(const QUuid &ns, const QByteArray &baseData)
{
return createFromName(ns, baseData, QCryptographicHash::Sha1, 5);
}
-#endif
/*!
Creates a QUuid object from the binary representation of the UUID, as
diff --git a/src/corelib/plugin/quuid.h b/src/corelib/plugin/quuid.h
index ee0a9f9dac..014b69831e 100644
--- a/src/corelib/plugin/quuid.h
+++ b/src/corelib/plugin/quuid.h
@@ -192,18 +192,20 @@ public:
static QUuid createUuid();
#ifndef QT_BOOTSTRAPPED
static QUuid createUuidV3(const QUuid &ns, const QByteArray &baseData);
+#endif
static QUuid createUuidV5(const QUuid &ns, const QByteArray &baseData);
+#ifndef QT_BOOTSTRAPPED
static inline QUuid createUuidV3(const QUuid &ns, const QString &baseData)
{
return QUuid::createUuidV3(ns, baseData.toUtf8());
}
+#endif
static inline QUuid createUuidV5(const QUuid &ns, const QString &baseData)
{
return QUuid::createUuidV5(ns, baseData.toUtf8());
}
-#endif
QUuid::Variant variant() const Q_DECL_NOTHROW;
QUuid::Version version() const Q_DECL_NOTHROW;
diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints
new file mode 100644
index 0000000000..e6b666ac74
--- /dev/null
+++ b/src/corelib/qtcore.tracepoints
@@ -0,0 +1,5 @@
+qcoreapplicationprivate_init_entry()
+qcoreapplicationprivate_init_exit()
+qfactoryloader_update(const QString &fileName)
+qlibraryprivate_load_entry(const QString &fileName)
+qlibraryprivate_load_exit(bool success)
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index f8cec00b82..759d6f3cbf 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -95,3 +95,6 @@ qtConfig(angle) {
qtConfig(egl): CMAKE_EGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_EGL)
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtGui.dynlist
+
+TRACEPOINT_PROVIDER = $$PWD/qtgui.tracepoints
+CONFIG += qt_tracepoints
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 3d85f47f34..70b4869442 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -111,6 +111,8 @@
# include <QtCore/QLibraryInfo>
#endif // Q_OS_WIN
+#include <qtgui_tracepoints_p.h>
+
#include <ctype.h>
QT_BEGIN_NAMESPACE
@@ -1360,6 +1362,8 @@ void QGuiApplicationPrivate::eventDispatcherReady()
void QGuiApplicationPrivate::init()
{
+ Q_TRACE(qguiapplicationprivate_init_entry);
+
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
#endif
@@ -1522,6 +1526,8 @@ void QGuiApplicationPrivate::init()
if (!QGuiApplicationPrivate::displayName)
QObject::connect(q, &QGuiApplication::applicationNameChanged,
q, &QGuiApplication::applicationDisplayNameChanged);
+
+ Q_TRACE(qguiapplicationprivate_init_exit);
}
extern void qt_cleanupFontDatabase();
@@ -1756,6 +1762,8 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra
void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e)
{
+ Q_TRACE(qguiapplicationprivate_processwsevents_entry, e->type);
+
switch(e->type) {
case QWindowSystemInterfacePrivate::Mouse:
QGuiApplicationPrivate::processMouseEvent(static_cast<QWindowSystemInterfacePrivate::MouseEvent *>(e));
@@ -1864,6 +1872,8 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
qWarning() << "Unknown user input event type:" << e->type;
break;
}
+
+ Q_TRACE(qguiapplicationprivate_processwsevents_exit, e->type);
}
/*! \internal
diff --git a/src/gui/qtgui.tracepoints b/src/gui/qtgui.tracepoints
new file mode 100644
index 0000000000..aa8a8ede57
--- /dev/null
+++ b/src/gui/qtgui.tracepoints
@@ -0,0 +1,8 @@
+qfontdatabase_addapplicationfont(const QString &filename)
+qfontdatabase_load(const QString &family, int pointSize)
+qfontdatabase_loadengine(const QString &family, int pointSize)
+qfontdatabaseprivate_addappfont(const QString &fileName)
+qguiapplicationprivate_init_entry()
+qguiapplicationprivate_init_exit()
+qguiapplicationprivate_processwsevents_entry(int type)
+qguiapplicationprivate_processwsevents_exit(int type)
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 4be2197c68..404a722e29 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -74,6 +74,7 @@
# define FM_DEBUG if (false) qDebug
#endif
+#include <qtgui_tracepoints_p.h>
QT_BEGIN_NAMESPACE
@@ -1009,6 +1010,8 @@ QFontEngine *loadEngine(int script, const QFontDef &request,
QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size);
if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) {
+ Q_TRACE(qfontdatabase_loadengine, request.family, request.pointSize);
+
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script));
if (!request.fallBackFamilies.isEmpty()) {
@@ -2439,6 +2442,8 @@ int QFontDatabasePrivate::addAppFont(const QByteArray &fontData, const QString &
font.data = fontData;
font.fileName = fileName;
+ Q_TRACE(qfontdatabaseprivate_addappfont, fileName);
+
int i;
for (i = 0; i < applicationFonts.count(); ++i)
if (applicationFonts.at(i).families.isEmpty())
@@ -2494,6 +2499,9 @@ int QFontDatabase::addApplicationFont(const QString &fileName)
QFile f(fileName);
if (!f.open(QIODevice::ReadOnly))
return -1;
+
+ Q_TRACE(qfontdatabase_addapplicationfont, fileName);
+
data = f.readAll();
}
QMutexLocker locker(fontDatabaseMutex());
@@ -2792,6 +2800,8 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
QFontEngine *fe = nullptr;
+ Q_TRACE(qfontdatabase_load, req.family, req.pointSize);
+
req.fallBackFamilies = fallBackFamilies;
if (!req.fallBackFamilies.isEmpty())
req.family = req.fallBackFamilies.takeFirst();
diff --git a/src/src.pro b/src/src.pro
index a2064b1362..3b93b1a9d8 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
-QT_FOR_CONFIG += gui-private
+QT_FOR_CONFIG += core-private gui-private
include($$OUT_PWD/corelib/qtcore-config.pri)
include($$OUT_PWD/gui/qtgui-config.pri)
@@ -30,6 +30,10 @@ src_tools_qlalr.target = sub-qlalr
force_bootstrap: src_tools_qlalr.depends = src_tools_bootstrap
else: src_tools_qlalr.depends = src_corelib
+src_tools_tracegen.subdir = tools/tracegen
+src_tools_tracegen.target = sub-tracegen
+src_tools_tracegen.depends = src_tools_bootstrap
+
src_tools_uic.subdir = tools/uic
src_tools_uic.target = sub-uic
force_bootstrap: src_tools_uic.depends = src_tools_bootstrap
@@ -152,8 +156,13 @@ qtConfig(regularexpression):pcre2 {
SUBDIRS += src_3rdparty_pcre2
src_corelib.depends += src_3rdparty_pcre2
}
-SUBDIRS += src_corelib src_tools_qlalr
TOOLS = src_tools_moc src_tools_rcc src_tools_qlalr src_tools_qfloat16_tables
+!force_bootstrap:if(qtConfig(lttng)|qtConfig(etw)) {
+ SUBDIRS += src_tools_tracegen
+ src_corelib.depends += src_tools_tracegen
+ TOOLS += src_tools_tracegen
+}
+SUBDIRS += src_corelib src_tools_qlalr
win32:SUBDIRS += src_winmain
qtConfig(network) {
SUBDIRS += src_network
@@ -220,7 +229,8 @@ android: SUBDIRS += src_android src_3rdparty_gradle
TR_EXCLUDE = \
src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_tools_qlalr \
src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml \
- src_3rdparty_pcre2 src_3rdparty_harfbuzzng src_3rdparty_freetype
+ src_3rdparty_pcre2 src_3rdparty_harfbuzzng src_3rdparty_freetype \
+ src_tools_tracegen
sub-tools.depends = $$TOOLS
QMAKE_EXTRA_TARGETS = sub-tools
diff --git a/src/tools/tracegen/etw.cpp b/src/tools/tracegen/etw.cpp
new file mode 100644
index 0000000000..07f2d114b6
--- /dev/null
+++ b/src/tools/tracegen/etw.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "etw.h"
+#include "provider.h"
+#include "helpers.h"
+#include "qtheaders.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <quuid.h>
+
+static inline QString providerVar(const QString &providerName)
+{
+ return providerName + QLatin1String("_provider");
+}
+
+static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
+{
+ const QString &name = field.name;
+
+ switch (field.backendType) {
+ case Tracepoint::Field::QtString:
+ stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>("
+ << name << ".utf16()), " << name << ".size(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtByteArray:
+ stream << "TraceLoggingBinary(" << name << ".constData(), "
+ << name << ".size(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtUrl:
+ stream << "TraceLoggingValue(" << name << ".toEncoded().constData(), \"" << name << "\")";
+ return;
+ case Tracepoint::Field::QtRect:
+ stream << "TraceLoggingValue(" << name << ".x(), \"x\"), "
+ << "TraceLoggingValue(" << name << ".y(), \"y\"), "
+ << "TraceLoggingValue(" << name << ".width(), \"width\"), "
+ << "TraceLoggingValue(" << name << ".height(), \"height\")";
+ return;
+ default:
+ break;
+ }
+
+ stream << "TraceLoggingValue(" << name << ", \"" << name << "\")";
+}
+
+static QString createGuid(const QUuid &uuid)
+{
+ QString guid;
+
+ QTextStream stream(&guid);
+
+ hex(stream);
+
+ stream << "("
+ << "0x" << uuid.data1 << ", "
+ << "0x" << uuid.data2 << ", "
+ << "0x" << uuid.data3 << ", "
+ << "0x" << uuid.data4[0] << ", "
+ << "0x" << uuid.data4[1] << ", "
+ << "0x" << uuid.data4[2] << ", "
+ << "0x" << uuid.data4[3] << ", "
+ << "0x" << uuid.data4[4] << ", "
+ << "0x" << uuid.data4[5] << ", "
+ << "0x" << uuid.data4[6] << ", "
+ << "0x" << uuid.data4[7]
+ << ")";
+
+ return guid;
+}
+
+static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName)
+{
+ QUuid uuid = QUuid::createUuidV5(QUuid(), providerName.toLocal8Bit());
+
+ const QString provider = providerVar(providerName);
+ const QString guard = includeGuard(fileName);
+ const QString guid = createGuid(uuid);
+ const QString guidString = uuid.toString();
+
+ stream << "#ifndef " << guard << "\n"
+ << "#define " << guard << "\n"
+ << "#include <windows.h>\n"
+ << "#include <TraceLoggingProvider.h>\n";
+
+ /* TraceLogging API macros cannot deal with UTF8
+ * source files, so we work around it like this
+ */
+ stream << "#undef _TlgPragmaUtf8Begin\n"
+ "#undef _TlgPragmaUtf8End\n"
+ "#define _TlgPragmaUtf8Begin\n"
+ "#define _TlgPragmaUtf8End\n";
+
+ stream << qtHeaders();
+
+ stream << "\n";
+
+ stream << "#ifdef TRACEPOINT_DEFINE\n"
+ << "/* " << guidString << " */\n"
+ << "TRACELOGGING_DEFINE_PROVIDER(" << provider << ", \""
+ << providerName <<"\", " << guid << ");\n\n";
+
+ stream << "static inline void registerProvider()\n"
+ << "{\n"
+ << " TraceLoggingRegister(" << provider << ");\n"
+ << "}\n\n";
+
+ stream << "static inline void unregisterProvider()\n"
+ << "{\n"
+ << " TraceLoggingUnregister(" << provider << ");\n"
+ << "}\n";
+
+ stream << "Q_CONSTRUCTOR_FUNCTION(registerProvider)\n"
+ << "Q_DESTRUCTOR_FUNCTION(unregisterProvider)\n\n";
+
+ stream << "#else\n"
+ << "TRACELOGGING_DECLARE_PROVIDER(" << provider << ");\n"
+ << "#endif // TRACEPOINT_DEFINE\n\n";
+}
+
+static void writeEpilogue(QTextStream &stream, const QString &fileName)
+{
+ stream << "\n#endif // " << includeGuard(fileName) << "\n"
+ << "#include <private/qtrace_p.h>\n";
+}
+
+static void writeWrapper(QTextStream &stream, const Tracepoint &tracepoint,
+ const QString &providerName)
+{
+ const QString argList = formatFunctionSignature(tracepoint.args);
+ const QString paramList = formatParameterList(tracepoint.args, ETW);
+ const QString &name = tracepoint.name;
+ const QString includeGuard = QStringLiteral("TP_%1_%2").arg(providerName).arg(name).toUpper();
+ const QString provider = providerVar(providerName);
+
+ stream << "\n";
+
+ stream << "inline void trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " TraceLoggingWrite(" << provider << ", \"" << name << "\"";
+
+ for (const Tracepoint::Field &field : tracepoint.fields) {
+ stream << ",\n";
+ stream << " ";
+ writeEtwMacro(stream, field);
+ }
+
+ stream << ");\n"
+ << "}\n\n";
+
+ stream << "inline void do_trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " trace_" << name << "(" << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline bool trace_" << name << "_enabled()\n"
+ << "{\n"
+ << " return TraceLoggingProviderEnabled(" << provider << ", 0, 0);\n"
+ << "}\n";
+}
+
+static void writeTracepoints(QTextStream &stream, const Provider &provider)
+{
+ if (provider.tracepoints.isEmpty())
+ return;
+
+ const QString includeGuard = QStringLiteral("TP_%1_PROVIDER").arg(provider.name).toUpper();
+
+ stream << "#if !defined(" << includeGuard << ") && !defined(TRACEPOINT_DEFINE)\n"
+ << "#define " << includeGuard << "\n"
+ << "namespace QtPrivate {\n";
+
+ for (const Tracepoint &t : provider.tracepoints)
+ writeWrapper(stream, t, provider.name);
+
+ stream << "} // namespace QtPrivate\n"
+ << "#endif // " << includeGuard << "\n\n";
+}
+
+void writeEtw(QFile &file, const Provider &provider)
+{
+ QTextStream stream(&file);
+
+ const QString fileName = QFileInfo(file.fileName()).fileName();
+
+ writePrologue(stream, fileName, provider.name);
+ writeTracepoints(stream, provider);
+ writeEpilogue(stream, fileName);
+}
+
diff --git a/src/tools/tracegen/etw.h b/src/tools/tracegen/etw.h
new file mode 100644
index 0000000000..5fc9b57eaa
--- /dev/null
+++ b/src/tools/tracegen/etw.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ETW_H
+#define ETW_H
+
+struct Provider;
+class QFile;
+
+void writeEtw(QFile &device, const Provider &p);
+
+#endif // ETW_H
diff --git a/src/tools/tracegen/helpers.cpp b/src/tools/tracegen/helpers.cpp
new file mode 100644
index 0000000000..f0ac7ed47f
--- /dev/null
+++ b/src/tools/tracegen/helpers.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpers.h"
+#include <qdebug.h>
+
+QString includeGuard(const QString &filename)
+{
+ QString guard = filename.toUpper();
+
+ for (int i = 0; i < guard.size(); ++i) {
+ if (!guard.at(i).isLetterOrNumber())
+ guard[i] = QChar('_');
+ }
+
+ return guard;
+}
+
+template <typename T>
+static QString joinArguments(const QVector<Tracepoint::Argument> &args, T joinFunction)
+{
+ QString ret;
+ bool first = true;
+
+ for (const Tracepoint::Argument &arg : args) {
+ if (!first)
+ ret += QLatin1String(", ");
+
+ ret += joinFunction(arg);
+
+ first = false;
+ }
+
+ return ret;
+}
+
+QString formatFunctionSignature(const QVector<Tracepoint::Argument> &args)
+{
+ return joinArguments(args, [](const Tracepoint::Argument &arg) {
+ return QStringLiteral("%1 %2").arg(arg.type).arg(arg.name);
+ });
+}
+
+QString formatParameterList(const QVector<Tracepoint::Argument> &args, ParamType type)
+{
+ if (type == LTTNG) {
+ QString ret;
+
+ for (const Tracepoint::Argument &arg : args)
+ ret += QLatin1String(", ") + arg.name;
+
+ return ret;
+ }
+
+ return joinArguments(args, [](const Tracepoint::Argument &arg) { return arg.name; });
+}
diff --git a/src/tools/tracegen/helpers.h b/src/tools/tracegen/helpers.h
new file mode 100644
index 0000000000..77f16a0da6
--- /dev/null
+++ b/src/tools/tracegen/helpers.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPERS_H
+#define HELPERS_H
+
+#include "provider.h"
+
+#include <qvector.h>
+#include <qstring.h>
+
+enum ParamType {
+ LTTNG,
+ ETW
+};
+
+QString includeGuard(const QString &filename);
+QString formatFunctionSignature(const QVector<Tracepoint::Argument> &args);
+QString formatParameterList(const QVector<Tracepoint::Argument> &args, ParamType type);
+
+#endif // HELPERS_H
diff --git a/src/tools/tracegen/lttng.cpp b/src/tools/tracegen/lttng.cpp
new file mode 100644
index 0000000000..6c0d8cc88b
--- /dev/null
+++ b/src/tools/tracegen/lttng.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lttng.h"
+#include "provider.h"
+#include "helpers.h"
+#include "panic.h"
+#include "qtheaders.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qdebug.h>
+
+static void writeCtfMacro(QTextStream &stream, const Tracepoint::Field &field)
+{
+ const QString &paramType = field.paramType;
+ const QString &name = field.name;
+ const QString &seqLen = field.seqLen;
+ const int arrayLen = field.arrayLen;
+
+ switch (field.backendType) {
+ case Tracepoint::Field::Array:
+ stream << "ctf_array(" <<paramType << ", "
+ << name << ", " << name << ", " << arrayLen << ")";
+ return;
+ case Tracepoint::Field::Sequence:
+ stream << "ctf_sequence(" << paramType
+ << ", " << name << ", " << name
+ << ", unsigned int, " << seqLen << ")";
+ return;
+ case Tracepoint::Field::Integer:
+ stream << "ctf_integer(" << paramType << ", " << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::Float:
+ stream << "ctf_float(" << paramType << ", " << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::String:
+ stream << "ctf_string(" << name << ", " << name << ")";
+ return;
+ case Tracepoint::Field::QtString:
+ stream << "ctf_sequence(const ushort, " << name << ", "
+ << name << ".utf16(), unsigned int, " << name << ".size())";
+ return;
+ case Tracepoint::Field::QtByteArray:
+ stream << "ctf_sequence(const char, " << name << ", "
+ << name << ".constData(), unsigned int, " << name << ".size())";
+ return;
+ case Tracepoint::Field::QtUrl:
+ stream << "ctf_sequence(const char, " << name << ", "
+ << name << ".toEncoded().constData(), unsigned int, "
+ << name << ".toEncoded().size())";
+ return;
+ case Tracepoint::Field::QtRect:
+ stream << "ctf_integer(int, x, " << name << ".x()) "
+ << "ctf_integer(int, y, " << name << ".y()) "
+ << "ctf_integer(int, width, " << name << ".width()) "
+ << "ctf_integer(int, height, " << name << ".height()) ";
+ return;
+ case Tracepoint::Field::Unknown:
+ panic("Cannot deduce CTF type for '%s %s", qPrintable(paramType), qPrintable(name));
+ break;
+ }
+}
+
+static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName)
+{
+ stream << "#undef TRACEPOINT_PROVIDER\n";
+ stream << "#define TRACEPOINT_PROVIDER " << providerName << "\n\n";
+
+ stream << qtHeaders();
+
+ const QString guard = includeGuard(fileName);
+
+ stream << "\n";
+
+ /* the first guard is the usual one, the second is required
+ * by LTTNG to force the re-evaluation of TRACEPOINT_* macros
+ */
+ stream << "#if !defined(" << guard << ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n";
+
+ stream << "#define " << guard << "\n\n"
+ << "#undef TRACEPOINT_INCLUDE\n"
+ << "#define TRACEPOINT_INCLUDE \"" << fileName << "\"\n\n";
+
+ stream << "#include <lttng/tracepoint.h>\n\n";
+}
+
+static void writeEpilogue(QTextStream &stream, const QString &fileName)
+{
+ stream << "\n";
+ stream << "#endif // " << includeGuard(fileName) << "\n"
+ << "#include <lttng/tracepoint-event.h>\n"
+ << "#include <private/qtrace_p.h>\n";
+}
+
+static void writeWrapper(QTextStream &stream,
+ const Tracepoint &tracepoint, const QString &providerName)
+{
+ const QString argList = formatFunctionSignature(tracepoint.args);
+ const QString paramList = formatParameterList(tracepoint.args, LTTNG);
+ const QString &name = tracepoint.name;
+ const QString includeGuard = QStringLiteral("TP_%1_%2").arg(providerName).arg(name).toUpper();
+
+ /* prevents the redefinion of the inline wrapper functions
+ * once LTTNG recursively includes this header file
+ */
+ stream << "\n"
+ << "#ifndef " << includeGuard << "\n"
+ << "#define " << includeGuard << "\n"
+ << "namespace QtPrivate {\n";
+
+ stream << "inline void trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " tracepoint(" << providerName << ", " << name << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline void do_trace_" << name << "(" << argList << ")\n"
+ << "{\n"
+ << " do_tracepoint(" << providerName << ", " << name << paramList << ");\n"
+ << "}\n";
+
+ stream << "inline bool trace_" << name << "_enabled()\n"
+ << "{\n"
+ << " return tracepoint_enabled(" << providerName << ", " << name << ");\n"
+ << "}\n";
+
+ stream << "} // namespace QtPrivate\n"
+ << "#endif // " << includeGuard << "\n\n";
+}
+
+static void writeTracepoint(QTextStream &stream,
+ const Tracepoint &tracepoint, const QString &providerName)
+{
+ stream << "TRACEPOINT_EVENT(\n"
+ << " " << providerName << ",\n"
+ << " " << tracepoint.name << ",\n"
+ << " TP_ARGS(";
+
+ const char *comma = nullptr;
+
+ for (const Tracepoint::Argument &arg : tracepoint.args) {
+ stream << comma << arg.type << ", " << arg.name;
+ comma = ", ";
+ }
+
+ stream << "),\n"
+ << " TP_FIELDS(";
+
+ const char *newline = nullptr;
+
+ for (const Tracepoint::Field &f : tracepoint.fields) {
+ stream << newline;
+ writeCtfMacro(stream, f);
+ newline = "\n ";
+ }
+
+ stream << ")\n)\n\n";
+}
+
+static void writeTracepoints(QTextStream &stream, const Provider &provider)
+{
+ for (const Tracepoint &t : provider.tracepoints) {
+ writeTracepoint(stream, t, provider.name);
+ writeWrapper(stream, t, provider.name);
+ }
+}
+
+void writeLttng(QFile &file, const Provider &provider)
+{
+ QTextStream stream(&file);
+
+ const QString fileName = QFileInfo(file.fileName()).fileName();
+
+ writePrologue(stream, fileName, provider.name);
+ writeTracepoints(stream, provider);
+ writeEpilogue(stream, fileName);
+}
diff --git a/src/tools/tracegen/lttng.h b/src/tools/tracegen/lttng.h
new file mode 100644
index 0000000000..0307b375bc
--- /dev/null
+++ b/src/tools/tracegen/lttng.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LTTNG_H
+#define LTTNG_H
+
+struct Provider;
+class QFile;
+
+void writeLttng(QFile &device, const Provider &p);
+
+#endif // LTTNG_H
diff --git a/src/tools/tracegen/panic.cpp b/src/tools/tracegen/panic.cpp
new file mode 100644
index 0000000000..d1e207764e
--- /dev/null
+++ b/src/tools/tracegen/panic.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "panic.h"
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+void panic(const char *fmt, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "tracegen: fatal: ");
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ fputc('\n', stderr);
+
+ exit(EXIT_FAILURE);
+}
diff --git a/src/tools/tracegen/panic.h b/src/tools/tracegen/panic.h
new file mode 100644
index 0000000000..c6b195af00
--- /dev/null
+++ b/src/tools/tracegen/panic.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PANIC_H
+#define PANIC_H
+
+void panic(const char *fmt, ...);
+
+#endif // PANIC_H
diff --git a/src/tools/tracegen/provider.cpp b/src/tools/tracegen/provider.cpp
new file mode 100644
index 0000000000..00e105377e
--- /dev/null
+++ b/src/tools/tracegen/provider.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "provider.h"
+#include "panic.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qtextstream.h>
+#include <qregexp.h>
+#include <qstring.h>
+
+#ifdef TRACEGEN_DEBUG
+#include <qdebug.h>
+
+static void dumpTracepoint(const Tracepoint &t)
+{
+ qDebug() << "=== BEGIN TRACEPOINT ===";
+ qDebug() << "name:" << t.name;
+ qDebug() << "ARGS\n";
+
+ int j = 0;
+
+ for (auto i = t.args.constBegin(); i != t.args.constEnd(); ++i) {
+ qDebug() << "ARG[" << j << "] type:" << i->type;
+ qDebug() << "ARG[" << j << "] name:" << i->name;
+ qDebug() << "ARG[" << j << "] arrayLen:" << i->arrayLen;
+ ++j;
+ }
+
+ qDebug() << "\nFIELDS\n";
+
+ j = 0;
+
+ for (auto i = t.fields.constBegin(); i != t.fields.constEnd(); ++i) {
+ qDebug() << "FIELD[" << j << "] backend_type" << static_cast<int>(i->backendType);
+ qDebug() << "FIELD[" << j << "] param_type" << i->paramType;
+ qDebug() << "FIELD[" << j << "] name" << i->name;
+ qDebug() << "FIELD[" << j << "] arrayLen" << i->arrayLen;
+ qDebug() << "FIELD[" << j << "] seqLen" << i->seqLen;
+ ++j;
+ }
+
+ qDebug() << "=== END TRACEPOINT ===\n";
+
+}
+#endif
+
+static inline int arrayLength(const QString &rawType)
+{
+ /* matches the length of an ordinary array type
+ * Ex: foo[10] yields '10'
+ */
+ static const QRegExp rx(QStringLiteral(".*\\[([0-9]+)\\].*"));
+
+ if (!rx.exactMatch(rawType.trimmed()))
+ return 0;
+
+ return rx.cap(1).toInt();
+}
+
+static inline QString sequenceLength(const QString &rawType)
+{
+ /* matches the identifier pointing to length of a CTF sequence type, which is
+ * a dynamic sized array.
+ * Ex: in qcoreapplication_foo(const char[len], some_string, unsigned int, * len)
+ * it will match the 'len' part of 'const char[len]')
+ */
+ static const QRegExp rx(QStringLiteral(".*\\[([A-Za-z_][A-Za-z_0-9]*)\\].*"));
+
+ if (!rx.exactMatch(rawType.trimmed()))
+ return QString();
+
+ return rx.cap(1);
+}
+
+static QString decayArrayToPointer(QString type)
+{
+ /* decays an array to a pointer, i.e., if 'type' holds int[10],
+ * this function returns 'int *'
+ */
+ static QRegExp rx(QStringLiteral("\\[(.+)\\]"));
+
+ rx.setMinimal(true);
+ return type.replace(rx, QStringLiteral("*"));
+}
+
+static QString removeBraces(QString type)
+{
+ static const QRegExp rx(QStringLiteral("\\[.*\\]"));
+
+ return type.remove(rx);
+}
+
+static Tracepoint::Field::BackendType backendType(QString rawType)
+{
+ static const struct {
+ const char *type;
+ Tracepoint::Field::BackendType backendType;
+ } typeTable[] = {
+ { "bool", Tracepoint::Field::Integer },
+ { "short_int", Tracepoint::Field::Integer },
+ { "signed_short", Tracepoint::Field::Integer },
+ { "signed_short_int", Tracepoint::Field::Integer },
+ { "unsigned_short", Tracepoint::Field::Integer },
+ { "unsigned_short_int", Tracepoint::Field::Integer },
+ { "int", Tracepoint::Field::Integer },
+ { "signed", Tracepoint::Field::Integer },
+ { "signed_int", Tracepoint::Field::Integer },
+ { "unsigned", Tracepoint::Field::Integer },
+ { "unsigned_int", Tracepoint::Field::Integer },
+ { "long", Tracepoint::Field::Integer },
+ { "long_int", Tracepoint::Field::Integer },
+ { "signed_long", Tracepoint::Field::Integer },
+ { "signed_long_int", Tracepoint::Field::Integer },
+ { "unsigned_long", Tracepoint::Field::Integer },
+ { "unsigned_long_int", Tracepoint::Field::Integer },
+ { "long_long", Tracepoint::Field::Integer },
+ { "long_long_int", Tracepoint::Field::Integer },
+ { "signed_long_long", Tracepoint::Field::Integer },
+ { "signed_long_long_int", Tracepoint::Field::Integer },
+ { "unsigned_long_long", Tracepoint::Field::Integer },
+ { "char", Tracepoint::Field::Integer },
+ { "float", Tracepoint::Field::Float },
+ { "double", Tracepoint::Field::Float },
+ { "long_double", Tracepoint::Field::Float },
+ { "char_ptr", Tracepoint::Field::String },
+ { "QString", Tracepoint::Field::QtString },
+ { "QByteArray", Tracepoint::Field::QtByteArray },
+ { "QUrl", Tracepoint::Field::QtUrl },
+ { "QRect", Tracepoint::Field::QtRect }
+ };
+
+ auto backendType = [](const QString &rawType) {
+
+ static const size_t tableSize = sizeof (typeTable) / sizeof (typeTable[0]);
+
+ for (size_t i = 0; i < tableSize; ++i) {
+ if (rawType == QLatin1String(typeTable[i].type))
+ return typeTable[i].backendType;
+ }
+
+ return Tracepoint::Field::Unknown;
+ };
+
+ if (arrayLength(rawType) > 0)
+ return Tracepoint::Field::Array;
+
+ if (!sequenceLength(rawType).isNull())
+ return Tracepoint::Field::Sequence;
+
+ static const QRegExp constMatch(QStringLiteral("\\bconst\\b"));
+ rawType.remove(constMatch);
+ rawType.remove(QLatin1Char('&'));
+
+ static const QRegExp ptrMatch(QStringLiteral("\\s*\\*\\s*"));
+ rawType.replace(ptrMatch, QStringLiteral("_ptr"));
+ rawType = rawType.trimmed();
+ rawType.replace(QStringLiteral(" "), QStringLiteral("_"));
+
+ return backendType(rawType.trimmed());
+}
+
+static Tracepoint parseTracepoint(const QString &name, const QStringList &args,
+ const QString &fileName, const int lineNumber)
+{
+ Tracepoint t;
+ t.name = name;
+
+ if (args.isEmpty())
+ return t;
+
+ auto i = args.constBegin();
+ auto end = args.constEnd();
+ int argc = 0;
+
+ static const QRegExp rx(QStringLiteral("(.*)\\b([A-Za-z_][A-Za-z0-9_]*)$"));
+
+ while (i != end) {
+ rx.exactMatch(*i);
+
+ const QString type = rx.cap(1).trimmed();
+
+ if (type.isNull()) {
+ panic("Missing parameter type for argument %d of %s (%s:%d)",
+ argc, qPrintable(name), qPrintable(fileName), lineNumber);
+ }
+
+ const QString name = rx.cap(2).trimmed();
+
+ if (name.isNull()) {
+ panic("Missing parameter name for argument %d of %s (%s:%d)",
+ argc, qPrintable(name), qPrintable(fileName), lineNumber);
+ }
+
+ int arrayLen = arrayLength(type);
+
+ Tracepoint::Argument a;
+ a.arrayLen = arrayLen;
+ a.name = name;
+ a.type = decayArrayToPointer(type);
+
+ t.args << std::move(a);
+
+ Tracepoint::Field f;
+ f.backendType = backendType(type);
+ f.paramType = removeBraces(type);
+ f.name = name;
+ f.arrayLen = arrayLen;
+ f.seqLen = sequenceLength(type);
+
+ t.fields << std::move(f);
+
+ ++i;
+ }
+
+ return t;
+}
+
+Provider parseProvider(const QString &filename)
+{
+ QFile f(filename);
+
+ if (!f.open(QIODevice::ReadOnly | QIODevice::Text))
+ panic("Cannot open %s: %s", qPrintable(filename), qPrintable(f.errorString()));
+
+ QTextStream s(&f);
+
+ static const QRegExp tracedef(QStringLiteral("([A-Za-z][A-Za-z0-9_]*)\\((.*)\\)"));
+
+ int lineNumber = 0;
+
+ Provider provider;
+ provider.name = QFileInfo(filename).baseName();
+
+ for (;;) {
+ QString line = s.readLine().trimmed();
+
+ if (line.isNull())
+ break;
+
+ if (line.isEmpty() || line.startsWith(QStringLiteral("#"))) {
+ ++lineNumber;
+ continue;
+ }
+
+ if (tracedef.exactMatch(line)) {
+ const QString name = tracedef.cap(1);
+ QStringList args = tracedef.cap(2).split(QStringLiteral(","), QString::SkipEmptyParts);
+
+ if (args.at(0).isNull())
+ args.clear();
+
+ provider.tracepoints << parseTracepoint(name, args, filename, lineNumber);
+ } else {
+ panic("Syntax error whilre processing %s on line %d", qPrintable(filename), lineNumber);
+ }
+
+ ++lineNumber;
+ }
+
+#ifdef TRACEGEN_DEBUG
+ for (auto i = provider.tracepoints.constBegin(); i != provider.tracepoints.constEnd(); ++i)
+ dumpTracepoint(*i);
+#endif
+
+ return provider;
+}
diff --git a/src/tools/tracegen/provider.h b/src/tools/tracegen/provider.h
new file mode 100644
index 0000000000..d8cbd2662d
--- /dev/null
+++ b/src/tools/tracegen/provider.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROVIDER_H
+#define PROVIDER_H
+
+#include <qvector.h>
+#include <qstring.h>
+#include <qtypeinfo.h>
+
+struct Tracepoint
+{
+ struct Argument
+ {
+ QString type;
+ QString name;
+ int arrayLen;
+ };
+
+ struct Field
+ {
+ enum BackendType {
+ Array,
+ Sequence,
+ Integer,
+ Float,
+ String,
+ QtString,
+ QtByteArray,
+ QtUrl,
+ QtRect,
+ Unknown
+ };
+
+ BackendType backendType;
+ QString paramType;
+ QString name;
+ int arrayLen;
+ QString seqLen;
+ };
+
+ QString name;
+ QVector<Argument> args;
+ QVector<Field> fields;
+};
+
+struct Provider
+{
+ QString name;
+ QVector<Tracepoint> tracepoints;
+};
+
+Provider parseProvider(const QString &filename);
+
+Q_DECLARE_TYPEINFO(Tracepoint::Argument, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Tracepoint::Field, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(Tracepoint, Q_MOVABLE_TYPE);
+
+#endif // PROVIDER_H
diff --git a/src/tools/tracegen/qtheaders.cpp b/src/tools/tracegen/qtheaders.cpp
new file mode 100644
index 0000000000..eec3488a6d
--- /dev/null
+++ b/src/tools/tracegen/qtheaders.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtheaders.h"
+
+const char *qtHeaders()
+{
+ static const char headers[] = ""
+ "#include <QString>\n"
+ "#include <QByteArray>\n"
+ "#include <QUrl>\n"
+ "#include <QRect>\n";
+
+ return headers;
+}
diff --git a/src/tools/tracegen/qtheaders.h b/src/tools/tracegen/qtheaders.h
new file mode 100644
index 0000000000..b80d374ca8
--- /dev/null
+++ b/src/tools/tracegen/qtheaders.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTHEADERS_H
+#define QTHEADERS_H
+
+const char *qtHeaders();
+
+#endif // QTHEADERS_H
diff --git a/src/tools/tracegen/tracegen.cpp b/src/tools/tracegen/tracegen.cpp
new file mode 100644
index 0000000000..978fe406d0
--- /dev/null
+++ b/src/tools/tracegen/tracegen.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "provider.h"
+#include "lttng.h"
+#include "etw.h"
+#include "panic.h"
+
+#include <qstring.h>
+#include <qfile.h>
+
+enum class Target
+{
+ LTTNG,
+ ETW
+};
+
+static inline void usage(int status)
+{
+ printf("Usage: tracegen <lttng|etw> <input file> <output file>\n");
+ exit(status);
+}
+
+static void parseArgs(int argc, char *argv[], Target *target, QString *inFile, QString *outFile)
+{
+ if (argc == 1)
+ usage(EXIT_SUCCESS);
+ if (argc != 4)
+ usage(EXIT_FAILURE);
+
+ const char *targetString = argv[1];
+
+ if (qstrcmp(targetString, "lttng") == 0) {
+ *target = Target::LTTNG;
+ } else if (qstrcmp(targetString, "etw") == 0) {
+ *target = Target::ETW;
+ } else {
+ fprintf(stderr, "Invalid target: %s\n", targetString);
+ usage(EXIT_FAILURE);
+ }
+
+ *inFile = QLatin1String(argv[2]);
+ *outFile = QLatin1String(argv[3]);
+}
+
+int main(int argc, char *argv[])
+{
+ Target target = Target::LTTNG;
+ QString inFile;
+ QString outFile;
+
+ parseArgs(argc, argv, &target, &inFile, &outFile);
+
+ Provider p = parseProvider(inFile);
+
+ QFile out(outFile);
+
+ if (!out.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
+ panic("Cannot open '%s' for writing: %s",
+ qPrintable(outFile), qPrintable(out.errorString()));
+ }
+
+ switch (target) {
+ case Target::LTTNG:
+ writeLttng(out, p);
+ break;
+ case Target::ETW:
+ writeEtw(out, p);
+ break;
+ }
+
+ return 0;
+}
diff --git a/src/tools/tracegen/tracegen.pro b/src/tools/tracegen/tracegen.pro
new file mode 100644
index 0000000000..20f0bb2914
--- /dev/null
+++ b/src/tools/tracegen/tracegen.pro
@@ -0,0 +1,21 @@
+option(host_build)
+CONFIG += force_bootstrap
+
+SOURCES += \
+ etw.cpp \
+ helpers.cpp \
+ lttng.cpp \
+ panic.cpp \
+ provider.cpp \
+ qtheaders.cpp \
+ tracegen.cpp
+
+HEADERS += \
+ etw.h \
+ helpers.h \
+ lttng.h \
+ panic.h \
+ provider.h \
+ qtheaders.h
+
+load(qt_tool)