summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2022-07-07 16:55:27 +0200
committerMilian Wolff <milian.wolff@kdab.com>2022-07-25 14:00:57 +0000
commitd432bc71926b1a855e54baabf5216b09b266b5fc (patch)
tree6089cb44e5e7c91f567f8ec4c7716d36616c7020
parent96b145c998d60d4c563abea0442c1549e263c3da (diff)
Optionally report debuginfod download progress
When available, report progress for ongoing debuginfod downloads. This is useful as otherwise users might think the application has stopped working and is frozen. This only works with elfutils that contains the new dwfl_get_debuginfod_client API, which is not yet released. Change-Id: Iffce1b31f4245977c8aa624b6c852fdfa1840d4e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--CMakeLists.txt4
-rw-r--r--app/CMakeLists.txt5
-rw-r--r--app/perfsymboltable.cpp17
-rw-r--r--app/perfunwind.cpp9
-rw-r--r--app/perfunwind.h2
5 files changed, 37 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3038294..0684030 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,5 +22,9 @@ set_package_properties(LibDDemangle PROPERTIES
URL "https://github.com/lievenhey/d_demangler"
TYPE RUNTIME)
+include(CheckSymbolExists)
+set(CMAKE_REQUIRED_LIBRARIES elfutils::dw elfutils::elf)
+check_symbol_exists(dwfl_get_debuginfod_client "libdwfl.h" HAVE_DWFL_GET_DEBUGINFOD_CLIENT)
+
add_subdirectory(app)
add_subdirectory(tests)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 4107a11..ccb8f2d 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -31,6 +31,11 @@ if (Zstd_FOUND)
target_compile_definitions(perfparser_lib PUBLIC HAVE_ZSTD=1)
endif()
+if (HAVE_DWFL_GET_DEBUGINFOD_CLIENT)
+ target_link_libraries(perfparser_lib PRIVATE elfutils::debuginfod)
+ target_compile_definitions(perfparser_lib PRIVATE HAVE_DWFL_GET_DEBUGINFOD_CLIENT=1)
+endif()
+
add_qtc_executable(perfparser
DEPENDS
perfparser_lib
diff --git a/app/perfsymboltable.cpp b/app/perfsymboltable.cpp
index ee6d9a6..4fbc6bb 100644
--- a/app/perfsymboltable.cpp
+++ b/app/perfsymboltable.cpp
@@ -34,6 +34,10 @@
#include <dwarf.h>
+#if HAVE_DWFL_GET_DEBUGINFOD_CLIENT
+#include <debuginfod.h>
+#endif
+
PerfSymbolTable::PerfSymbolTable(qint32 pid, Dwfl_Callbacks *callbacks, PerfUnwind *parent) :
m_perfMapFile(QDir::tempPath() + QDir::separator()
+ QString::fromLatin1("perf-%1.map").arg(pid)),
@@ -52,6 +56,19 @@ PerfSymbolTable::PerfSymbolTable(qint32 pid, Dwfl_Callbacks *callbacks, PerfUnwi
m_dwfl = dwfl_begin(m_callbacks);
+#if HAVE_DWFL_GET_DEBUGINFOD_CLIENT
+ auto client = dwfl_get_debuginfod_client(m_dwfl);
+ debuginfod_set_user_data(client, this);
+ debuginfod_set_progressfn(client, [](debuginfod_client* client, long numerator, long denominator) {
+ auto self = reinterpret_cast<PerfSymbolTable*>(debuginfod_get_user_data(client));
+ auto url = self->m_unwind->resolveString(QByteArray(debuginfod_get_url(client)));
+ self->m_unwind->sendDebugInfoDownloadProgress(url, numerator, denominator);
+ // NOTE: eventually we could add a back channel to allow the user to cancel an ongoing download
+ // to do so, we'd have to return any non-zero value here then
+ return 0;
+ });
+#endif
+
dwfl_report_begin(m_dwfl);
// "DWFL can not be used until this function returns 0"
diff --git a/app/perfunwind.cpp b/app/perfunwind.cpp
index 2d3e9a3..e9d2b74 100644
--- a/app/perfunwind.cpp
+++ b/app/perfunwind.cpp
@@ -875,6 +875,15 @@ void PerfUnwind::sendProgress(float percent)
sendBuffer(buffer);
}
+void PerfUnwind::sendDebugInfoDownloadProgress(qint32 url, qint64 numerator, qint64 denominator)
+{
+ QByteArray buffer;
+ buffer.reserve(21);
+ QDataStream(&buffer, QIODevice::WriteOnly) << static_cast<quint8>(DebugInfoDownloadProgress)
+ << url << numerator << denominator;
+ sendBuffer(buffer);
+}
+
qint32 PerfUnwind::resolveString(const QByteArray& string)
{
if (string.isEmpty())
diff --git a/app/perfunwind.h b/app/perfunwind.h
index ff355b1..fdb78b0 100644
--- a/app/perfunwind.h
+++ b/app/perfunwind.h
@@ -61,6 +61,7 @@ public:
ContextSwitchDefinition,
Sample,
TracePointSample,
+ DebugInfoDownloadProgress,
InvalidType
};
@@ -223,6 +224,7 @@ public:
Q_ENUM(ErrorCode)
void sendError(ErrorCode error, const QString &message);
void sendProgress(float percent);
+ void sendDebugInfoDownloadProgress(qint32 url, qint64 numerator, qint64 denominator);
QString systemRoot() const { return m_systemRoot; }
QString extraLibsPath() const { return m_extraLibsPath; }