summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-05-17 13:10:05 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-05-17 13:21:33 +0000
commit01b4d7d8c98a13df10ce22dd86188806b99205f3 (patch)
tree501700a189879e7ac5402dd492e840ac677c0401
parent9f43fc9b48535a9204c17fabf9e542dcd1052ccf (diff)
Don't repeatedly report unsuitable modules for an address
dwfl may disagree with our mmap events about the length of a module. If dwfl considers the module to be shorter, the address we are looking for may fall in an area that's not covered by the reported module. In that case we should not try to report the same module again the next time we catch this address. We already know that it doesn't fit, after all. Task-number: QTCREATORBUG-20427 Change-Id: I852dd39f0a53fe7bc1bde149efa3541d0fc7b8ba Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
-rw-r--r--app/perfelfmap.cpp15
-rw-r--r--app/perfelfmap.h4
-rw-r--r--app/perfsymboltable.cpp7
3 files changed, 23 insertions, 3 deletions
diff --git a/app/perfelfmap.cpp b/app/perfelfmap.cpp
index 3e0a6b4..6ba72ba 100644
--- a/app/perfelfmap.cpp
+++ b/app/perfelfmap.cpp
@@ -114,7 +114,20 @@ PerfElfMap::ElfInfo PerfElfMap::findElf(quint64 ip) const
return ElfInfo();
}
- return (i->addr + i->length > ip) ? *i : ElfInfo();
+ if (i->dwflStart < i->dwflEnd)
+ return (i->dwflStart <= ip && i->dwflEnd > ip) ? *i : ElfInfo();
+ else
+ return (i->addr + i->length > ip) ? *i : ElfInfo();
+}
+
+void PerfElfMap::updateElf(quint64 addr, quint64 dwflStart, quint64 dwflEnd)
+{
+ auto i = std::upper_bound(m_elfs.begin(), m_elfs.end(), addr, SortByAddr());
+ Q_ASSERT(i != m_elfs.begin());
+ --i;
+ Q_ASSERT(i->addr == addr);
+ i->dwflStart = dwflStart;
+ i->dwflEnd = dwflEnd;
}
bool PerfElfMap::isAddressInRange(quint64 addr) const
diff --git a/app/perfelfmap.h b/app/perfelfmap.h
index a9af9f9..2396046 100644
--- a/app/perfelfmap.h
+++ b/app/perfelfmap.h
@@ -68,6 +68,9 @@ public:
quint64 addr;
quint64 length;
quint64 pgoff;
+
+ quint64 dwflStart = 0;
+ quint64 dwflEnd = 0;
};
bool registerElf(quint64 addr, quint64 len, quint64 pgoff,
@@ -75,6 +78,7 @@ public:
const QByteArray &originalFileName = {},
const QByteArray &originalPath = {});
ElfInfo findElf(quint64 ip) const;
+ void updateElf(quint64 addr, quint64 dwflStart, quint64 dwflEnd);
bool isEmpty() const
{
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 2cc7107..644e947 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -486,9 +486,12 @@ Dwfl_Module *PerfSymbolTable::reportElf(const PerfElfMap::ElfInfo& info)
} else {
// set symbol table as user data, cf. find_debuginfo callback in perfunwind.cpp
void** userData;
- dwfl_module_info(ret, &userData, nullptr, nullptr, nullptr, nullptr,
- nullptr, nullptr);
+ Dwarf_Addr start = 0;
+ Dwarf_Addr end = 0;
+
+ dwfl_module_info(ret, &userData, &start, &end, nullptr, nullptr, nullptr, nullptr);
*userData = this;
+ m_elfs.updateElf(info.addr, start, end);
}
const int reportEnd = dwfl_report_end(m_dwfl, NULL, NULL);
Q_ASSERT(reportEnd == 0);