From 78ef28b45fef95702ce16a21b333cd7205eeb82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4=C3=A4tt=C3=A4?= Date: Mon, 16 Jan 2023 13:06:39 +0200 Subject: [PATCH] CTF: Fix minor problems in the implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Check if trace location is writable - Call fclose only if file is opened - Convert metadata to QByteArray in one place. - Add constraint to array operator. Change-Id: Id01998fe8e754dab7a4b7d8ce1361ac822d01390 Reviewed-by: Antti Määttä (cherry picked from commit 1d0da1d683cc71ea14cfd85f5e9aa227d7f75762) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tracing/qctflib.cpp | 40 +++++++++++++++++++++++---------- src/corelib/tracing/qctflib_p.h | 2 +- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/corelib/tracing/qctflib.cpp b/src/corelib/tracing/qctflib.cpp index 2992d5f5ce8..f1a76d93acc 100644 --- a/src/corelib/tracing/qctflib.cpp +++ b/src/corelib/tracing/qctflib.cpp @@ -16,6 +16,8 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + Q_LOGGING_CATEGORY(lcDebugTrace, "qt.core.ctf"); static const size_t packetHeaderSize = 24 + 6 * 8 + 4; @@ -27,8 +29,9 @@ static const char traceMetadataTemplate[] = static const size_t traceMetadataSize = sizeof(traceMetadataTemplate); template -QByteArray &operator << (QByteArray &arr, T val) +QByteArray &operator<<(QByteArray &arr, T val) { + static_assert(std::is_arithmetic_v); arr.append((char *)&val, sizeof(val)); return arr; } @@ -55,19 +58,28 @@ QCtfLibImpl::QCtfLibImpl() qCWarning (lcDebugTrace) << "QTRACE_LOCATION not set"; return; } + + // Check if the location is writable FILE *file = nullptr; - file = fopen(qPrintable(location + QStringLiteral("/session.json")), "rb"); + file = fopen(qPrintable(location + "/metadata"_L1), "w+b"); if (!file) { - qCWarning (lcDebugTrace) << "unable to open session file: " << (location + QStringLiteral("/session.json")); + qCWarning (lcDebugTrace) << "Unable to write to location"; + return; + } + fclose(file); + + const QString filename = location + QStringLiteral("/session.json"); + file = fopen(qPrintable(filename), "rb"); + if (!file) { + qCWarning (lcDebugTrace) << "unable to open session file: " << filename; m_location = location; m_session.tracepoints.append(QStringLiteral("all")); m_session.name = QStringLiteral("default"); } else { - QByteArray data; fseek(file, 0, SEEK_END); long pos = ftell(file); fseek(file, 0, SEEK_SET); - data.resize(pos); + QByteArray data(pos, Qt::Uninitialized); long size = (long)fread(data.data(), pos, 1, file); fclose(file); if (size != 1) @@ -104,20 +116,23 @@ QCtfLibImpl::QCtfLibImpl() #else metadata.replace(QStringLiteral("$ENDIANNESS"), QStringLiteral("le")); #endif - writeMetadata(metadata.toUtf8(), true); + writeMetadata(metadata, true); m_timer.start(); } -void QCtfLibImpl::writeMetadata(const QByteArray &data, bool overwrite) +void QCtfLibImpl::writeMetadata(const QString &metadata, bool overwrite) { FILE *file = nullptr; - file = fopen(qPrintable(m_location + QStringLiteral("/metadata")), overwrite ? "w+b": "ab"); + file = fopen(qPrintable(m_location + "/metadata"_L1), overwrite ? "w+b": "ab"); if (!file) return; if (!overwrite) fputs("\n", file); + + // data contains zero at the end, hence size - 1. + const QByteArray data = metadata.toUtf8(); fwrite(data.data(), data.size() - 1, 1, file); fclose(file); } @@ -154,8 +169,8 @@ void QCtfLibImpl::writeCtfPacket(QCtfLibImpl::Channel &ch) fwrite(packet.data(), packet.size(), 1, file); ch.data.resize(packetSize - packet.size(), 0); fwrite(ch.data.data(), ch.data.size(), 1, file); + fclose(file); } - fclose(file); } QCtfLibImpl::~QCtfLibImpl() @@ -229,10 +244,10 @@ void QCtfLibImpl::doTracepoint(const QCtfTracePointEvent &point, const QByteArra } if (m_newAdditionalMetadata.size()) { for (const QString &name : m_newAdditionalMetadata) - writeMetadata(m_additionalMetadata[name]->metadata.toUtf8()); + writeMetadata(m_additionalMetadata[name]->metadata); m_newAdditionalMetadata.clear(); } - writeMetadata(priv->metadata.toUtf8()); + writeMetadata(priv->metadata); } timestamp = m_timer.nsecsElapsed(); } @@ -254,7 +269,8 @@ void QCtfLibImpl::doTracepoint(const QCtfTracePointEvent &point, const QByteArra sprintf(ch.channelName, "%s/channel_%d", qPrintable(m_location), m_threadIndices[thread]); FILE *f = nullptr; f = fopen(ch.channelName, "wb"); - fclose(f); + if (f) + fclose(f); ch.minTimestamp = ch.maxTimestamp = timestamp; ch.thread = thread; ch.threadIndex = m_threadIndices[thread]; diff --git a/src/corelib/tracing/qctflib_p.h b/src/corelib/tracing/qctflib_p.h index 7d773d962d8..4ad386e2091 100644 --- a/src/corelib/tracing/qctflib_p.h +++ b/src/corelib/tracing/qctflib_p.h @@ -85,7 +85,7 @@ private: static QCtfLibImpl *s_instance; QHash m_eventPrivs; void updateMetadata(const QCtfTracePointEvent &point); - void writeMetadata(const QByteArray &data, bool overwrite = false); + void writeMetadata(const QString &metadata, bool overwrite = false); static void writeCtfPacket(Channel &ch); static constexpr QUuid s_TraceUuid = QUuid(0x3e589c95, 0xed11, 0xc159, 0x42, 0x02, 0x6a, 0x9b, 0x02, 0x00, 0x12, 0xac);