diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2017-09-15 18:28:50 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2017-09-29 08:27:08 +0000 |
commit | 12c7370bf7a8c762e756f4465443ef4a04a3abe4 (patch) | |
tree | b3f00daab0bda8dd838f12273329a57be339db57 | |
parent | 5499916b0d2af6a54bab04732bed9bc6e7129522 (diff) |
Handle tracing data header event
The content size is incorrect in this case, and naively skipping it
will prevent us from reading the following events.
Change-Id: Iedde4937576236b953d3d52c6faf388b9ca6f7dc
Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
-rw-r--r-- | app/app.pro | 19 | ||||
-rw-r--r-- | app/perfdata.cpp | 15 | ||||
-rw-r--r-- | elfutils.pri | 17 | ||||
-rw-r--r-- | tests/auto/auto.pro | 3 | ||||
-rw-r--r-- | tests/auto/auto.qbs | 2 | ||||
-rw-r--r-- | tests/auto/perfdata/perfdata.pro | 38 | ||||
-rw-r--r-- | tests/auto/perfdata/perfdata.qbs | 34 | ||||
-rw-r--r-- | tests/auto/perfdata/perfdata.qrc | 5 | ||||
-rw-r--r-- | tests/auto/perfdata/probe.data.stream | bin | 0 -> 18676 bytes | |||
-rw-r--r-- | tests/auto/perfdata/tst_perfdata.cpp | 69 |
10 files changed, 182 insertions, 20 deletions
diff --git a/app/app.pro b/app/app.pro index b0df268..2811982 100644 --- a/app/app.pro +++ b/app/app.pro @@ -9,24 +9,7 @@ CONFIG += c++11 console CONFIG -= app_bundle include(../paths.pri) - -!isEmpty(ELFUTILS_INSTALL_DIR) { - INCLUDEPATH += $$ELFUTILS_INSTALL_DIR/include $$ELFUTILS_INSTALL_DIR/include/elfutils - LIBS += -L$$ELFUTILS_INSTALL_DIR/lib -} else:unix { - INCLUDEPATH += /usr/include/elfutils -} - -LIBS += -ldw -lelf - -win32 { - LIBS += -leu_compat -} - -linux-g++*:!isEmpty(PERFPARSER_ELFUTILS_INSTALLDIR) { - RPATH = $$relative_path($$PERFPARSER_ELFUTILS_INSTALLDIR, $$PERFPARSER_APP_INSTALLDIR) - QMAKE_LFLAGS += -Wl,-z,origin \'-Wl,-rpath,\$\$ORIGIN/$$RPATH\' -} +include(../elfutils.pri) DESTDIR = $$PERFPARSER_APP_DESTDIR target.path = $$PERFPARSER_APP_INSTALLDIR diff --git a/app/perfdata.cpp b/app/perfdata.cpp index d73f31c..94f9fa2 100644 --- a/app/perfdata.cpp +++ b/app/perfdata.cpp @@ -132,6 +132,21 @@ PerfData::ReadStatus PerfData::processEvents(QDataStream &stream) m_destination->exit(exit); break; } + case PERF_RECORD_HEADER_TRACING_DATA: { + if (contentSize == 4) { + // The content is actually another 4 byte integer, + // describing the size of the real content that follows. + quint32 content; + stream >> content; + stream.skipRawData(content); + } else { + // Maybe someone with a brain will fix this eventually ... + // then we'll hit this branch. + qWarning() << "HEADER_TRACING_DATA with unexpected contentSize" << contentSize; + stream.skipRawData(contentSize); + } + break; + } case PERF_RECORD_FINISHED_ROUND: { m_destination->finishedRound(); if (contentSize != 0) { diff --git a/elfutils.pri b/elfutils.pri new file mode 100644 index 0000000..37f2e0c --- /dev/null +++ b/elfutils.pri @@ -0,0 +1,17 @@ +!isEmpty(ELFUTILS_INSTALL_DIR) { + INCLUDEPATH += $$ELFUTILS_INSTALL_DIR/include $$ELFUTILS_INSTALL_DIR/include/elfutils + LIBS += -L$$ELFUTILS_INSTALL_DIR/lib +} else:unix { + INCLUDEPATH += /usr/include/elfutils +} + +LIBS += -ldw -lelf + +win32 { + LIBS += -leu_compat +} + +linux-g++*:!isEmpty(PERFPARSER_ELFUTILS_INSTALLDIR) { + RPATH = $$relative_path($$PERFPARSER_ELFUTILS_INSTALLDIR, $$PERFPARSER_APP_INSTALLDIR) + QMAKE_LFLAGS += -Wl,-z,origin \'-Wl,-rpath,\$\$ORIGIN/$$RPATH\' +} diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index a5dcc9b..bd5fb62 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS = \ elfmap \ - kallsyms + kallsyms \ + perfdata diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index a815e4f..08ea2fe 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -4,6 +4,6 @@ Project { name: "PerfParserAutotests" condition: project.withAutotests references: [ - "elfmap", "kallsyms" + "elfmap", "kallsyms", "perfdata" ] } diff --git a/tests/auto/perfdata/perfdata.pro b/tests/auto/perfdata/perfdata.pro new file mode 100644 index 0000000..689a387 --- /dev/null +++ b/tests/auto/perfdata/perfdata.pro @@ -0,0 +1,38 @@ +include(../../../elfutils.pri) + +QT += testlib +QT -= gui + +CONFIG += testcase strict_flags warn_on + +INCLUDEPATH += ../../../app + +TARGET = tst_perfdata + +SOURCES += \ + tst_perfdata.cpp \ + ../../../app/perfattributes.cpp \ + ../../../app/perfdata.cpp \ + ../../../app/perfelfmap.cpp \ + ../../../app/perffeatures.cpp \ + ../../../app/perffilesection.cpp \ + ../../../app/perfheader.cpp \ + ../../../app/perfkallsyms.cpp \ + ../../../app/perfregisterinfo.cpp \ + ../../../app/perfsymboltable.cpp \ + ../../../app/perfunwind.cpp + +HEADERS += \ + ../../../app/perfattributes.h \ + ../../../app/perfdata.h \ + ../../../app/perfelfmap.h \ + ../../../app/perffeatures.h \ + ../../../app/perffilesection.h \ + ../../../app/perfheader.h \ + ../../../app/perfkallsyms.h \ + ../../../app/perfregisterinfo.h \ + ../../../app/perfsymboltable.h \ + ../../../app/perfunwind.h + +RESOURCES += \ + perfdata.qrc diff --git a/tests/auto/perfdata/perfdata.qbs b/tests/auto/perfdata/perfdata.qbs new file mode 100644 index 0000000..a50f4ee --- /dev/null +++ b/tests/auto/perfdata/perfdata.qbs @@ -0,0 +1,34 @@ +import qbs + +QtcAutotest { + name: "PerfData Autotest" + + cpp.includePaths: ["/usr/include/elfutils"] + cpp.dynamicLibraries: ["dw", "elf"] + + files: [ + "perfdata.qrc", + "tst_perfdata.cpp", + "../../../app/perfattributes.cpp", + "../../../app/perfattributes.h", + "../../../app/perfdata.cpp", + "../../../app/perfdata.h", + "../../../app/perfelfmap.cpp", + "../../../app/perfelfmap.h", + "../../../app/perffeatures.cpp", + "../../../app/perffeatures.h", + "../../../app/perffilesection.cpp", + "../../../app/perffilesection.h", + "../../../app/perfheader.cpp", + "../../../app/perfheader.h", + "../../../app/perfkallsyms.cpp", + "../../../app/perfkallsyms.h", + "../../../app/perfregisterinfo.cpp", + "../../../app/perfregisterinfo.h", + "../../../app/perfsymboltable.cpp", + "../../../app/perfsymboltable.h", + "../../../app/perfunwind.cpp", + "../../../app/perfunwind.h" + ] + cpp.includePaths: base.concat(["../../../app"]) +} diff --git a/tests/auto/perfdata/perfdata.qrc b/tests/auto/perfdata/perfdata.qrc new file mode 100644 index 0000000..1b5d91a --- /dev/null +++ b/tests/auto/perfdata/perfdata.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>probe.data.stream</file> + </qresource> +</RCC> diff --git a/tests/auto/perfdata/probe.data.stream b/tests/auto/perfdata/probe.data.stream Binary files differnew file mode 100644 index 0000000..b8de1ee --- /dev/null +++ b/tests/auto/perfdata/probe.data.stream diff --git a/tests/auto/perfdata/tst_perfdata.cpp b/tests/auto/perfdata/tst_perfdata.cpp new file mode 100644 index 0000000..820dae9 --- /dev/null +++ b/tests/auto/perfdata/tst_perfdata.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Enterprise Perf Profiler Add-on. +** +** GNU General Public License Usage +** This file may be used under the terms of the GNU General Public License +** version 3 as published by the Free Software Foundation and appearing in +** the file LICENSE.GPLv3 included in the packaging of this file. Please +** review the following information to ensure the GNU General Public License +** requirements will be met: https://www.gnu.org/licenses/gpl.html. +** +** If you have questions regarding the use of this file, please use +** contact form at http://www.qt.io/contact-us +** +****************************************************************************/ + +#include <QObject> +#include <QTest> +#include <QBuffer> +#include <QSignalSpy> +#include <QDebug> + +#include "perfdata.h" +#include "perfunwind.h" + +class TestPerfData : public QObject +{ + Q_OBJECT +private slots: + void testTraceDataHeaderEvent(); +}; + +void TestPerfData::testTraceDataHeaderEvent() +{ + QBuffer output; + QFile input(":/probe.data.stream"); + QVERIFY(input.open(QIODevice::ReadOnly)); + QVERIFY(output.open(QIODevice::WriteOnly)); + + PerfUnwind unwind(&output, QDir::rootPath(), PerfUnwind::defaultDebugInfoPath(), QString(), + QString(), true); + PerfHeader header(&input); + PerfAttributes attributes; + PerfData data(&input, &unwind, &header, &attributes); + + QSignalSpy spy(&data, SIGNAL(finished())); + connect(&header, &PerfHeader::finished, &data, &PerfData::read); + header.read(); + QCOMPARE(spy.count(), 1); + + unwind.flushEventBuffer(); + + const PerfUnwind::Stats stats = unwind.stats(); + QCOMPARE(stats.numSamples, 1u); + QCOMPARE(stats.numMmaps, 120u); + QCOMPARE(stats.numRounds, 1u); + QCOMPARE(stats.numBufferFlushes, 1u); + QCOMPARE(stats.numTimeViolatingSamples, 0u); + QCOMPARE(stats.numTimeViolatingMmaps, 0u); + QCOMPARE(stats.maxBufferSize, 15488u); + QCOMPARE(stats.maxTime, 13780586522722ull); +} + +QTEST_GUILESS_MAIN(TestPerfData) + +#include "tst_perfdata.moc" |