https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/119716
>From b7216d7c3edd5974d84612586fbabdef19037387 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Thu, 26 Dec 2024 20:50:40 -0500 Subject: [PATCH 1/4] Implement LLDB Telemetry (Part 1) This contains only the concrete implementation of the framework to be used but no usages yet. This is a subset of PR/98528. I plan to send a few follow-up patches: part2 : includes changes in the plugin-manager to set up the plugin stuff (ie., how to create a default vs vendor impl) part3 (all of the following can be done in parallel): * part 3_a: define DebuggerTelemetryInfo and related methods to collect data about debugger startup/exit * part 3_b: define TargetTelemetryInfo and related methods to collect data about debug target(s) * part 3_c: define CommandTelemetryInfo and related methods to collect data about debug-commands * part 3_d: define ClientTelemtryInfo and related methods to collect data about lldb-dap/any other client --- lldb/include/lldb/Core/Telemetry.h | 101 ++++++++++++++++++++++++++ lldb/include/lldb/lldb-enumerations.h | 4 +- lldb/source/Core/CMakeLists.txt | 2 + lldb/source/Core/Telemetry.cpp | 92 +++++++++++++++++++++++ lldb/test/CMakeLists.txt | 3 + 5 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 lldb/include/lldb/Core/Telemetry.h create mode 100644 lldb/source/Core/Telemetry.cpp diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h new file mode 100644 index 00000000000000..882511efd804d2 --- /dev/null +++ b/lldb/include/lldb/Core/Telemetry.h @@ -0,0 +1,101 @@ +//===-- Telemetry.h ----------------------------------------------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_CORE_TELEMETRY_H +#define LLDB_CORE_TELEMETRY_H + +#include <chrono> +#include <ctime> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> + +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/JSON.h" +#include "llvm/Telemetry/Telemetry.h" + +namespace lldb_private { + +using llvm::telemetry::Destination; +using llvm::telemetry::KindType; +using llvm::telemetry::Serializer; +using llvm::telemetry::TelemetryInfo; + +struct LldbEntryKind : public ::llvm::telemetry::EntryKind { + static const KindType BaseInfo = 0b11000; +}; + +/// Defines a convenient type for timestamp of various events. +/// This is used by the EventStats below. +using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock, + std::chrono::nanoseconds>; + +/// Various time (and possibly memory) statistics of an event. +struct EventStats { + // REQUIRED: Start time of an event + SteadyTimePoint start; + // OPTIONAL: End time of an event - may be empty if not meaningful. + std::optional<SteadyTimePoint> end; + // TBD: could add some memory stats here too? + + EventStats() = default; + EventStats(SteadyTimePoint start) : start(start) {} + EventStats(SteadyTimePoint start, SteadyTimePoint end) + : start(start), end(end) {} +}; + +/// Describes the exit signal of an event. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct LldbBaseTelemetryInfo : public TelemetryInfo { + EventStats stats; + + std::optional<ExitDescription> exit_desc; + + Debugger *debugger; + + // For dyn_cast, isa, etc operations. + KindType getKind() const override { return LldbEntryKind::BaseInfo; } + + static bool classof(const TelemetryInfo *t) { + // Subclasses of this is also acceptable. + return (t->getKind() & LldbEntryKind::BaseInfo) == LldbEntryKind::BaseInfo; + } + + void serialize(Serializer &serializer) const override; +}; + +/// The base Telemetry manager instance in LLDB +/// This class declares additional instrumentation points +/// applicable to LLDB. +class TelemetryManager : public llvm::telemetry::Manager { +public: + TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config); + + llvm::Error dispatch(TelemetryInfo *entry) override; + + void addDestination(std::unique_ptr<Destination> destination) override; + +private: + std::unique_ptr<llvm::telemetry::Config> m_config; + const std::string m_session_uuid; + std::vector<std::unique_ptr<Destination>> m_destinations; +}; + +} // namespace lldb_private +#endif // LLDB_CORE_TELEMETRY_H diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0094fcd596fdf7..f63e446b6042f6 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -257,8 +257,8 @@ enum StopReason { }; /// Command Return Status Types. -enum ReturnStatus { - eReturnStatusInvalid, +enum ReturnStatus : int { + eReturnStatusInvalid = 0, eReturnStatusSuccessFinishNoResult, eReturnStatusSuccessFinishResult, eReturnStatusSuccessContinuingNoResult, diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt index 6d14f7a87764e0..dcab3b19ad8ff9 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -51,6 +51,7 @@ add_lldb_library(lldbCore Section.cpp SourceLocationSpec.cpp SourceManager.cpp + Telemetry.cpp StreamAsynchronousIO.cpp ThreadedCommunication.cpp UserSettingsController.cpp @@ -80,6 +81,7 @@ add_lldb_library(lldbCore Support Demangle TargetParser + Telemetry ) add_dependencies(lldbCore diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp new file mode 100644 index 00000000000000..3d6264a4c8e57a --- /dev/null +++ b/lldb/source/Core/Telemetry.cpp @@ -0,0 +1,92 @@ +//===-- Telemetry.cpp -----------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#include "lldb/Core/Telemetry.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Target/Statistics.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/UUID.h" +#include "lldb/Version/Version.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/RandomNumberGenerator.h" +#include "llvm/Telemetry/Telemetry.h" +#include <chrono> +#include <cstdlib> +#include <ctime> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +namespace lldb_private { + +using ::llvm::Error; +using ::llvm::telemetry::Destination; +using ::llvm::telemetry::TelemetryInfo; + +static uint64_t ToNanosec(const SteadyTimePoint Point) { + return nanoseconds(Point.value().time_since_epoch()).count(); +} + +void LldbBaseTelemetryInfo::serialize(Serializer &serializer) const { + serializer.write("entry_kind", getKind()); + serializer.write("session_id", SessionId); + serializer.write("start_time", ToNanosec(stats.start)); + if (stats.end.has_value()) + serializer.write("end_time", ToNanosec(stats.end.value())); + if (exit_desc.has_value()) { + serializer.write("exit_code", exit_desc->exit_code); + serializer.write("exit_msg", exit_desc->description); + } +} + +static std::string MakeUUID(lldb_private::Debugger *debugger) { + std::string ret; + uint8_t random_bytes[16]; + if (auto ec = llvm::getRandomBytes(random_bytes, 16)) { + LLDB_LOG(GetLog(LLDBLog::Object), + "Failed to generate random bytes for UUID: {0}", ec.message()); + // fallback to using timestamp + debugger ID. + ret = std::to_string( + std::chrono::steady_clock::now().time_since_epoch().count()) + + "_" + std::to_string(debugger->GetID()); + } else { + ret = lldb_private::UUID(random_bytes).GetAsString(); + } + + return ret; +} + +TelemetryManager::TelemetryManager( + std::unique_ptr<llvm::telemetry::Config> config, + lldb_private::Debugger *debugger) + : m_config(std::move(config)), m_debugger(debugger), + m_session_uuid(MakeUUID(debugger)) {} + +llvm::Error TelemetryManager::dispatch(TelemetryInfo *entry) { + entry->SessionId = m_session_uuid; + + llvm::Error defferedErrs = llvm::Error::success(); + for (auto &destination : m_destinations) + deferredErrs = llvm::joinErrors(std::move(deferredErrs), + destination->receiveEntry(entry)); + + return std::move(deferredErrs); +} + +void TelemetryManager::addDestination( + std::unique_ptr<Destination> destination) { + m_destinations.push_back(std::move(destination)); +} + +} // namespace lldb_private diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index 6449ac5a9247f6..b71550d1788864 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -108,6 +108,9 @@ endfunction(add_lldb_test_dependency) add_lldb_test_dependency(lldb) add_lldb_test_dependency(lldb-test) +# Enable Telemetry for testing. +target_compile_definitions(lldb PRIVATE -DTEST_TELEMETRY) + # On Darwin, darwin-debug is an hard dependency for the testsuites. if (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_lldb_test_dependency(darwin-debug) >From fca467450e244b54bcf88cc81de91e28fb3bd3cd Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Thu, 26 Dec 2024 21:08:14 -0500 Subject: [PATCH 2/4] fix order --- lldb/include/lldb/Core/Telemetry.h | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 882511efd804d2..025f73bc5daeab 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -10,13 +10,6 @@ #ifndef LLDB_CORE_TELEMETRY_H #define LLDB_CORE_TELEMETRY_H -#include <chrono> -#include <ctime> -#include <memory> -#include <optional> -#include <string> -#include <unordered_map> - #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/StructuredData.h" @@ -25,6 +18,12 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" #include "llvm/Telemetry/Telemetry.h" +#include <chrono> +#include <ctime> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> namespace lldb_private { >From ec5a6611eaae0c9bb469b9eaef1893c7e0c77f40 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Tue, 4 Feb 2025 15:22:04 -0500 Subject: [PATCH 3/4] Sync to head and update LLDB's telemetry to match with new llvm::Telemetry changes --- lldb/include/lldb/Core/Telemetry.h | 6 +----- lldb/source/Core/Telemetry.cpp | 26 +++++++------------------- lldb/test/CMakeLists.txt | 3 --- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 025f73bc5daeab..ce518c6d487fb2 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -86,14 +86,10 @@ class TelemetryManager : public llvm::telemetry::Manager { public: TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config); - llvm::Error dispatch(TelemetryInfo *entry) override; - - void addDestination(std::unique_ptr<Destination> destination) override; + llvm::Error preDispatch(TelemetryInfo *entry) override; private: std::unique_ptr<llvm::telemetry::Config> m_config; - const std::string m_session_uuid; - std::vector<std::unique_ptr<Destination>> m_destinations; }; } // namespace lldb_private diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index 3d6264a4c8e57a..35bae965efffe6 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -35,7 +35,7 @@ using ::llvm::telemetry::Destination; using ::llvm::telemetry::TelemetryInfo; static uint64_t ToNanosec(const SteadyTimePoint Point) { - return nanoseconds(Point.value().time_since_epoch()).count(); + return std::chrono::nanoseconds(Point.time_since_epoch()).count(); } void LldbBaseTelemetryInfo::serialize(Serializer &serializer) const { @@ -68,25 +68,13 @@ static std::string MakeUUID(lldb_private::Debugger *debugger) { } TelemetryManager::TelemetryManager( - std::unique_ptr<llvm::telemetry::Config> config, - lldb_private::Debugger *debugger) - : m_config(std::move(config)), m_debugger(debugger), - m_session_uuid(MakeUUID(debugger)) {} + std::unique_ptr<llvm::telemetry::Config> config) + : m_config(std::move(config)) {} -llvm::Error TelemetryManager::dispatch(TelemetryInfo *entry) { - entry->SessionId = m_session_uuid; - - llvm::Error defferedErrs = llvm::Error::success(); - for (auto &destination : m_destinations) - deferredErrs = llvm::joinErrors(std::move(deferredErrs), - destination->receiveEntry(entry)); - - return std::move(deferredErrs); -} - -void TelemetryManager::addDestination( - std::unique_ptr<Destination> destination) { - m_destinations.push_back(std::move(destination)); +llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { + // Do nothing for now. + // In up-coming patch, this would be where the manager + // attach the session_uuid to the entry. } } // namespace lldb_private diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index b71550d1788864..6449ac5a9247f6 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -108,9 +108,6 @@ endfunction(add_lldb_test_dependency) add_lldb_test_dependency(lldb) add_lldb_test_dependency(lldb-test) -# Enable Telemetry for testing. -target_compile_definitions(lldb PRIVATE -DTEST_TELEMETRY) - # On Darwin, darwin-debug is an hard dependency for the testsuites. if (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_lldb_test_dependency(darwin-debug) >From 5e19b7e5112d36e0c1b19c2d6a0a2f1d9a1a0eae Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Wed, 5 Feb 2025 10:05:25 -0500 Subject: [PATCH 4/4] put Telemetry sources behind cmake condition-variable --- lldb/source/Core/CMakeLists.txt | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt index dcab3b19ad8ff9..acadcd67fb3fb6 100644 --- a/lldb/source/Core/CMakeLists.txt +++ b/lldb/source/Core/CMakeLists.txt @@ -17,6 +17,15 @@ if (LLDB_ENABLE_CURSES) endif() # TODO: Add property `NO_PLUGIN_DEPENDENCIES` to lldbCore +set(LLDB_CORE_SRCS + +) + +if (LLVM_BUILD_TELEMETRY) + set(TELEMETRY_SOURCES Telemetry.cpp) + set(TELEMETRY_DEPS Telemetry) +endif() + add_lldb_library(lldbCore Address.cpp AddressRange.cpp @@ -51,12 +60,12 @@ add_lldb_library(lldbCore Section.cpp SourceLocationSpec.cpp SourceManager.cpp - Telemetry.cpp StreamAsynchronousIO.cpp ThreadedCommunication.cpp UserSettingsController.cpp Value.cpp - + ${TELEMETRY_SOURCES} + PARTIAL_SOURCES_INTENDED DEPENDS clang-tablegen-targets @@ -81,7 +90,7 @@ add_lldb_library(lldbCore Support Demangle TargetParser - Telemetry + ${TELEMETRY_DEPS} ) add_dependencies(lldbCore _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits