diff options
author | Lieven Hey <lieven.hey@kdab.com> | 2021-08-23 13:20:07 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2022-06-08 20:18:01 +0000 |
commit | a1cf7a0fdb9bdf853cb59ae289f377d2e3e92776 (patch) | |
tree | c9e194c1fee5edd60e116c9ef74ea184132d8cf7 | |
parent | e50bc913563e445888f08de03007ff91bcd5dd1e (diff) |
improve debug symbol discovery
If elfutils fails to find the debug symbols, the perfparser tries to
find it by checking first in /usr/lib/ then in .debug and then in
/usr/lib/debug. This causes some problems if the debug file has the same
name as the library itself. In this case the algorithm stops at
/usr/lib/ and returns the wrong file.
To prevent this I reorder the algorithm to first check in .debug then in
/usr/lib/debug and then in /usr/lib/
I also changed how the algorithm searches inside /usr/lib/debug. Some
distros (e.g. Ubuntu) uses shorted path names so the debug file for
/usr/lib/x86_64-linux-gnu/libc-2.31.so is located in
/usr/lib/debug/lib/x86_64-linux-gnu/libc-2.31.so. To find the file the
/usr/lib/debug/usr/lib and /usr/lib/debug/lib are searched.
fixes KDAB/hotspot#265
fixes KDAB/hotspot#128
Change-Id: Iab2283819f947e89e9a933e66dfb7f45ff9156e1
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | app/perfsymboltable.cpp | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp index 7fb19ec..27b54ad 100644 --- a/app/perfsymboltable.cpp +++ b/app/perfsymboltable.cpp @@ -473,33 +473,61 @@ static QFileInfo findDebugInfoFile(const QString &root, const QString &file, QFileInfo debugLinkFile; + // try in .debug folder if (!folder.isEmpty()) { - debugLinkFile.setFile(dir, folder + QDir::separator() + debugLinkString); + debugLinkFile.setFile(dir.path() + QDir::separator() + folder + QDir::separator() + QLatin1String(".debug") + + QDir::separator() + debugLinkString); if (debugLinkFile.isFile()) return debugLinkFile; } - debugLinkFile.setFile(dir, file + QDir::separator() + debugLinkString); + debugLinkFile.setFile(dir.path() + QDir::separator() + file + QDir::separator() + QLatin1String(".debug") + + QDir::separator() + debugLinkString); if (debugLinkFile.isFile()) return debugLinkFile; - // try again in .debug folder - if (!folder.isEmpty()) { - debugLinkFile.setFile(dir, folder + QDir::separator() + QLatin1String(".debug") - + QDir::separator() + debugLinkString); - if (debugLinkFile.isFile()) + // try again in /usr/lib/debug folder + // some distros use for example /usr/lib/debug/lib (ubuntu) and some use /usr/lib/debug/usr/lib (fedora) + const auto usr = QDir::separator() + QLatin1String("usr") + QDir::separator(); + auto folderWithoutUsr = folder; + folderWithoutUsr.replace(usr, QDir::separator()); + + // make sure both (/usr/ and /) are searched + for (const auto& path : {folderWithoutUsr, usr + folderWithoutUsr}) { + debugLinkFile.setFile(dir.path() + QDir::separator() + QLatin1String("usr") + QDir::separator() + + QLatin1String("lib") + QDir::separator() + QLatin1String("debug") + QDir::separator() + + path + QDir::separator() + debugLinkString); + + if (debugLinkFile.isFile()) { return debugLinkFile; + } } - debugLinkFile.setFile(dir, file + QDir::separator() + QLatin1String(".debug") - + QDir::separator() + debugLinkString); - if (debugLinkFile.isFile()) + debugLinkFile.setFile(dir.path() + QDir::separator() + QLatin1String("usr") + QDir::separator() + + QLatin1String("lib") + QDir::separator() + QLatin1String("debug") + QDir::separator() + + folder + QDir::separator() + debugLinkString); + + if (debugLinkFile.isFile()) { return debugLinkFile; + } - // try again in /usr/lib/debug folder - debugLinkFile.setFile(dir, QLatin1String("usr") + QDir::separator() + QLatin1String("lib") - + QDir::separator() + QLatin1String("debug") + QDir::separator() + folder - + QDir::separator() + debugLinkString); + debugLinkFile.setFile(dir, + QLatin1String("usr") + QDir::separator() + QLatin1String("lib") + QDir::separator() + + QLatin1String("debug") + QDir::separator() + debugLinkString); + + if (debugLinkFile.isFile()) { + return debugLinkFile; + } + + // try the default files + if (!folder.isEmpty()) { + debugLinkFile.setFile(dir.path() + QDir::separator() + folder + QDir::separator() + debugLinkString); + if (debugLinkFile.isFile()) { + return debugLinkFile; + } + } + + debugLinkFile.setFile(dir.path() + QDir::separator() + file + QDir::separator() + debugLinkString); return debugLinkFile; } |