diff options
author | Milian Wolff <milian.wolff@kdab.com> | 2022-07-07 16:55:27 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2022-07-25 14:00:57 +0000 |
commit | d432bc71926b1a855e54baabf5216b09b266b5fc (patch) | |
tree | 6089cb44e5e7c91f567f8ec4c7716d36616c7020 | |
parent | 96b145c998d60d4c563abea0442c1549e263c3da (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.txt | 4 | ||||
-rw-r--r-- | app/CMakeLists.txt | 5 | ||||
-rw-r--r-- | app/perfsymboltable.cpp | 17 | ||||
-rw-r--r-- | app/perfunwind.cpp | 9 | ||||
-rw-r--r-- | app/perfunwind.h | 2 |
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; } |