summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2020-08-31 17:01:52 +0200
committerMilian Wolff <milian.wolff@kdab.com>2020-09-11 10:31:33 +0000
commit7290c82c234451f1763deb718ab55d8147cd11a8 (patch)
treeb6e7a468794417654c958b8bee3befac25a228a0
parentad2d78340a959517abe90aacc707d7820896a5c5 (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.h3
-rw-r--r--app/perfsymboltable.cpp10
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;