Fix -trace build on Windows

The TraceLoggingValue template does not have overloads for Qt
types, so it was throwing multiple template instantiation errors
while trying to log the unknown types.
Fix it by serializing such types to QString using QDebug::toString,
and the logging this string.

Apart from that, fixes some other compiler errors on Windows build
with -trace enabled:
- implicit size_t to ULONG conversion
- complaints on std::min
- add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE to the generated
  *_tracepoints_p.h headers to fix the namespace build.

Task-number: QTBUG-97246
Fixes: QTBUG-97241
Pick-to: 6.2
Change-Id: Ifba134bab8d7fda7f1e30da9938e25cae813e1c6
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Ivan Solovev 2021-10-19 12:44:49 +02:00
parent 2a72f0f15d
commit 164e575673
2 changed files with 23 additions and 4 deletions

View File

@ -1682,7 +1682,7 @@ static void win_outputDebugString_helper(QStringView message)
} else {
wchar_t *messagePart = new wchar_t[maxOutputStringLength + 1];
for (qsizetype i = 0; i < message.length(); i += maxOutputStringLength) {
const qsizetype length = std::min(message.length() - i, maxOutputStringLength);
const qsizetype length = qMin(message.length() - i, maxOutputStringLength);
const qsizetype len = message.mid(i, length).toWCharArray(messagePart);
Q_ASSERT(len == length);
messagePart[len] = 0;

View File

@ -59,7 +59,8 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
switch (field.backendType) {
case Tracepoint::Field::QtString:
stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>("
<< name << ".utf16()), " << name << ".size(), \"" << name << "\")";
<< name << ".utf16()), static_cast<ULONG>(" << name << ".size()), \""
<< name << "\")";
return;
case Tracepoint::Field::QtByteArray:
stream << "TraceLoggingBinary(" << name << ".constData(), "
@ -77,6 +78,13 @@ static void writeEtwMacro(QTextStream &stream, const Tracepoint::Field &field)
case Tracepoint::Field::Pointer:
stream << "TraceLoggingPointer(" << name << ", \"" << name << "\")";
return;
case Tracepoint::Field::Unknown:
// Write down the previously stringified data (like we do for QString).
// The string is already created in writeWrapper().
// Variable name is name##Str.
stream << "TraceLoggingCountedWideString(reinterpret_cast<LPCWSTR>(" << name
<< "Str.utf16()), static_cast<ULONG>(" << name << "Str.size()), \"" << name << "\")";
return;
default:
break;
}
@ -181,8 +189,17 @@ static void writeWrapper(QTextStream &stream, const Tracepoint &tracepoint,
stream << "\n";
stream << "inline void trace_" << name << "(" << argList << ")\n"
<< "{\n"
<< " TraceLoggingWrite(" << provider << ", \"" << name << "\"";
<< "{\n";
// Convert all unknown types to QString's using QDebug.
// Note the naming convention: it's field.name##Str
for (const Tracepoint::Field &field : tracepoint.fields) {
if (field.backendType == Tracepoint::Field::Unknown) {
stream << " const QString " << field.name << "Str = QDebug::toString(" << field.name
<< ");\n";
}
}
stream << " TraceLoggingWrite(" << provider << ", \"" << name << "\"";
for (const Tracepoint::Field &field : tracepoint.fields) {
stream << ",\n";
@ -213,12 +230,14 @@ static void writeTracepoints(QTextStream &stream, const Provider &provider)
stream << "#if !defined(" << includeGuard << ") && !defined(TRACEPOINT_DEFINE)\n"
<< "#define " << includeGuard << "\n"
<< "QT_BEGIN_NAMESPACE\n"
<< "namespace QtPrivate {\n";
for (const Tracepoint &t : provider.tracepoints)
writeWrapper(stream, t, provider.name);
stream << "} // namespace QtPrivate\n"
<< "QT_END_NAMESPACE\n"
<< "#endif // " << includeGuard << "\n\n";
}