Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
lttng.cpp
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 GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "lttng.h"
5#include "provider.h"
6#include "helpers.h"
7#include "panic.h"
8#include "qtheaders.h"
9
10#include <qfile.h>
11#include <qfileinfo.h>
12#include <qtextstream.h>
13#include <qdebug.h>
14
15static void writeCtfMacro(QTextStream &stream, const Provider &provider, const Tracepoint::Field &field)
16{
17 const QString &paramType = field.paramType;
18 const QString &name = field.name;
19 const QString &seqLen = field.seqLen;
20 const int arrayLen = field.arrayLen;
21
22 if (arrayLen > 0) {
23 if (paramType == QStringLiteral("double") || paramType == QStringLiteral("float")) {
24 const char *newline = nullptr;
25 for (int i = 0; i < arrayLen; i++) {
26 stream << newline;
27 stream << "ctf_float(" <<paramType << ", " << name << "_" << QString::number(i) << ", "
28 << name << "[" << QString::number(i) << "]" << ")";
29 newline = "\n ";
30 }
31
32 } else {
33 stream << "ctf_array(" <<paramType << ", "
34 << name << ", " << name << ", " << arrayLen << ")";
35 }
36 return;
37 }
38
39 switch (field.backendType) {
41 stream << "ctf_sequence(" << paramType
42 << ", " << name << ", " << name
43 << ", unsigned int, " << seqLen << ")";
44 return;
47 stream << "ctf_integer(" << paramType << ", " << name << ", " << name << ")";
48 return;
51 stream << "ctf_integer_hex(" << paramType << ", " << name << ", " << name << ")";
52 return;
54 stream << "ctf_float(" << paramType << ", " << name << ", " << name << ")";
55 return;
57 stream << "ctf_string(" << name << ", " << name << ")";
58 return;
60 stream << "ctf_string(" << name << ", " << name << ".toUtf8().constData())";
61 return;
63 stream << "ctf_sequence(const char, " << name << ", "
64 << name << ".constData(), unsigned int, " << name << ".size())";
65 return;
67 stream << "ctf_string(" << name << ", " << name << ".toString().toUtf8().constData())";
68 return;
70 stream << "ctf_integer(int, QRect_" << name << "_x, " << name << ".x()) "
71 << "ctf_integer(int, QRect_" << name << "_y, " << name << ".y()) "
72 << "ctf_integer(int, QRect_" << name << "_width, " << name << ".width()) "
73 << "ctf_integer(int, QRect_" << name << "_height, " << name << ".height()) ";
74 return;
76 stream << "ctf_float(double, QSizeF_" << name << "_width, " << name << ".width()) "
77 << "ctf_float(double, QSizeF_" << name << "_height, " << name << ".height()) ";
78 return;
80 stream << "ctf_float(double, QRectF_" << name << "_x, " << name << ".x()) "
81 << "ctf_float(double, QRectF_" << name << "_y, " << name << ".y()) "
82 << "ctf_float(double, QRectF_" << name << "_width, " << name << ".width()) "
83 << "ctf_float(double, QRectF_" << name << "_height, " << name << ".height()) ";
84 return;
86 stream << "ctf_integer(int, QSize_" << name << "_width, " << name << ".width()) "
87 << "ctf_integer(int, QSize_" << name << "_height, " << name << ".height()) ";
88 return;
90 stream << "ctf_enum(" << provider.name << ", " << typeToTypeName(paramType) << ", int, " << name << ", " << name << ") ";
91 return;
93 stream << "ctf_sequence(const char , " << name << ", "
94 << name << ".constData(), unsigned int, " << name << ".size())";
95 return;
97 panic("Cannot deduce CTF type for '%s %s", qPrintable(paramType), qPrintable(name));
98 break;
99 }
100}
101
102static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider)
103{
105 const QString guard = includeGuard(fileName);
106
107 stream << "#undef TRACEPOINT_PROVIDER\n";
108 stream << "#define TRACEPOINT_PROVIDER " << provider.name << "\n";
109 stream << "\n";
110
111 // include prefix text or qt headers only once
112 stream << "#if !defined(" << guard << ")\n";
113 stream << qtHeaders();
114 stream << "\n";
115 if (!provider.prefixText.isEmpty())
116 stream << provider.prefixText.join(u'\n') << "\n\n";
117 stream << "#endif\n\n";
118
119 /* the first guard is the usual one, the second is required
120 * by LTTNG to force the re-evaluation of TRACEPOINT_* macros
121 */
122 stream << "#if !defined(" << guard << ") || defined(TRACEPOINT_HEADER_MULTI_READ)\n";
123
124 stream << "#define " << guard << "\n\n"
125 << "#undef TRACEPOINT_INCLUDE\n"
126 << "#define TRACEPOINT_INCLUDE \"" << fileName << "\"\n\n";
127
128 stream << "#include <lttng/tracepoint.h>\n\n";
129
130 const QString namespaceGuard = guard + QStringLiteral("_USE_NAMESPACE");
131 stream << "#if !defined(" << namespaceGuard << ")\n"
132 << "#define " << namespaceGuard << "\n"
133 << "QT_USE_NAMESPACE\n"
134 << "#endif // " << namespaceGuard << "\n\n";
135}
136
138{
139 stream << "\n";
140 stream << "#endif // " << includeGuard(fileName) << "\n"
141 << "#include <lttng/tracepoint-event.h>\n"
142 << "#include <private/qtrace_p.h>\n";
143}
144
146 const Tracepoint &tracepoint, const Provider &provider)
147{
148 const QString argList = formatFunctionSignature(tracepoint.args);
149 const QString paramList = formatParameterList(provider, tracepoint.args, tracepoint.fields, LTTNG);
150 const QString &name = tracepoint.name;
151 const QString includeGuard = QStringLiteral("TP_%1_%2").arg(provider.name).arg(name).toUpper();
152
153 /* prevents the redefinion of the inline wrapper functions
154 * once LTTNG recursively includes this header file
155 */
156 stream << "\n"
157 << "#ifndef " << includeGuard << "\n"
158 << "#define " << includeGuard << "\n"
159 << "QT_BEGIN_NAMESPACE\n"
160 << "namespace QtPrivate {\n";
161
162 stream << "inline void trace_" << name << "(" << argList << ")\n"
163 << "{\n"
164 << " tracepoint(" << provider.name << ", " << name << paramList << ");\n"
165 << "}\n";
166
167 stream << "inline void do_trace_" << name << "(" << argList << ")\n"
168 << "{\n"
169 << " do_tracepoint(" << provider.name << ", " << name << paramList << ");\n"
170 << "}\n";
171
172 stream << "inline bool trace_" << name << "_enabled()\n"
173 << "{\n"
174 << " return tracepoint_enabled(" << provider.name << ", " << name << ");\n"
175 << "}\n";
176
177 stream << "} // namespace QtPrivate\n"
178 << "QT_END_NAMESPACE\n"
179 << "#endif // " << includeGuard << "\n\n";
180}
181
182static void writeTracepoint(QTextStream &stream, const Provider &provider,
183 const Tracepoint &tracepoint, const QString &providerName)
184{
185 stream << "TRACEPOINT_EVENT(\n"
186 << " " << providerName << ",\n"
187 << " " << tracepoint.name << ",\n"
188 << " TP_ARGS(";
189
190 const char *comma = nullptr;
191
192 for (int i = 0; i < tracepoint.args.size(); i++) {
193 const auto &arg = tracepoint.args[i];
194 const auto &field = tracepoint.fields[i];
195 if (field.backendType == Tracepoint::Field::FlagType)
196 stream << comma << "QByteArray, " << arg.name;
197 else
198 stream << comma << arg.type << ", " << arg.name;
199 comma = ", ";
200 }
201
202 stream << "),\n"
203 << " TP_FIELDS(";
204
205 const char *newline = nullptr;
206
207 for (const Tracepoint::Field &f : tracepoint.fields) {
208 stream << newline;
209 writeCtfMacro(stream, provider, f);
210 newline = "\n ";
211 }
212
213 stream << ")\n)\n\n";
214}
215
216static void writeEnums(QTextStream &stream, const Provider &provider)
217{
218 for (const auto &e : provider.enumerations) {
219 stream << "TRACEPOINT_ENUM(\n"
220 << " " << provider.name << ",\n"
221 << " " << typeToTypeName(e.name) << ",\n"
222 << " TP_ENUM_VALUES(\n";
223 QList<int> handledValues;
224 for (const auto &v : e.values) {
225 if (v.range > 0) {
226 stream << " ctf_enum_range(\"" << v.name << "\", " << v.value << ", " << v.range << ")\n";
227 } else if (!handledValues.contains(v.value)) {
228 stream << " ctf_enum_value(\"" << aggregateListValues(v.value, e.values) << "\", " << v.value << ")\n";
229 handledValues.append(v.value);
230 }
231 }
232 stream << " )\n)\n\n";
233 }
234}
235
236static void writeFlags(QTextStream &stream, const Provider &provider)
237{
238 for (const auto &f : provider.flags) {
239 stream << "TRACEPOINT_ENUM(\n"
240 << " " << provider.name << ",\n"
241 << " " << typeToTypeName(f.name) << ",\n"
242 << " TP_ENUM_VALUES(\n";
243 QList<int> handledValues;
244 for (const auto &v : f.values) {
245 if (!handledValues.contains(v.value)) {
246 stream << " ctf_enum_value(\"" << aggregateListValues(v.value, f.values) << "\", " << v.value << ")\n";
247 handledValues.append(v.value);
248 }
249 }
250 stream << " )\n)\n\n";
251 }
252
253 // converters
254 const QString includeGuard = QStringLiteral("TP_%1_CONVERTERS").arg(provider.name).toUpper();
255 stream << "\n"
256 << "#ifndef " << includeGuard << "\n"
257 << "#define " << includeGuard << "\n";
258 stream << "QT_BEGIN_NAMESPACE\n";
259 stream << "namespace QtPrivate {\n";
260 for (const auto &f : provider.flags) {
261 stream << "inline QByteArray trace_convert_" << typeToTypeName(f.name) << "(" << f.name << " val)\n";
262 stream << "{\n";
263 stream << " QByteArray ret;\n";
264 stream << " if (val == 0) { ret.append((char)0); return ret; }\n";
265
266 for (const auto &v : f.values) {
267 if (!v.value)
268 continue;
269 stream << " if (val & " << (1 << (v.value - 1)) << ") { ret.append((char)" << v.value << "); };\n";
270 }
271 stream << " return ret;\n";
272 stream << "}\n";
273
274 }
275 stream << "} // namespace QtPrivate\n"
276 << "QT_END_NAMESPACE\n\n"
277 << "#endif // " << includeGuard << "\n\n";
278}
279
280static void writeTracepoints(QTextStream &stream, const Provider &provider)
281{
282 for (const Tracepoint &t : provider.tracepoints) {
283 writeTracepoint(stream, provider, t, provider.name);
284 writeWrapper(stream, t, provider);
285 }
286}
287
288void writeLttng(QFile &file, const Provider &provider)
289{
291
293
294 writePrologue(stream, fileName, provider);
295 writeEnums(stream, provider);
296 writeFlags(stream, provider);
297 writeTracepoints(stream, provider);
299}
300
QString fileName() const
\inmodule QtCore
Definition qfile.h:93
QString fileName() const override
Returns the name set by setFileName() or to the QFile constructors.
Definition qfile.cpp:277
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
void writeCommonPrologue(QTextStream &stream)
Definition helpers.cpp:9
QString typeToTypeName(const QString &name)
Definition helpers.cpp:14
QString includeGuard(const QString &filename)
Definition helpers.cpp:20
QString formatFunctionSignature(const QList< Tracepoint::Argument > &args)
Definition helpers.cpp:50
QString formatParameterList(const Provider &provider, const QList< Tracepoint::Argument > &args, const QList< Tracepoint::Field > &fields, ParamType type)
Definition helpers.cpp:57
@ LTTNG
Definition helpers.h:14
static QString aggregateListValues(int value, const QList< T > &list)
Definition helpers.h:27
static void writeEpilogue(QTextStream &stream, const QString &fileName)
Definition lttng.cpp:137
void writeLttng(QFile &file, const Provider &provider)
Definition lttng.cpp:288
static void writeEnums(QTextStream &stream, const Provider &provider)
Definition lttng.cpp:216
static void writeTracepoint(QTextStream &stream, const Provider &provider, const Tracepoint &tracepoint, const QString &providerName)
Definition lttng.cpp:182
static void writeWrapper(QTextStream &stream, const Tracepoint &tracepoint, const Provider &provider)
Definition lttng.cpp:145
static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider)
Definition lttng.cpp:102
static void writeCtfMacro(QTextStream &stream, const Provider &provider, const Tracepoint::Field &field)
Definition lttng.cpp:15
static void writeFlags(QTextStream &stream, const Provider &provider)
Definition lttng.cpp:236
static void writeTracepoints(QTextStream &stream, const Provider &provider)
Definition lttng.cpp:280
void panic(const char *fmt,...)
Definition panic.cpp:10
#define tracepoint(provider, name,...)
Definition qctf_p.h:214
EGLStreamKHR stream
GLsizei const GLfloat * v
[13]
GLfloat GLfloat f
GLuint name
GLdouble GLdouble t
Definition qopenglext.h:243
SSL_CTX int void * arg
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
const char * qtHeaders()
Definition qtheaders.cpp:6
QFile file
[0]
QStringList prefixText
Definition provider.h:85
QList< TraceEnum > enumerations
Definition provider.h:86
QList< TraceFlags > flags
Definition provider.h:87
QString name
Definition provider.h:83
QList< Tracepoint > tracepoints
Definition provider.h:84
QString paramType
Definition provider.h:43