summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-15 14:37:03 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-15 16:15:16 +0000
commiteb8cb4749e8b30a4bc25f2c2adeeabc8481fab4b (patch)
tree4e0e474d030ded2579646c9c79cf7c6dfe1f72ef
parent85edb324c7f4d3d504275f719cae40e840e6ebac (diff)
At least resolve the IP if neither fp nor dwarf info is available
This gives us some minimal information from perf.data recorded without --call-graph. Change-Id: I9aa021cae94d90d0e67f606de01c063da21484f0 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r--app/perfunwind.cpp23
-rw-r--r--app/perfunwind.h1
2 files changed, 21 insertions, 3 deletions
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 1af8885..ae13b92 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -198,6 +198,21 @@ Dwfl_Module *PerfUnwind::reportElf(quint64 ip, quint32 pid, const ElfInfo **info
}
}
+bool PerfUnwind::ipIsInKernelSpace(quint64 ip) const
+{
+ auto elfsIt = elfs.constFind(quint32(s_kernelPid));
+ if (elfsIt == elfs.constEnd())
+ return false;
+
+ const QMap<quint64, ElfInfo> &kernelElfs = elfsIt.value();
+ if (kernelElfs.isEmpty())
+ return false;
+
+ const auto last = (--kernelElfs.constEnd());
+ const auto first = kernelElfs.constBegin();
+ return first.key() <= ip && last.key() + last.value().length > ip;
+}
+
QDataStream &operator<<(QDataStream &stream, const PerfUnwind::Frame &frame)
{
return stream << frame.frame << frame.isKernel << frame.symbol << frame.elfFile
@@ -474,9 +489,11 @@ void PerfUnwind::analyze(const PerfRecordSample &sample)
if (sample.registerAbi() != 0) {
if (dwfl && sample.userStack().length() > 0)
unwindStack();
- // If nothing was found, at least look up the IP
- if (currentUnwind.frames.isEmpty())
- currentUnwind.frames.append(lookupSymbol(&currentUnwind, dwfl, sample.ip(), false));
+ }
+ // If nothing was found, at least look up the IP
+ if (currentUnwind.frames.isEmpty()) {
+ currentUnwind.frames.append(lookupSymbol(&currentUnwind, dwfl, sample.ip(),
+ ipIsInKernelSpace(sample.ip())));
}
QByteArray buffer;
diff --git a/app/perfunwind.h b/app/perfunwind.h
index b2601b6..f7a3520 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -111,6 +111,7 @@ public:
void comm(PerfRecordComm &comm);
Dwfl_Module *reportElf(quint64 ip, quint32 pid, const ElfInfo **info = 0) const;
+ bool ipIsInKernelSpace(quint64 ip) const;
void sample(const PerfRecordSample &sample);
void fork(const PerfRecordFork &sample);