summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-04-20 12:37:37 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-04-23 07:23:51 +0000
commit6556a15d50ddf95a9888375c906c59d2c0f68c6f (patch)
treea778ec2a286f4362f4c5a5c4bc0990c892039e66
parent88d5bd3ea36fbf810c1f49b767be435f123759bf (diff)
Don't duplicate the first user frame when resolving callchains
The first callchain entry frequently is meta info with IP > PERF_CONTEXT_MAX. The current sample's IP is always different from that. Change-Id: I0b407331767ea482cd4e66ba0c8efade29089eb9 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--app/perfunwind.cpp21
1 files changed, 11 insertions, 10 deletions
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 94b68ef..756dd5d 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -395,6 +395,7 @@ void PerfUnwind::unwindStack()
void PerfUnwind::resolveCallchain()
{
bool isKernel = false;
+ bool addedUserFrames = false;
PerfSymbolTable *symbols = symbolTable(m_currentUnwind.sample->pid());
for (int i = 0; i < m_currentUnwind.sample->callchain().length(); ++i) {
quint64 ip = m_currentUnwind.sample->callchain()[i];
@@ -417,21 +418,21 @@ void PerfUnwind::resolveCallchain()
qWarning() << "invalid callchain context" << ip;
return;
}
- }
-
- // sometimes it skips the first user frame.
- if (i == 0 && !isKernel && ip != m_currentUnwind.sample->ip()) {
- symbols->attachDwfl(&m_currentUnwind);
- m_currentUnwind.frames.append(symbols->lookupFrame(
- m_currentUnwind.sample->ip(), false,
- &m_currentUnwind.isInterworking));
- }
+ } else {
+ if (!addedUserFrames && !isKernel && ip != m_currentUnwind.sample->ip()) {
+ // sometimes it skips the first user frame.
+ symbols->attachDwfl(&m_currentUnwind);
+ m_currentUnwind.frames.append(symbols->lookupFrame(
+ m_currentUnwind.sample->ip(), false,
+ &m_currentUnwind.isInterworking));
+ }
- if (ip <= PERF_CONTEXT_MAX) {
symbols->attachDwfl(&m_currentUnwind);
m_currentUnwind.frames.append(symbols->lookupFrame(
ip, isKernel,
&m_currentUnwind.isInterworking));
+ if (!isKernel)
+ addedUserFrames = true;
}
if (symbols->cacheIsDirty())