Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtrace_p.h
Go to the documentation of this file.
1// Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Rafael Roquetto <rafael.roquetto@kdab.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QTRACE_P_H
6#define QTRACE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/private/qglobal_p.h>
20#include <QtCore/qscopeguard.h>
21
23
24/*! \internal
25 Tracing needs to be enabled using `configure -trace`. As explained
26 by `configure --help`, the backend can be given as an optional argument.
27 Currently supported backends include [LTTNG](https://lttng.org) on Linux,
28 [ETW](https://learn.microsoft.com/en-us/windows/win32/etw/event-tracing-portal)
29 on Windows, and [CTF](https://diamon.org/ctf/) (common trace format)
30 as a cross-platform solution.
31
32 \section Qt API
33
34 The Qt tracepoints API consists of five macros:
35
36 Macro | Behavior
37 ------------------------------------------- | -----------------------------
38 Q_TRACE(tracepoint, args...) | Fires 'tracepoint' if it is enabled.
39 Q_TRACE_EXIT(tracepoint, args...) | Fires 'tracepoint' if it is enabled when the current scope exists.
40 Q_TRACE_SCOPE(tracepoint, args...) | Wrapper around Q_TRACE/_EXIT to trace entry and exit. First it traces `${tracepoint}_entry` and then `${tracepoint}_exit` on scope exit.
41 Q_UNCONDITIONAL_TRACE(tracepoint, args...) | Fires 'tracepoint' unconditionally: no check is performed to query whether 'tracepoint' is enabled.
42 Q_TRACE_ENABLED(tracepoint) | Returns 'true' if 'tracepoint' is enabled; false otherwise.
43
44 When using LTTNG, Q_TRACE(), Q_UNCONDITIONAL_TRACE() and Q_TRACE_ENABLED()
45 map ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
46 respectively, described on the `lttng-ust` manpage (man 3 lttng-ust).
47
48 On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
49 amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
50 wraps around TraceLoggingProviderEnabled().
51
52 A tracepoint provider is defined in a separate file, that follows the
53 following format:
54
55 \code
56 tracepoint_name(arg_type arg_name, ...)
57 \endcode
58
59 For instance:
60
61 \code
62 qcoreapplication_ctor(int argc, const char * const argv)
63 qcoreapplication_foo(int argc, const char[10] argv)
64 qcoreapplication_baz(const char[len] some_string, unsigned int len)
65 qcoreapplication_qstring(const QString &foo)
66 qcoreapplication_qrect(const QRect &rect)
67 \endcode
68
69 The provider file is then parsed by src/tools/tracegen (which gets built to
70 \c libexec/tracegen), which can be switched to output ETW, CTF or LTTNG
71 tracepoint definitions. The provider name is deduced to be
72 `basename(provider_file)`.
73
74 To use the above (inside qtcore), you need `include <providername_tracepoints_p.h>`.
75 After that, the following call becomes possible:
76
77 \code
78 Q_TRACE(qcoreapplication_qrect, myRect);
79 \endcode
80
81 Currently, all C++ primitive non-pointer types are supported for arguments.
82 Additionally, `char *` is supported, and is assumed to be a
83 nullptr-terminated string. Finally, the following subset of Qt types are
84 also currently supported:
85
86 - QString
87 - QByteArray
88 - QUrl
89 - QRect
90 - QRectF
91 - QSize
92 - QSizeF
93
94 Dynamic arrays are supported using the syntax illustrated by
95 \c qcoreapplication_baz above.
96
97 One can also add prefix for the generated \c providername_tracepoints_p.h
98 file by specifying it inside brackets `{ }` in the tracepoints file.
99 One can for example add a forward declaration for a type:
100
101 \code
102 {
103 QT_BEGIN_NAMESPACE
104 class QEvent;
105 QT_END_NAMESPACE
106 }
107 \endcode
108
109 \section Metadata
110
111 Metadata is used to add textual information for different types such as
112 enums and flags. How this data is handled depends on the used backend.
113 For ETW, the values are converted to text; for CTF and LTTNG they are used
114 to add CTF enumerations, which are converted to text after tracing.
115
116 Enumerations are specified using ENUM:
117
118 \code
119 ENUM {
120 Enum0 = 0,
121 Enum1 = 1,
122 Enum2,
123 RANGE(RangeEnum, 3 ... 10),
124 } Name;
125 \endcode
126
127 Name must match to one of the enumerations used in the tracepoints. Range of values
128 can be provided using RANGE(name, first ... last). All values must be unique.
129
130 Flags are specified using FLAGS:
131
132 \code
133 FLAGS {
134 Default = 0,
135 Flag0 = 1,
136 Flag1 = 2,
137 Flag2 = 4,
138 } Name;
139 \endcode
140
141 Name must match to one of the flags used in the tracepoints. Each value must be
142 power of two and unique.
143
144 The Qt tracepoints can also be defined directly in the source files using
145 the macros Q_TRACE_INSTRUMENT(), Q_TRACE_PARAM_REPLACE(), Q_TRACE_POINT(),
146 Q_TRACE_PREFIX() and Q_TRACE_METADATA(). If using these macros, the
147 tracepoints file is automatically generated using the `tracepointgen` tool.
148 The tool scans the input files for these macros. These macros are ignored
149 during compile time. Both automatic generation and manually specifying
150 tracepoints in a file can't be done at the same time for the same provider.
151
152 \note Traces are not object-oriented. Often, the purpose of a specific
153 tracepoint is to record the fact that a function was called; but you
154 cannot see on which object instance a method was called, unless some
155 information about the object (such as its pointer or ID) is given as one of
156 the arguments to the trace macro. So far, we have not standardized that.
157*/
158
159#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
160# define Q_HAS_TRACEPOINTS 1
161# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
162# define Q_TRACE_EXIT(x, ...)
163 const auto qTraceExit_ ## x ## __COUNTER__ = qScopeGuard([&]() { Q_TRACE(x, __VA_ARGS__); });
164# define Q_TRACE_SCOPE(x, ...)
165 Q_TRACE(x ## _entry, __VA_ARGS__);
166 Q_TRACE_EXIT(x ## _exit);
167# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
168# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
169#else
170# define Q_HAS_TRACEPOINTS 0
171
172/*! \internal
173 This macro fires \a tracepoint if it is enabled.
174*/
175# define Q_TRACE(x, ...)
176
177/*! \internal
178 This macro fires \a tracepoint if it is enabled when the current scope exits.
179*/
180# define Q_TRACE_EXIT(x, ...)
181
182/*! \internal
183 This macro is a wrapper around Q_TRACE/_EXIT to trace entry and exit.
184 First it traces \c {${tracepoint}_entry}, and then \c {${tracepoint}_exit} on scope exit.
185*/
186# define Q_TRACE_SCOPE(x, ...)
187
188/*! \internal
189 This macro fires \a tracepoint unconditionally: no check is performed to
190 query whether \c tracepoint is enabled.
191*/
192# define Q_UNCONDITIONAL_TRACE(x, ...)
193
194/*! \internal
195 This macro returns \c true if \a tracepoint is enabled, or \c false otherwise.
196*/
197# define Q_TRACE_ENABLED(x) false
198#endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
199
200/*! \internal
201 Generate entry/exit tracepoints for a function. For example, member function
202
203 \code
204 void SomeClass::method(int param1, float param2)
205 {
206 ...
207 }
208 \endcode
209
210 converted to use tracepoints:
211
212 \code
213 void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, float param2)
214 {
215 Q_TRACE_SCOPE(SomeClass_method, param1, param2);
216 ...
217 }
218 \encode
219
220 generates the following tracepoints in the \c provider.tracepoints file:
221
222 \code
223 SomeClass_method_entry(int param1, float param2)
224 SomeClass_method_exit()
225 \encode
226
227 \sa qt_tracing
228*/
229#define Q_TRACE_INSTRUMENT(provider)
230
231/*! \internal
232 Can be used with Q_TRACE_INSTRUMENT to replace parameter type \a in with
233 type \a out. If a parameter type is not supported by the \c tracegen tool,
234 one can use this to change it to another supported type.
235
236 \code
237 void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, UserType param2)
238 {
239 Q_TRACE_PARAM_REPLACE(UserType, QString);
240 Q_TRACE_SCOPE(SomeClass_method, param1, param2.toQString());
241 }
242 \encode
243
244 \sa qt_tracing
245*/
246#define Q_TRACE_PARAM_REPLACE(in, out)
247
248/*! \internal
249 Manually specify tracepoint for the provider. \a tracepoint is the full
250 name of the tracepoint, and there can be zero or more parameters.
251
252 \code
253 Q_TRACE_POINT(provider, SomeClass_function_entry, int param1, int param2);
254 \encode
255
256 generates the following tracepoint:
257
258 \code
259 SomeClass_function_entry(int param1, int param2)
260 \encode
261
262 \sa qt_tracing
263*/
264#define Q_TRACE_POINT(provider, tracepoint, ...)
265
266/*! \internal
267 Provides a prefix for the tracepoint. Multiple prefixes can be specified
268 for the same provider in different files; they are all concatenated into
269 one in the \c provider.tracepoints file.
270
271 \code
272 Q_TRACE_PREFIX(provider,
273 "QT_BEGIN_NAMESPACE" \
274 "class QEvent;" \
275 "QT_END_NAMESPACE")
276 \encode
277
278 \sa qt_tracing
279*/
280#define Q_TRACE_PREFIX(provider, prefix)
281
282/*! \internal
283 Provides metadata for the tracepoint provider.
284
285 \code
286 Q_TRACE_METADATA(qtgui,
287 "ENUM {" \
288 "Format_Invalid," \
289 "Format_Mono," \
290 "Format_MonoLSB," \
291 "Format_Indexed8," \
292 ...
293 "} QImage::Format;" \
294 );
295 \encode
296
297 If the content of \c enum is empty or contains the keyword \c AUTO, then
298 the \c tracepointgen tool tries to find the enumeration from header files.
299
300 \code
301 Q_TRACE_METADATA(qtcore, "ENUM { AUTO, RANGE User ... MaxUser } QEvent::Type;");
302 \encode
303
304 \sa qt_tracing
305*/
306#define Q_TRACE_METADATA(provider, metadata)
307
309
310#endif // QTRACE_P_H
\inmodule QtSql