diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-03-15 14:37:03 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-03-15 16:15:16 +0000 |
commit | eb8cb4749e8b30a4bc25f2c2adeeabc8481fab4b (patch) | |
tree | 4e0e474d030ded2579646c9c79cf7c6dfe1f72ef | |
parent | 85edb324c7f4d3d504275f719cae40e840e6ebac (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.cpp | 23 | ||||
-rw-r--r-- | app/perfunwind.h | 1 |
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(¤tUnwind, dwfl, sample.ip(), false)); + } + // If nothing was found, at least look up the IP + if (currentUnwind.frames.isEmpty()) { + currentUnwind.frames.append(lookupSymbol(¤tUnwind, 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); |