summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2017-02-04 21:44:37 +0100
committerMilian Wolff <milian.wolff@kdab.com>2017-02-09 19:44:16 +0000
commitb46fb02d2def932f8d34d9f5f4ce9e76c5a0b5f2 (patch)
treedf3b27e6dcbe43b17e63a2836e6bf1aa2ec41d2d
parent5cfb70c88add63221db1d44c7d69bb5350d7c27d (diff)
Include features in output
The features allow clients to display information about the system where the perf file was recorded. It also includes the actual cmdline that was used to record the data and more information about the contents of the perf data file. Change-Id: I0492f00511d3be8298109050549aa47945f89cea Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--app/main.cpp3
-rw-r--r--app/perffeatures.cpp56
-rw-r--r--app/perffeatures.h23
-rw-r--r--app/perfunwind.cpp27
-rw-r--r--app/perfunwind.h2
5 files changed, 111 insertions, 0 deletions
diff --git a/app/main.cpp b/app/main.cpp
index 748c109..d981389 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -195,6 +195,9 @@ int main(int argc, char *argv[])
features.read(infile.data(), &header);
infile->seek(filePos);
+ // first send features, as it may contain better event descriptions
+ unwind.features(features);
+
const auto& attrs = attributes.attributes();
for (auto it = attrs.begin(), end = attrs.end(); it != end; ++it) {
unwind.attr(PerfRecordAttr(it.value(), {it.key()}));
diff --git a/app/perffeatures.cpp b/app/perffeatures.cpp
index ed87f9f..bf8ed87 100644
--- a/app/perffeatures.cpp
+++ b/app/perffeatures.cpp
@@ -155,6 +155,16 @@ QDataStream &operator>>(QDataStream &stream, PerfBuildId &buildId)
return stream;
}
+QDataStream &operator<<(QDataStream &stream, const PerfBuildId::BuildId &buildId)
+{
+ return stream << buildId.pid << buildId.id << buildId.fileName;
+}
+
+QDataStream &operator<<(QDataStream &stream, const PerfBuildId &buildId)
+{
+ return stream << buildId.buildIds;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfEventHeader &header)
{
return stream >> header.type >> header.misc >> header.size;
@@ -178,6 +188,11 @@ QDataStream &operator>>(QDataStream &stream, PerfNrCpus &nrCpus)
return stream >> nrCpus.online >> nrCpus.available;
}
+QDataStream &operator<<(QDataStream &stream, const PerfNrCpus &nrCpus)
+{
+ return stream << nrCpus.online << nrCpus.available;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfTotalMem &totalMem)
{
return stream >> totalMem.totalMem;
@@ -240,6 +255,11 @@ QDataStream &operator>>(QDataStream &stream, PerfCpuTopology &cpuTopology)
return stream;
}
+QDataStream &operator<<(QDataStream &stream, const PerfCpuTopology &cpuTopology)
+{
+ return stream << cpuTopology.siblingCores << cpuTopology.siblingThreads;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfNumaTopology &numaTopology)
{
quint32 numNodes;
@@ -255,6 +275,16 @@ QDataStream &operator>>(QDataStream &stream, PerfNumaTopology &numaTopology)
return stream;
}
+QDataStream &operator<<(QDataStream &stream, const PerfNumaTopology::NumaNode &node)
+{
+ return stream << node.nodeId << node.memTotal << node.memFree << node.topology;
+}
+
+QDataStream &operator<<(QDataStream &stream, const PerfNumaTopology &numaTopology)
+{
+ return stream << numaTopology.nodes;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfBranchStack &branchStack)
{
// Doesn't really exist.
@@ -263,6 +293,12 @@ QDataStream &operator>>(QDataStream &stream, PerfBranchStack &branchStack)
return stream;
}
+QDataStream &operator<<(QDataStream &stream, const PerfBranchStack &branchStack)
+{
+ Q_UNUSED(branchStack);
+ return stream;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfPmuMappings &pmuMappings)
{
quint32 numPmus;
@@ -278,6 +314,16 @@ QDataStream &operator>>(QDataStream &stream, PerfPmuMappings &pmuMappings)
return stream;
}
+QDataStream &operator<<(QDataStream &stream, const PerfPmuMappings::Pmu &pmu)
+{
+ return stream << pmu.type << pmu.name;
+}
+
+QDataStream &operator<<(QDataStream &stream, const PerfPmuMappings &pmuMappings)
+{
+ return stream << pmuMappings.pmus;
+}
+
QDataStream &operator>>(QDataStream &stream, PerfGroupDesc &groupDesc)
{
quint32 numGroups;
@@ -293,3 +339,13 @@ QDataStream &operator>>(QDataStream &stream, PerfGroupDesc &groupDesc)
}
return stream;
}
+
+QDataStream &operator<<(QDataStream &stream, const PerfGroupDesc::GroupDesc &groupDesc)
+{
+ return stream << groupDesc.name << groupDesc.leaderIndex << groupDesc.numMembers;
+}
+
+QDataStream &operator<<(QDataStream &stream, const PerfGroupDesc &groupDesc)
+{
+ return stream << groupDesc.groupDescs;
+}
diff --git a/app/perffeatures.h b/app/perffeatures.h
index 384a465..4a4c9a3 100644
--- a/app/perffeatures.h
+++ b/app/perffeatures.h
@@ -56,6 +56,7 @@ struct PerfBuildId {
};
QDataStream &operator>>(QDataStream &stream, PerfBuildId &buildId);
+QDataStream &operator<<(QDataStream &stream, const PerfBuildId &buildId);
struct PerfStringFeature {
QByteArray value;
@@ -69,6 +70,7 @@ struct PerfNrCpus {
};
QDataStream &operator>>(QDataStream &stream, PerfNrCpus &numCpus);
+QDataStream &operator<<(QDataStream &stream, const PerfNrCpus &numCpus);
struct PerfTotalMem {
quint64 totalMem;
@@ -102,6 +104,7 @@ struct PerfCpuTopology {
};
QDataStream &operator>>(QDataStream &stream, PerfCpuTopology &cpuTopology);
+QDataStream &operator<<(QDataStream &stream, const PerfCpuTopology &cpuTopology);
struct PerfNumaTopology {
@@ -116,11 +119,13 @@ struct PerfNumaTopology {
};
QDataStream &operator>>(QDataStream &stream, PerfNumaTopology &numaTopology);
+QDataStream &operator<<(QDataStream &stream, const PerfNumaTopology &numaTopology);
struct PerfBranchStack {
};
QDataStream &operator>>(QDataStream &stream, PerfBranchStack &branchStack);
+QDataStream &operator<<(QDataStream &stream, const PerfBranchStack &branchStack);
struct PerfPmuMappings {
@@ -132,6 +137,7 @@ struct PerfPmuMappings {
};
QDataStream &operator>>(QDataStream &stream, PerfPmuMappings &pmuMappings);
+QDataStream &operator<<(QDataStream &stream, const PerfPmuMappings &pmuMappings);
struct PerfGroupDesc {
@@ -145,6 +151,7 @@ struct PerfGroupDesc {
};
QDataStream &operator>>(QDataStream &stream, PerfGroupDesc &groupDesc);
+QDataStream &operator<<(QDataStream &stream, const PerfGroupDesc &groupDesc);
class PerfFeatures
{
@@ -156,6 +163,22 @@ public:
const QByteArray &architecture() const { return m_arch.value; }
void setArchitecture(const QByteArray &arch) { m_arch.value = arch; }
+ PerfBuildId buildId() const { return m_buildId; }
+ QByteArray hostName() const { return m_hostName.value; }
+ QByteArray osRelease() const { return m_osRelease.value; }
+ QByteArray version() const { return m_version.value; }
+ PerfNrCpus nrCpus() const { return m_nrCpus; }
+ QByteArray cpuDesc() const { return m_cpuDesc.value; }
+ QByteArray cpuId() const { return m_cpuId.value; }
+ quint64 totalMem() const { return m_totalMem.totalMem; }
+ QList<QByteArray> cmdline() const { return m_cmdline.cmdline; }
+ PerfEventDesc eventDesc() const { return m_eventDesc; }
+ PerfCpuTopology cpuTopology() const { return m_cpuTopology; }
+ PerfNumaTopology numaTopology() const { return m_numaToplogy; }
+ PerfBranchStack branchStack() const { return m_branchStack; }
+ PerfPmuMappings pmuMappings() const { return m_pmuMappings; }
+ PerfGroupDesc groupDesc() const { return m_groupDesc; }
+
private:
void createFeature(QIODevice *device, QDataStream::ByteOrder byteOrder,
const PerfFileSection &section, PerfHeader::Feature featureId);
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index d793525..25022be 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -158,6 +158,33 @@ void PerfUnwind::lost(const PerfRecordLost &lost)
sendBuffer(buffer);
}
+void PerfUnwind::features(const PerfFeatures &features)
+{
+ const auto &eventDescs = features.eventDesc().eventDescs;
+ for (const auto &desc : eventDescs) {
+ resolveAttr(desc.attrs, desc.name);
+ }
+
+ QByteArray buffer;
+ QDataStream(&buffer, QIODevice::WriteOnly) << static_cast<quint8>(FeaturesDefinition)
+ << features.hostName()
+ << features.osRelease()
+ << features.version()
+ << features.architecture()
+ << features.nrCpus()
+ << features.cpuDesc()
+ << features.cpuId()
+ << features.totalMem()
+ << features.cmdline()
+ << features.buildId()
+ << features.cpuTopology()
+ << features.numaTopology()
+ << features.branchStack()
+ << features.pmuMappings()
+ << features.groupDesc();
+ sendBuffer(buffer);
+}
+
Dwfl_Module *PerfUnwind::reportElf(quint64 ip, quint32 pid, quint64 timestamp)
{
auto symbols = symbolTable(pid);
diff --git a/app/perfunwind.h b/app/perfunwind.h
index b6bc990..19361f3 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -57,6 +57,7 @@ public:
AttributesDefinition,
StringDefinition,
LostDefinition,
+ FeaturesDefinition,
InvalidType
};
@@ -116,6 +117,7 @@ public:
void comm(const PerfRecordComm &comm);
void attr(const PerfRecordAttr &attr);
void lost(const PerfRecordLost &lost);
+ void features(const PerfFeatures &features);
Dwfl_Module *reportElf(quint64 ip, quint32 pid, quint64 timestamp);
bool ipIsInKernelSpace(quint64 ip) const;