1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QTRACE_P_H
41 #define QTRACE_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 /*
55  * The Qt tracepoints API consists of only five macros:
56  *
57  *     - Q_TRACE(tracepoint, args...)
58  *       Fires 'tracepoint' if it is enabled.
59  *
60  *     - Q_TRACE_EXIT(tracepoint, args...)
61  *       Fires 'tracepoint' if it is enabled when the current scope exists.
62  *
63  *     - Q_TRACE_SCOPE(tracepoint, args...)
64  *       Wrapper around Q_TRACE/_EXIT to trace entry and exit. First it traces
65  *       `${tracepoint}_entry` and then `${tracepoint}_exit` on scope exit.
66  *
67  *     - Q_UNCONDITIONAL_TRACE(tracepoint, args...)
68  *       Fires 'tracepoint' unconditionally: no check is performed to query
69  *       whether 'tracepoint' is enabled.
70  *
71  *     - Q_TRACE_ENABLED(tracepoint)
72  *       Returns 'true' if 'tracepoint' is enabled; false otherwise.
73  *
74  * When using LTTNG, Q_TRACE, Q_UNCONDITIONAL_TRACE and Q_TRACE_ENABLED map
75  * ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
76  * respectively, described on the lttng-ust manpage (man 3 lttng-ust).
77  *
78  * On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
79  * amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
80  * wraps around TraceLoggingProviderEnabled().
81  *
82  * A tracepoint provider is defined in a separate file, that follows the
83  * following format:
84  *
85  *     tracepoint_name(arg_type arg_name, ...)
86  *
87  * For instance:
88  *
89  *     qcoreapplication_ctor(int argc, const char * const argv)
90  *     qcoreapplication_foo(int argc, const char[10] argv)
91  *     qcoreapplication_baz(const char[len] some_string, unsigned int len)
92  *     qcoreapplication_qstring(const QString &foo)
93  *     qcoreapplication_qrect(const QRect &rect)
94  *
95  * The provider file is then parsed by src/tools/tracegen, which can be
96  * switched to output either ETW or LTTNG tracepoint definitions. The provider
97  * name is deduced to be basename(provider_file).
98  *
99  * To use the above (inside qtcore), you need to include
100  * <providername_tracepoints_p.h>. After that, the following call becomes
101  * possible:
102  *
103  *     Q_TRACE(qcoreapplication_qrect, myRect);
104  *
105  * Currently, all C++ primitive non-pointer types are supported for
106  * arguments. Additionally, char * is supported, and is assumed to
107  * be a NULL-terminated string. Finally, the following subset of Qt types also
108  * currently supported:
109  *
110  *      - QString
111  *      - QByteArray
112  *      - QUrl
113  *      - QRect
114  *
115  * Dynamic arrays are supported using the syntax illustrated by
116  * qcoreapplication_baz above.
117  */
118 
119 #include <QtCore/qglobal.h>
120 #include <QtCore/qscopeguard.h>
121 
122 QT_BEGIN_NAMESPACE
123 
124 #if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
125 #  define Q_HAS_TRACEPOINTS 1
126 #  define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
127 #  define Q_TRACE_EXIT(x, ...) \
128     const auto qTraceExit_ ## x ## __COUNTER__ = qScopeGuard([&]() { Q_TRACE(x, __VA_ARGS__); });
129 #  define Q_TRACE_SCOPE(x, ...) \
130     Q_TRACE(x ## _entry, __VA_ARGS__); \
131     Q_TRACE_EXIT(x ## _exit);
132 #  define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
133 #  define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
134 #else
135 #  define Q_HAS_TRACEPOINTS 0
136 #  define Q_TRACE(x, ...)
137 #  define Q_TRACE_EXIT(x, ...)
138 #  define Q_TRACE_SCOPE(x, ...)
139 #  define Q_UNCONDITIONAL_TRACE(x, ...)
140 #  define Q_TRACE_ENABLED(x) false
141 #endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
142 
143 QT_END_NAMESPACE
144 
145 #endif // QTRACE_P_H
146