Support for LTTNG and ETW tracing
This commit introduces minimal support for instrumentation within Qt. Currently, only LTTNG/Linux and ETW/Windows are supported. Change-Id: I59b48cf83acf5532a998bb493e6379e9177e14c8 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
2b7de16fbe
commit
48bce2e8f0
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
@ -907,6 +936,11 @@ Please apply the patch corresponding to your Standard Library vendor, found in
|
|||
"glib",
|
||||
"iconv",
|
||||
"icu",
|
||||
{
|
||||
"message": "Tracing backend",
|
||||
"type": "firstAvailableFeature",
|
||||
"args": "etw lttng"
|
||||
},
|
||||
{
|
||||
"section": "Logging backends",
|
||||
"entries": [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
16
src/src.pro
16
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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; });
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ¶mType = 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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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)
|
||||
Loading…
Reference in New Issue