summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2017-11-14 13:15:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2017-11-15 10:12:08 +0000
commit141dbed197c1ab28c22f7378dc19d76576fce5e8 (patch)
tree0ba42cc9aefe0e149ea9655912b648fd7a30bfc2
parente41b16ea55b739bfaf7b2802bc38bb8d9a3c5cff (diff)
Read the contentSize of a stack sample only if section size > 0
Otherwise we crash on any samples in kernel space. Change-Id: Id194302c7ba2e0fcc2f7d79d56eed6e1d1796308 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--app/perfdata.cpp15
-rw-r--r--tests/auto/perfdata/contentsize.databin0 -> 40688 bytes
-rw-r--r--tests/auto/perfdata/perfdata.qrc1
-rw-r--r--tests/auto/perfdata/tst_perfdata.cpp33
4 files changed, 42 insertions, 7 deletions
diff --git a/app/perfdata.cpp b/app/perfdata.cpp
index 1305d21..20253c4 100644
--- a/app/perfdata.cpp
+++ b/app/perfdata.cpp
@@ -554,17 +554,18 @@ QDataStream &operator>>(QDataStream &stream, PerfRecordSample &record)
} while (sectionSize > intMax);
stream.skipRawData(static_cast<int>(sectionSize));
sectionSize = 0;
+ stream.skipRawData(sizeof(quint64)); // skip contentSize
} else if (sectionSize > 0) {
record.m_userStack.resize(static_cast<int>(sectionSize));
stream.readRawData(record.m_userStack.data(), record.m_userStack.size());
- }
- quint64 contentSize;
- stream >> contentSize;
- if (contentSize > sectionSize)
- qWarning() << "Truncated stack snapshot" << contentSize << sectionSize;
- else
- record.m_userStack.resize(static_cast<int>(contentSize));
+ quint64 contentSize;
+ stream >> contentSize;
+ if (contentSize > sectionSize)
+ qWarning() << "Truncated stack snapshot" << contentSize << sectionSize;
+ else
+ record.m_userStack.resize(static_cast<int>(contentSize));
+ }
}
if (sampleType & PerfEventAttributes::SAMPLE_WEIGHT)
diff --git a/tests/auto/perfdata/contentsize.data b/tests/auto/perfdata/contentsize.data
new file mode 100644
index 0000000..0c1db67
--- /dev/null
+++ b/tests/auto/perfdata/contentsize.data
Binary files differ
diff --git a/tests/auto/perfdata/perfdata.qrc b/tests/auto/perfdata/perfdata.qrc
index 1b5d91a..8df083c 100644
--- a/tests/auto/perfdata/perfdata.qrc
+++ b/tests/auto/perfdata/perfdata.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>probe.data.stream</file>
+ <file>contentsize.data</file>
</qresource>
</RCC>
diff --git a/tests/auto/perfdata/tst_perfdata.cpp b/tests/auto/perfdata/tst_perfdata.cpp
index 820dae9..08ef47d 100644
--- a/tests/auto/perfdata/tst_perfdata.cpp
+++ b/tests/auto/perfdata/tst_perfdata.cpp
@@ -31,6 +31,7 @@ class TestPerfData : public QObject
Q_OBJECT
private slots:
void testTraceDataHeaderEvent();
+ void testContentSize();
};
void TestPerfData::testTraceDataHeaderEvent()
@@ -48,6 +49,7 @@ void TestPerfData::testTraceDataHeaderEvent()
QSignalSpy spy(&data, SIGNAL(finished()));
connect(&header, &PerfHeader::finished, &data, &PerfData::read);
+
header.read();
QCOMPARE(spy.count(), 1);
@@ -64,6 +66,37 @@ void TestPerfData::testTraceDataHeaderEvent()
QCOMPARE(stats.maxTime, 13780586522722ull);
}
+void TestPerfData::testContentSize()
+{
+ QString file(":/contentsize.data");
+
+ QBuffer output;
+ QFile input(file);
+
+ QVERIFY(input.open(QIODevice::ReadOnly));
+ QVERIFY(output.open(QIODevice::WriteOnly));
+
+ // Don't try to load any system files. They are not the same as the ones we use to report.
+ PerfUnwind unwind(&output, ":/", QString(), 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.finalize();
+
+ QObject::connect(&data, &PerfData::error, []() {
+ QFAIL("PerfData reported an error");
+ });
+
+ QCOMPARE(unwind.stats().numSamples, 69u);
+}
+
QTEST_GUILESS_MAIN(TestPerfData)
#include "tst_perfdata.moc"