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/*
20 * The Qt tracepoints API consists of only five macros:
21 *
22 * - Q_TRACE(tracepoint, args...)
23 * Fires 'tracepoint' if it is enabled.
24 *
25 * - Q_TRACE_EXIT(tracepoint, args...)
26 * Fires 'tracepoint' if it is enabled when the current scope exists.
27 *
28 * - Q_TRACE_SCOPE(tracepoint, args...)
29 * Wrapper around Q_TRACE/_EXIT to trace entry and exit. First it traces
30 * `${tracepoint}_entry` and then `${tracepoint}_exit` on scope exit.
31 *
32 * - Q_UNCONDITIONAL_TRACE(tracepoint, args...)
33 * Fires 'tracepoint' unconditionally: no check is performed to query
34 * whether 'tracepoint' is enabled.
35 *
36 * - Q_TRACE_ENABLED(tracepoint)
37 * Returns 'true' if 'tracepoint' is enabled; false otherwise.
38 *
39 * When using LTTNG, Q_TRACE, Q_UNCONDITIONAL_TRACE and Q_TRACE_ENABLED map
40 * ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
41 * respectively, described on the lttng-ust manpage (man 3 lttng-ust).
42 *
43 * On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
44 * amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
45 * wraps around TraceLoggingProviderEnabled().
46 *
47 * On HiTrace, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, each
48 * amounting to an OH_HiTrace_StartTraceEx() and OH_HiTrace_FinishTraceEx()
49 * pair, whereas Q_TRACE_ENABLED() reports whether a capture is running.
50 *
51 * A tracepoint provider is defined in a separate file, that follows the
52 * following format:
53 *
54 * tracepoint_name(arg_type arg_name, ...)
55 *
56 * For instance:
57 *
58 * qcoreapplication_ctor(int argc, const char * const argv)
59 * qcoreapplication_foo(int argc, const char[10] argv)
60 * qcoreapplication_baz(const char[len] some_string, unsigned int len)
61 * qcoreapplication_qstring(const QString &foo)
62 * qcoreapplication_qrect(const QRect &rect)
63 *
64 * The provider file is then parsed by src/tools/tracegen, which can be
65 * switched to output either ETW, LTTNG, HiTrace or CTF tracepoint definitions.
66 * The provider name is deduced to be basename(provider_file).
67 *
68 * To use the above (inside qtcore), you need to include
69 * <providername_tracepoints_p.h>. After that, the following call becomes
70 * possible:
71 *
72 * Q_TRACE(qcoreapplication_qrect, myRect);
73 *
74 * Currently, all C++ primitive non-pointer types are supported for
75 * arguments. Additionally, char * is supported, and is assumed to
76 * be a NULL-terminated string. Finally, the following subset of Qt types also
77 * currently supported:
78 *
79 * - QString
80 * - QByteArray
81 * - QUrl
82 * - QRect
83 * - QRectF
84 * - QSize
85 * - QSizeF
86 *
87 * Dynamic arrays are supported using the syntax illustrated by
88 * qcoreapplication_baz above.
89 *
90 * One can also add prefix for the generated providername_tracepoints_p.h file
91 * by specifying it inside brackets '{ }' in the tracepoints file. One can
92 * for example add forward declaration for a type:
93 *
94 * {
95 * QT_BEGIN_NAMESPACE
96 * class QEvent;
97 * QT_END_NAMESPACE
98 * }
99 *
100 * Metadata
101 *
102 * Metadata is used to add textual information for different types such
103 * as enums and flags. How this data is handled depends on the used backend.
104 * For ETW, the values are converted to text, for CTF and LTTNG they are used to add
105 * CTF enumerations, which are converted to text after tracing.
106 *
107 * Enumererations are specified using ENUM:
108 *
109 * ENUM {
110 * Enum0 = 0,
111 * Enum1 = 1,
112 * Enum2,
113 * RANGE(RangeEnum, 3 ... 10),
114 * } Name;
115 *
116 * Name must match to one of the enumerations used in the tracepoints. Range of values
117 * can be provided using RANGE(name, first ... last). All values must be unique.
118 *
119 * Flags are specified using FLAGS:
120 *
121 * FLAGS {
122 * Default = 0,
123 * Flag0 = 1,
124 * Flag1 = 2,
125 * Flag2 = 4,
126 * } Name;
127 *
128 * Name must match to one of the flags used in the tracepoints. Each value must be
129 * power of two and unique.
130 */
131
132#include <QtCore/private/qglobal_p.h>
133#include <QtCore/qscopeguard.h>
134
136
137/*! \internal
138 Tracing needs to be enabled using `configure -trace`. As explained
139 by `configure --help`, the backend can be given as an optional argument.
140 Currently supported backends include [LTTNG](https://lttng.org) on Linux,
141 [ETW](https://learn.microsoft.com/en-us/windows/win32/etw/event-tracing-portal)
142 on Windows, and [CTF](https://diamon.org/ctf/) (common trace format)
143 as a cross-platform solution.
144
145 \section Qt API
146
147 The Qt tracepoints API consists of five macros:
148
149 Macro | Behavior
150 ------------------------------------------- | -----------------------------
151 Q_TRACE(tracepoint, args...) | Fires 'tracepoint' if it is enabled.
152 Q_TRACE_EXIT(tracepoint, args...) | Fires 'tracepoint' if it is enabled when the current scope exists.
153 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.
154 Q_UNCONDITIONAL_TRACE(tracepoint, args...) | Fires 'tracepoint' unconditionally: no check is performed to query whether 'tracepoint' is enabled.
155 Q_TRACE_ENABLED(tracepoint) | Returns 'true' if 'tracepoint' is enabled; false otherwise.
156
157 When using LTTNG, Q_TRACE(), Q_UNCONDITIONAL_TRACE() and Q_TRACE_ENABLED()
158 map ultimately to tracepoint(), do_tracepoint() and tracepoint_enabled(),
159 respectively, described on the `lttng-ust` manpage (man 3 lttng-ust).
160
161 On ETW, Q_TRACE() and Q_UNCONDITIONAL_TRACE() are equivalent, ultimately
162 amounting to a call to TraceLoggingWrite(), whereas Q_TRACE_ENABLED()
163 wraps around TraceLoggingProviderEnabled().
164
165 A tracepoint provider is defined in a separate file, that follows the
166 following format:
167
168 \code
169 tracepoint_name(arg_type arg_name, ...)
170 \endcode
171
172 For instance:
173
174 \code
175 qcoreapplication_ctor(int argc, const char * const argv)
176 qcoreapplication_foo(int argc, const char[10] argv)
177 qcoreapplication_baz(const char[len] some_string, unsigned int len)
178 qcoreapplication_qstring(const QString &foo)
179 qcoreapplication_qrect(const QRect &rect)
180 \endcode
181
182 The provider file is then parsed by src/tools/tracegen (which gets built to
183 \c libexec/tracegen), which can be switched to output ETW, CTF or LTTNG
184 tracepoint definitions. The provider name is deduced to be
185 `basename(provider_file)`.
186
187 To use the above (inside qtcore), you need `include <providername_tracepoints_p.h>`.
188 After that, the following call becomes possible:
189
190 \code
191 Q_TRACE(qcoreapplication_qrect, myRect);
192 \endcode
193
194 Currently, all C++ primitive non-pointer types are supported for arguments.
195 Additionally, `char *` is supported, and is assumed to be a
196 nullptr-terminated string. Finally, the following subset of Qt types are
197 also currently supported:
198
199 - QString
200 - QByteArray
201 - QUrl
202 - QRect
203 - QRectF
204 - QSize
205 - QSizeF
206
207 Dynamic arrays are supported using the syntax illustrated by
208 \c qcoreapplication_baz above.
209
210 One can also add prefix for the generated \c providername_tracepoints_p.h
211 file by specifying it inside brackets `{ }` in the tracepoints file.
212 One can for example add a forward declaration for a type:
213
214 \code
215 {
216 QT_BEGIN_NAMESPACE
217 class QEvent;
218 QT_END_NAMESPACE
219 }
220 \endcode
221
222 \section Metadata
223
224 Metadata is used to add textual information for different types such as
225 enums and flags. How this data is handled depends on the used backend.
226 For ETW, the values are converted to text; for CTF and LTTNG they are used
227 to add CTF enumerations, which are converted to text after tracing.
228
229 Enumerations are specified using ENUM:
230
231 \code
232 ENUM {
233 Enum0 = 0,
234 Enum1 = 1,
235 Enum2,
236 RANGE(RangeEnum, 3 ... 10),
237 } Name;
238 \endcode
239
240 Name must match to one of the enumerations used in the tracepoints. Range of values
241 can be provided using RANGE(name, first ... last). All values must be unique.
242
243 Flags are specified using FLAGS:
244
245 \code
246 FLAGS {
247 Default = 0,
248 Flag0 = 1,
249 Flag1 = 2,
250 Flag2 = 4,
251 } Name;
252 \endcode
253
254 Name must match to one of the flags used in the tracepoints. Each value must be
255 power of two and unique.
256
257 The Qt tracepoints can also be defined directly in the source files using
258 the macros Q_TRACE_INSTRUMENT(), Q_TRACE_PARAM_REPLACE(), Q_TRACE_POINT(),
259 Q_TRACE_PREFIX() and Q_TRACE_METADATA(). If using these macros, the
260 tracepoints file is automatically generated using the `tracepointgen` tool.
261 The tool scans the input files for these macros. These macros are ignored
262 during compile time. Both automatic generation and manually specifying
263 tracepoints in a file can't be done at the same time for the same provider.
264
265 \note Traces are not object-oriented. Often, the purpose of a specific
266 tracepoint is to record the fact that a function was called; but you
267 cannot see on which object instance a method was called, unless some
268 information about the object (such as its pointer or ID) is given as one of
269 the arguments to the trace macro. So far, we have not standardized that.
270*/
271
272#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
273# define Q_HAS_TRACEPOINTS 1
274# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
275# define Q_TRACE_EXIT(x, ...)
276 const auto qTraceExit_ ## x ## __COUNTER__ = qScopeGuard([&]() { Q_TRACE(x, __VA_ARGS__); });
277# define Q_TRACE_SCOPE(x, ...)
278 Q_TRACE(x ## _entry, __VA_ARGS__);
279 Q_TRACE_EXIT(x ## _exit);
280# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
281# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
282#else
283# define Q_HAS_TRACEPOINTS 0
284
285/*! \internal
286 This macro fires \a tracepoint if it is enabled.
287*/
288# define Q_TRACE(x, ...)
289
290/*! \internal
291 This macro fires \a tracepoint if it is enabled when the current scope exits.
292*/
293# define Q_TRACE_EXIT(x, ...)
294
295/*! \internal
296 This macro is a wrapper around Q_TRACE/_EXIT to trace entry and exit.
297 First it traces \c {${tracepoint}_entry}, and then \c {${tracepoint}_exit} on scope exit.
298*/
299# define Q_TRACE_SCOPE(x, ...)
300
301/*! \internal
302 This macro fires \a tracepoint unconditionally: no check is performed to
303 query whether \c tracepoint is enabled.
304*/
305# define Q_UNCONDITIONAL_TRACE(x, ...)
306
307/*! \internal
308 This macro returns \c true if \a tracepoint is enabled, or \c false otherwise.
309*/
310# define Q_TRACE_ENABLED(x) false
311#endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
312
313/*! \internal
314 Generate entry/exit tracepoints for a function. For example, member function
315
316 \code
317 void SomeClass::method(int param1, float param2)
318 {
319 ...
320 }
321 \endcode
322
323 converted to use tracepoints:
324
325 \code
326 void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, float param2)
327 {
328 Q_TRACE_SCOPE(SomeClass_method, param1, param2);
329 ...
330 }
331 \encode
332
333 generates the following tracepoints in the \c provider.tracepoints file:
334
335 \code
336 SomeClass_method_entry(int param1, float param2)
337 SomeClass_method_exit()
338 \encode
339
340 \sa qt_tracing
341*/
342#define Q_TRACE_INSTRUMENT(provider)
343
344/*! \internal
345 Can be used with Q_TRACE_INSTRUMENT to replace parameter type \a in with
346 type \a out. If a parameter type is not supported by the \c tracegen tool,
347 one can use this to change it to another supported type.
348
349 \code
350 void Q_TRACE_INSTRUMENT(provider) SomeClass::method(int param1, UserType param2)
351 {
352 Q_TRACE_PARAM_REPLACE(UserType, QString);
353 Q_TRACE_SCOPE(SomeClass_method, param1, param2.toQString());
354 }
355 \encode
356
357 \sa qt_tracing
358*/
359#define Q_TRACE_PARAM_REPLACE(in, out)
360
361/*! \internal
362 Manually specify tracepoint for the provider. \a tracepoint is the full
363 name of the tracepoint, and there can be zero or more parameters.
364
365 \code
366 Q_TRACE_POINT(provider, SomeClass_function_entry, int param1, int param2);
367 \encode
368
369 generates the following tracepoint:
370
371 \code
372 SomeClass_function_entry(int param1, int param2)
373 \encode
374
375 \sa qt_tracing
376*/
377#define Q_TRACE_POINT(provider, tracepoint, ...)
378
379/*! \internal
380 Provides a prefix for the tracepoint. Multiple prefixes can be specified
381 for the same provider in different files; they are all concatenated into
382 one in the \c provider.tracepoints file.
383
384 \code
385 Q_TRACE_PREFIX(provider,
386 "QT_BEGIN_NAMESPACE" \
387 "class QEvent;" \
388 "QT_END_NAMESPACE")
389 \encode
390
391 \sa qt_tracing
392*/
393#define Q_TRACE_PREFIX(provider, prefix)
394
395/*! \internal
396 Provides metadata for the tracepoint provider.
397
398 \code
399 Q_TRACE_METADATA(qtgui,
400 "ENUM {" \
401 "Format_Invalid," \
402 "Format_Mono," \
403 "Format_MonoLSB," \
404 "Format_Indexed8," \
405 ...
406 "} QImage::Format;" \
407 );
408 \encode
409
410 If the content of \c enum is empty or contains the keyword \c AUTO, then
411 the \c tracepointgen tool tries to find the enumeration from header files.
412
413 \code
414 Q_TRACE_METADATA(qtcore, "ENUM { AUTO, RANGE User ... MaxUser } QEvent::Type;");
415 \encode
416
417 \sa qt_tracing
418*/
419#define Q_TRACE_METADATA(provider, metadata)
420
422
423#endif // QTRACE_P_H
\inmodule QtSql