diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2020-08-31 17:01:52 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2020-09-11 10:31:33 +0000 |
commit | 7290c82c234451f1763deb718ab55d8147cd11a8 (patch) | |
tree | b6e7a468794417654c958b8bee3befac25a228a0 | |
parent | ad2d78340a959517abe90aacc707d7820896a5c5 (diff) |
Only call dwfl_attach_state with user-level CPU registers and stack
For samples with frame pointer or LBR call chains, we may not have
the CPU registers or stack information available. Under such
circumstances we would spam the command line with repeated warnings
of the form:
```
<pid> failed to attach state Couldn't find architecture of any ELF
```
Prevent that by checking whether the sample has register and stack
information available and only attach dwfl state then.
Note that symbol resolution and inline-frame resolution is independent
of the dwfl_attach_state call - that really is only required for stack
unwinding.
Based on a patch by vtoropov, thanks!
Fixes: https://github.com/kdab/hotspot/issues/178
Change-Id: I8b88ee5b97d3e9d3ded82a17c4487d01add6d5ca
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | app/perfdata.h | 3 | ||||
-rw-r--r-- | app/perfsymboltable.cpp | 10 |
2 files changed, 12 insertions, 1 deletions
diff --git a/app/perfdata.h b/app/perfdata.h index fcabe1f..942de34 100644 --- a/app/perfdata.h +++ b/app/perfdata.h @@ -307,7 +307,7 @@ enum PerfEventType { PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, - PERF_RECORD_HEADER_EVENT_TYPE = 65, /* depreceated */ + PERF_RECORD_HEADER_EVENT_TYPE = 65, /* deprecated */ PERF_RECORD_HEADER_TRACING_DATA = 66, PERF_RECORD_HEADER_BUILD_ID = 67, PERF_RECORD_FINISHED_ROUND = 68, @@ -379,6 +379,7 @@ public: quint32 cpu() const { return m_sampleId.cpu(); } quint16 size() const { return m_header.size; } quint16 misc() const { return m_header.misc; } + quint64 type() const { return m_sampleId.sampleType(); } protected: PerfRecord(const PerfEventHeader *header, quint64 sampleType, bool sampleIdAll); diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index 27cf569..ce44a47 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -935,6 +935,16 @@ Dwfl *PerfSymbolTable::attachDwfl(void *arg) if (static_cast<pid_t>(m_pid) == dwfl_pid(m_dwfl)) return m_dwfl; // Already attached, nothing to do + // only attach state when we have the required information for stack unwinding + // for normal symbol resolution and inline frame resolution this is not needed + // most notably, this isn't needed for frame pointer callchains + PerfUnwind::UnwindInfo *unwindInfo = static_cast<PerfUnwind::UnwindInfo *>(arg); + const auto sampleType = unwindInfo->sample->type(); + const auto hasSampleRegsUser = (sampleType & PerfEventAttributes::SAMPLE_REGS_USER); + const auto hasSampleStackUser = (sampleType & PerfEventAttributes::SAMPLE_STACK_USER); + if (!hasSampleRegsUser || !hasSampleStackUser) + return nullptr; + if (!dwfl_attach_state(m_dwfl, m_firstElf.elf(), m_pid, &threadCallbacks, arg)) { qWarning() << m_pid << "failed to attach state" << dwfl_errmsg(dwfl_errno()); return nullptr; |