summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-06-19 14:57:05 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-06-20 11:16:02 +0000
commit42b4d2752cffdb9cf2e395788f979fa35b07f9af (patch)
tree81a605840749ce5081a94c555fb1d2d4192c16cc
parentb9a998065902d3364c7132bc0cdd48718e6d4ef8 (diff)
If dwfl_module_getsrc fails, iterate CUs to find source file/linev4.7.2v4.7.1v4.7.0-rc1v4.7.04.7
Some ELF objects have .debug_info and .debug_line sections, but no .debug_aranges. dwfl_module_getsrc doesn't like this and gives up. We can, however, do better. The information is all there, we just need to get hold of the right CU. The iteration is expensive, but as we cache the resulting locations, it's tolerable. In case there is no .debug_info at all, this won't iterate, as the Dwarf object won't be found in the first place. Task-number: QTCREATORBUG-20441 Change-Id: I9846397d1e930ba5f25ccfa9748542a198f0f2a4 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--app/perfsymboltable.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index 986a463..0b217bb 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -608,6 +608,32 @@ int PerfSymbolTable::lookupFrame(Dwarf_Addr ip, bool isKernel,
const QByteArray file = dwfl_lineinfo(srcLine, nullptr, &addressLocation.line,
&addressLocation.column, nullptr, nullptr);
addressLocation.file = m_unwind->resolveString(file);
+ } else {
+ Dwarf_Addr bias = 0;
+ if (Dwarf *dwarf = dwfl_module_getdwarf(mod, &bias)) {
+ const quint64 adjusted = addressLocation.address - bias;
+ size_t headerSize = 0;
+ Dwarf_Off nextOffset = 0;
+ for (Dwarf_Off offset = 0;
+ dwarf_nextcu(dwarf, offset, &nextOffset, &headerSize,
+ nullptr, nullptr, nullptr) == 0;
+ offset = nextOffset) {
+ Dwarf_Die cudieMemory;
+ Dwarf_Die *cudie = dwarf_offdie(dwarf, offset + headerSize, &cudieMemory);
+
+ if (!cudie || !dwarf_haspc(cudie, adjusted))
+ continue;
+
+ if (Dwarf_Line *line = dwarf_getsrc_die(cudie, adjusted)) {
+ const QByteArray file = dwarf_linesrc(line, nullptr, nullptr);
+ addressLocation.file = m_unwind->resolveString(file);
+ dwarf_lineno(line, &addressLocation.line);
+ dwarf_linecol(line, &addressLocation.column);
+ }
+
+ break;
+ }
+ }
}
if (off == addressLocation.address) {// no symbol found