https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/127696
>From 24e9f78744f98ecf3ac01f1f719f1eac9b3479f0 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Tue, 18 Feb 2025 15:58:08 -0500 Subject: [PATCH 1/5] [LLDB][Telemetry]Define DebuggerTelemetryInfo and related methods - This type of entry is used to collect data about the debugger startup/exit - Tests will be added (They may need to be shell test with a "test-only" TelemetryManager plugin defined. I'm trying to figure out how to get that linked only when tests are running and not to the LLDB binary all the time. --- lldb/include/lldb/Core/Telemetry.h | 78 +++++++++++++++++++ lldb/source/Core/Debugger.cpp | 40 ++++++++++ lldb/source/Core/Telemetry.cpp | 115 +++++++++++++++++++++++++---- 3 files changed, 220 insertions(+), 13 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index b72556ecaf3c9..d6eec5dc687be 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -13,6 +13,7 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-forward.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" @@ -29,6 +30,9 @@ namespace telemetry { struct LLDBEntryKind : public ::llvm::telemetry::EntryKind { static const llvm::telemetry::KindType BaseInfo = 0b11000; + static const llvm::telemetry::KindType DebuggerInfo = 0b11001; + // There are other entries in between (added in separate PRs) + static const llvm::telemetry::KindType MiscInfo = 0b11110; }; /// Defines a convenient type for timestamp of various events. @@ -56,6 +60,71 @@ struct LLDBBaseTelemetryInfo : public llvm::telemetry::TelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; +/// Describes the exit status of a debugger. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct DebuggerTelemetryInfo : public LLDBBaseTelemetryInfo { + std::string username; + std::string lldb_git_sha; + std::string lldb_path; + std::string cwd; + std::optional<ExitDescription> exit_desc; + + DebuggerTelemetryInfo() = default; + + // Provide a copy ctor because we may need to make a copy before + // sanitizing the data. + // (The sanitization might differ between different Destination classes). + DebuggerTelemetryInfo(const DebuggerTelemetryInfo &other) { + username = other.username; + lldb_git_sha = other.lldb_git_sha; + lldb_path = other.lldb_path; + cwd = other.cwd; + }; + + llvm::telemetry::KindType getKind() const override { + return LLDBEntryKind::DebuggerInfo; + } + + static bool classof(const llvm::telemetry::TelemetryInfo *T) { + return T->getKind() == LLDBEntryKind::DebuggerInfo; + } + + void serialize(llvm::telemetry::Serializer &serializer) const override; +}; + +/// The "catch-all" entry to store a set of non-standard data, such as +/// error-messages, etc. +struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo { + /// If the event is/can be associated with a target entry, + /// this field contains that target's UUID. + /// <EMPTY> otherwise. + std::string target_uuid; + + /// Set of key-value pairs for any optional (or impl-specific) data + std::map<std::string, std::string> meta_data; + + MiscTelemetryInfo() = default; + + MiscTelemetryInfo(const MiscTelemetryInfo &other) { + target_uuid = other.target_uuid; + meta_data = other.meta_data; + } + + llvm::telemetry::KindType getKind() const override { + return LLDBEntryKind::MiscInfo; + } + + static bool classof(const llvm::telemetry::TelemetryInfo *T) { + return T->getKind() == LLDBEntryKind::MiscInfo; + } + + void serialize(llvm::telemetry::Serializer &serializer) const override; +}; + /// The base Telemetry manager instance in LLDB. /// This class declares additional instrumentation points /// applicable to LLDB. @@ -63,6 +132,11 @@ class TelemetryManager : public llvm::telemetry::Manager { public: llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override; + const llvm::telemetry::Config *getConfig(); + + void atDebuggerStartup(DebuggerTelemetryInfo *entry); + void atDebuggerExit(DebuggerTelemetryInfo *entry); + virtual llvm::StringRef GetInstanceName() const = 0; static TelemetryManager *getInstance(); @@ -73,6 +147,10 @@ class TelemetryManager : public llvm::telemetry::Manager { private: std::unique_ptr<llvm::telemetry::Config> m_config; + // Each debugger is assigned a unique ID (session_id). + // All TelemetryInfo entries emitted for the same debugger instance + // will get the same session_id. + llvm::DenseMap<Debugger *, std::string> session_ids; static std::unique_ptr<TelemetryManager> g_instance; }; diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 18569e155b517..b458abc798a9e 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -62,6 +62,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Process.h" @@ -69,6 +70,11 @@ #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" +#ifdef LLVM_BUILD_TELEMETRY +#include "lldb/Core/Telemetry.h" +#include <chrono> +#endif + #include <cstdio> #include <cstdlib> #include <cstring> @@ -761,12 +767,29 @@ void Debugger::InstanceInitialize() { DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback, void *baton) { +#ifdef LLVM_BUILD_TELEMETRY + lldb_private::telemetry::SteadyTimePoint start_time = + std::chrono::steady_clock::now(); +#endif DebuggerSP debugger_sp(new Debugger(log_callback, baton)); if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); g_debugger_list_ptr->push_back(debugger_sp); } debugger_sp->InstanceInitialize(); + +#ifdef LLVM_BUILD_TELEMETRY + if (auto *telemetry_manager = telemetry::TelemetryManager::getInstance()) { + if (telemetry_manager->getConfig()->EnableTelemetry) { + lldb_private::telemetry::DebuggerTelemetryInfo entry; + entry.start_time = start_time; + entry.end_time = std::chrono::steady_clock::now(); + entry.debugger = debugger_sp.get(); + telemetry_manager->atDebuggerStartup(&entry); + } + } +#endif + return debugger_sp; } @@ -985,6 +1008,10 @@ void Debugger::Clear() { // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp); // static void Debugger::Terminate(); llvm::call_once(m_clear_once, [this]() { +#ifdef LLVM_BUILD_TELEMETRY + lldb_private::telemetry::SteadyTimePoint quit_start_time = + std::chrono::steady_clock::now(); +#endif ClearIOHandlers(); StopIOHandlerThread(); StopEventHandlerThread(); @@ -1007,6 +1034,19 @@ void Debugger::Clear() { if (Diagnostics::Enabled()) Diagnostics::Instance().RemoveCallback(m_diagnostics_callback_id); + +#ifdef LLVM_BUILD_TELEMETRY + if (auto telemetry_manager = telemetry::TelemetryManager::getInstance()) { + if (telemetry_manager->getConfig()->EnableTelemetry) { + // TBD: We *may* have to send off the log BEFORE the ClearIOHanders()? + lldb_private::telemetry::DebuggerTelemetryInfo entry; + entry.start_time = quit_start_time; + entry.end_time = std::chrono::steady_clock::now(); + entry.debugger = this; + telemetry_manager->atDebuggerExit(&entry); + } + } +#endif }); } diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index 5222f76704f91..ab7d8ae0b44df 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -10,14 +10,20 @@ #ifdef LLVM_BUILD_TELEMETRY -#include "lldb/Core/Telemetry.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/Telemetry.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Statistics.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/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Path.h" #include "llvm/Support/RandomNumberGenerator.h" #include "llvm/Telemetry/Telemetry.h" #include <chrono> @@ -35,15 +41,7 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) { return std::chrono::nanoseconds(Point.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(start_time)); - if (end_time.has_value()) - serializer.write("end_time", ToNanosec(end_time.value())); -} - -[[maybe_unused]] static std::string MakeUUID(Debugger *debugger) { +static std::string MakeUUID(Debugger *debugger) { uint8_t random_bytes[16]; if (auto ec = llvm::getRandomBytes(random_bytes, 16)) { LLDB_LOG(GetLog(LLDBLog::Object), @@ -56,16 +54,107 @@ void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { return UUID(random_bytes).GetAsString(); } +void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { + serializer.write("entry_kind", getKind()); + serializer.write("session_id", SessionId); + serializer.write("start_time", ToNanosec(start_time)); + if (end_time.has_value()) + serializer.write("end_time", ToNanosec(end_time.value())); +} + +void DebuggerTelemetryInfo::serialize(Serializer &serializer) const { + LLDBBaseTelemetryInfo::serialize(serializer); + + serializer.write("username", username); + serializer.write("lldb_git_sha", lldb_git_sha); + serializer.write("lldb_path", lldb_path); + serializer.write("cwd", cwd); + if (exit_desc.has_value()) { + serializer.write("exit_code", exit_desc->exit_code); + serializer.write("exit_desc", exit_desc->description); + } +} + +void MiscTelemetryInfo::serialize(Serializer &serializer) const { + LLDBBaseTelemetryInfo::serialize(serializer); + serializer.write("target_uuid", target_uuid); + serializer.beginObject("meta_data"); + for (const auto &kv : meta_data) + serializer.write(kv.first, kv.second); + serializer.endObject(); +} + TelemetryManager::TelemetryManager(std::unique_ptr<Config> config) : m_config(std::move(config)) {} 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. + LLDBBaseTelemetryInfo *lldb_entry = + llvm::dyn_cast<LLDBBaseTelemetryInfo>(entry); + std::string session_id = ""; + if (Debugger *debugger = lldb_entry->debugger) { + auto session_id_pos = session_ids.find(debugger); + if (session_id_pos != session_ids.end()) + session_id = session_id_pos->second; + else + session_id_pos->second = session_id = MakeUUID(debugger); + } + lldb_entry->SessionId = session_id; + return llvm::Error::success(); } +const Config *getConfig() { return m_config.get(); } + +void TelemetryManager::atDebuggerStartup(DebuggerTelemetryInfo *entry) { + UserIDResolver &resolver = lldb_private::HostInfo::GetUserIDResolver(); + std::optional<llvm::StringRef> opt_username = + resolver.GetUserName(lldb_private::HostInfo::GetUserID()); + if (opt_username) + entry->username = *opt_username; + + entry->lldb_git_sha = + lldb_private::GetVersion(); // TODO: find the real git sha? + + entry->lldb_path = HostInfo::GetProgramFileSpec().GetPath(); + + llvm::SmallString<64> cwd; + if (!llvm::sys::fs::current_path(cwd)) { + entry->cwd = cwd.c_str(); + } else { + MiscTelemetryInfo misc_info; + misc_info.meta_data["internal_errors"] = "Cannot determine CWD"; + if (auto er = dispatch(&misc_info)) { + LLDB_LOG(GetLog(LLDBLog::Object), + "Failed to dispatch misc-info at startup"); + } + } + + if (auto er = dispatch(entry)) { + LLDB_LOG(GetLog(LLDBLog::Object), "Failed to dispatch entry at startup"); + } +} + +void TelemetryManager::atDebuggerExit(DebuggerTelemetryInfo *entry) { + // There must be a reference to the debugger at this point. + assert(entry->debugger != nullptr); + + if (auto *selected_target = + entry->debugger->GetSelectedExecutionContext().GetTargetPtr()) { + if (!selected_target->IsDummyTarget()) { + const lldb::ProcessSP proc = selected_target->GetProcessSP(); + if (proc == nullptr) { + // no process has been launched yet. + entry->exit_desc = {-1, "no process launched."}; + } else { + entry->exit_desc = {proc->GetExitStatus(), ""}; + if (const char *description = proc->GetExitDescription()) + entry->exit_desc->description = std::string(description); + } + } + } + dispatch(entry); +} + std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr; TelemetryManager *TelemetryManager::getInstance() { return g_instance.get(); } >From 496c370bffd3a518eda4f8d34aabad13356831b3 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Tue, 18 Feb 2025 20:51:23 -0500 Subject: [PATCH 2/5] Update lldb/include/lldb/Core/Telemetry.h Co-authored-by: Jonas Devlieghere <jo...@devlieghere.com> --- lldb/include/lldb/Core/Telemetry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index d6eec5dc687be..9d34bf205c607 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -105,7 +105,7 @@ struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo { std::string target_uuid; /// Set of key-value pairs for any optional (or impl-specific) data - std::map<std::string, std::string> meta_data; + llvm::StringMap<std::string> meta_data; MiscTelemetryInfo() = default; >From 11efc09e1ab9ffcca8e965906530af995f5c8c83 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Wed, 19 Feb 2025 14:23:00 -0500 Subject: [PATCH 3/5] Update lldb/source/Core/Telemetry.cpp Co-authored-by: Pavel Labath <pa...@labath.sk> --- lldb/source/Core/Telemetry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index ab7d8ae0b44df..2e86d793c5ab3 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -123,9 +123,9 @@ void TelemetryManager::atDebuggerStartup(DebuggerTelemetryInfo *entry) { } else { MiscTelemetryInfo misc_info; misc_info.meta_data["internal_errors"] = "Cannot determine CWD"; - if (auto er = dispatch(&misc_info)) { - LLDB_LOG(GetLog(LLDBLog::Object), - "Failed to dispatch misc-info at startup"); + if (llvm::Error er = dispatch(&misc_info)) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er), + "Failed to dispatch misc-info at startup: {0}"); } } >From 5aec2845cee08ada1a5ca7da7ff901ea9a1017d8 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Thu, 20 Feb 2025 15:51:06 -0500 Subject: [PATCH 4/5] adddressed review comments: - remove collection of username,cwd,lldb_path (that can be collected in vendor-specific impl) - use DebuggerID as key rather than the debugger pointer - renaming --- lldb/include/lldb/Core/Telemetry.h | 32 ++++++-------- lldb/source/Core/Telemetry.cpp | 67 ++++++++++++++---------------- 2 files changed, 44 insertions(+), 55 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 9d34bf205c607..1fb2c5b6b7eeb 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -66,24 +66,15 @@ struct ExitDescription { std::string description; }; -struct DebuggerTelemetryInfo : public LLDBBaseTelemetryInfo { - std::string username; - std::string lldb_git_sha; - std::string lldb_path; - std::string cwd; +struct DebuggerInfo : public LLDBBaseTelemetryInfo { + std::string lldb_version; std::optional<ExitDescription> exit_desc; - DebuggerTelemetryInfo() = default; + std::string lldb_path; + std::string cwd; + std::string username; - // Provide a copy ctor because we may need to make a copy before - // sanitizing the data. - // (The sanitization might differ between different Destination classes). - DebuggerTelemetryInfo(const DebuggerTelemetryInfo &other) { - username = other.username; - lldb_git_sha = other.lldb_git_sha; - lldb_path = other.lldb_path; - cwd = other.cwd; - }; + DebuggerInfo() = default; llvm::telemetry::KindType getKind() const override { return LLDBEntryKind::DebuggerInfo; @@ -134,8 +125,8 @@ class TelemetryManager : public llvm::telemetry::Manager { const llvm::telemetry::Config *getConfig(); - void atDebuggerStartup(DebuggerTelemetryInfo *entry); - void atDebuggerExit(DebuggerTelemetryInfo *entry); + virtual void AtDebuggerStartup(DebuggerInfo *entry); + virtual void AtDebuggerExit(DebuggerInfo *entry); virtual llvm::StringRef GetInstanceName() const = 0; static TelemetryManager *getInstance(); @@ -147,10 +138,13 @@ class TelemetryManager : public llvm::telemetry::Manager { private: std::unique_ptr<llvm::telemetry::Config> m_config; - // Each debugger is assigned a unique ID (session_id). + // Each instance of a TelemetryManager is assigned a unique ID. + const std::string m_id; + + // Map of debugger's ID to a unique session_id string. // All TelemetryInfo entries emitted for the same debugger instance // will get the same session_id. - llvm::DenseMap<Debugger *, std::string> session_ids; + llvm::DenseMap<lldb::user_id_t, std::string> session_ids; static std::unique_ptr<TelemetryManager> g_instance; }; diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index 2e86d793c5ab3..9ae5f9c4e8243 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -41,17 +41,32 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) { return std::chrono::nanoseconds(Point.time_since_epoch()).count(); } -static std::string MakeUUID(Debugger *debugger) { +// Generate a unique string. This should be unique across different runs. +// We build such string by combining three parts: +// <16 random bytes>_<timestamp>_<hash of username> +// This reduces the chances of getting the same UUID, even when the same +// user runs the two copies of binary at the same time. +static std::string MakeUUID() { uint8_t random_bytes[16]; + std::string randomString = "_"; 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. - return llvm::formatv( - "{0}_{1}", std::chrono::steady_clock::now().time_since_epoch().count(), - debugger->GetID()); + } else { + randomString = UUID(random_bytes).GetAsString(); } - return UUID(random_bytes).GetAsString(); + + std::string username = "_"; + UserIDResolver &resolver = lldb_private::HostInfo::GetUserIDResolver(); + std::optional<llvm::StringRef> opt_username = + resolver.GetUserName(lldb_private::HostInfo::GetUserID()); + if (opt_username) + username = *opt_username; + + return llvm::formatv( + "{0}_{1}_{2}", randomString, + std::chrono::steady_clock::now().time_since_epoch().count(), + llvm::MD5Hash(username)); } void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { @@ -62,7 +77,7 @@ void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { serializer.write("end_time", ToNanosec(end_time.value())); } -void DebuggerTelemetryInfo::serialize(Serializer &serializer) const { +void DebuggerInfo::serialize(Serializer &serializer) const { LLDBBaseTelemetryInfo::serialize(serializer); serializer.write("username", username); @@ -85,18 +100,21 @@ void MiscTelemetryInfo::serialize(Serializer &serializer) const { } TelemetryManager::TelemetryManager(std::unique_ptr<Config> config) - : m_config(std::move(config)) {} + : m_config(std::move(config)), m_id(MakeUUID) {} llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { + // Look up the session_id to assign to this entry or make one + // if none had been computed for this debugger. LLDBBaseTelemetryInfo *lldb_entry = llvm::dyn_cast<LLDBBaseTelemetryInfo>(entry); - std::string session_id = ""; + std::string session_id = m_id; if (Debugger *debugger = lldb_entry->debugger) { - auto session_id_pos = session_ids.find(debugger); + auto session_id_pos = session_ids.find(debugger->getID()); if (session_id_pos != session_ids.end()) session_id = session_id_pos->second; else - session_id_pos->second = session_id = MakeUUID(debugger); + session_id_pos->second = session_id = + llvm::formatv("{0}_{1}", m_id, debugger->getID()); } lldb_entry->SessionId = session_id; @@ -105,36 +123,13 @@ llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { const Config *getConfig() { return m_config.get(); } -void TelemetryManager::atDebuggerStartup(DebuggerTelemetryInfo *entry) { - UserIDResolver &resolver = lldb_private::HostInfo::GetUserIDResolver(); - std::optional<llvm::StringRef> opt_username = - resolver.GetUserName(lldb_private::HostInfo::GetUserID()); - if (opt_username) - entry->username = *opt_username; - - entry->lldb_git_sha = - lldb_private::GetVersion(); // TODO: find the real git sha? - - entry->lldb_path = HostInfo::GetProgramFileSpec().GetPath(); - - llvm::SmallString<64> cwd; - if (!llvm::sys::fs::current_path(cwd)) { - entry->cwd = cwd.c_str(); - } else { - MiscTelemetryInfo misc_info; - misc_info.meta_data["internal_errors"] = "Cannot determine CWD"; - if (llvm::Error er = dispatch(&misc_info)) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er), - "Failed to dispatch misc-info at startup: {0}"); - } - } - +void TelemetryManager::AtDebuggerStartup(DebuggerInfo *entry) { if (auto er = dispatch(entry)) { LLDB_LOG(GetLog(LLDBLog::Object), "Failed to dispatch entry at startup"); } } -void TelemetryManager::atDebuggerExit(DebuggerTelemetryInfo *entry) { +void TelemetryManager::AtDebuggerExit(DebuggerInfo *entry) { // There must be a reference to the debugger at this point. assert(entry->debugger != nullptr); >From 4b6a4bdf158dd631baec5768fb44719b8e8bf100 Mon Sep 17 00:00:00 2001 From: Vy Nguyen <v...@google.com> Date: Mon, 24 Feb 2025 13:39:35 -0500 Subject: [PATCH 5/5] remove unused fields --- lldb/include/lldb/Core/Telemetry.h | 38 +----------- lldb/source/Core/Telemetry.cpp | 99 ++++++++++++------------------ 2 files changed, 41 insertions(+), 96 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 1fb2c5b6b7eeb..79351b8f8e37c 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -45,6 +45,7 @@ struct LLDBBaseTelemetryInfo : public llvm::telemetry::TelemetryInfo { std::optional<SteadyTimePoint> end_time; // TBD: could add some memory stats here too? + uint64_t debugger_id = 0; Debugger *debugger; // For dyn_cast, isa, etc operations. @@ -70,10 +71,6 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo { std::string lldb_version; std::optional<ExitDescription> exit_desc; - std::string lldb_path; - std::string cwd; - std::string username; - DebuggerInfo() = default; llvm::telemetry::KindType getKind() const override { @@ -87,35 +84,6 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; -/// The "catch-all" entry to store a set of non-standard data, such as -/// error-messages, etc. -struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo { - /// If the event is/can be associated with a target entry, - /// this field contains that target's UUID. - /// <EMPTY> otherwise. - std::string target_uuid; - - /// Set of key-value pairs for any optional (or impl-specific) data - llvm::StringMap<std::string> meta_data; - - MiscTelemetryInfo() = default; - - MiscTelemetryInfo(const MiscTelemetryInfo &other) { - target_uuid = other.target_uuid; - meta_data = other.meta_data; - } - - llvm::telemetry::KindType getKind() const override { - return LLDBEntryKind::MiscInfo; - } - - static bool classof(const llvm::telemetry::TelemetryInfo *T) { - return T->getKind() == LLDBEntryKind::MiscInfo; - } - - void serialize(llvm::telemetry::Serializer &serializer) const override; -}; - /// The base Telemetry manager instance in LLDB. /// This class declares additional instrumentation points /// applicable to LLDB. @@ -141,10 +109,6 @@ class TelemetryManager : public llvm::telemetry::Manager { // Each instance of a TelemetryManager is assigned a unique ID. const std::string m_id; - // Map of debugger's ID to a unique session_id string. - // All TelemetryInfo entries emitted for the same debugger instance - // will get the same session_id. - llvm::DenseMap<lldb::user_id_t, std::string> session_ids; static std::unique_ptr<TelemetryManager> g_instance; }; diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index 9ae5f9c4e8243..74dd8bf6f7e09 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -43,7 +43,7 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) { // Generate a unique string. This should be unique across different runs. // We build such string by combining three parts: -// <16 random bytes>_<timestamp>_<hash of username> +// <16 random bytes>_<timestamp> // This reduces the chances of getting the same UUID, even when the same // user runs the two copies of binary at the same time. static std::string MakeUUID() { @@ -56,17 +56,9 @@ static std::string MakeUUID() { randomString = UUID(random_bytes).GetAsString(); } - std::string username = "_"; - UserIDResolver &resolver = lldb_private::HostInfo::GetUserIDResolver(); - std::optional<llvm::StringRef> opt_username = - resolver.GetUserName(lldb_private::HostInfo::GetUserID()); - if (opt_username) - username = *opt_username; - return llvm::formatv( - "{0}_{1}_{2}", randomString, - std::chrono::steady_clock::now().time_since_epoch().count(), - llvm::MD5Hash(username)); + "{0}_{1}", randomString, + std::chrono::steady_clock::now().time_since_epoch().count()); } void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { @@ -90,33 +82,16 @@ void DebuggerInfo::serialize(Serializer &serializer) const { } } -void MiscTelemetryInfo::serialize(Serializer &serializer) const { - LLDBBaseTelemetryInfo::serialize(serializer); - serializer.write("target_uuid", target_uuid); - serializer.beginObject("meta_data"); - for (const auto &kv : meta_data) - serializer.write(kv.first, kv.second); - serializer.endObject(); -} - TelemetryManager::TelemetryManager(std::unique_ptr<Config> config) : m_config(std::move(config)), m_id(MakeUUID) {} llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { - // Look up the session_id to assign to this entry or make one - // if none had been computed for this debugger. + // Assign the manager_id, and debugger_id, if available, to this entry. LLDBBaseTelemetryInfo *lldb_entry = llvm::dyn_cast<LLDBBaseTelemetryInfo>(entry); - std::string session_id = m_id; - if (Debugger *debugger = lldb_entry->debugger) { - auto session_id_pos = session_ids.find(debugger->getID()); - if (session_id_pos != session_ids.end()) - session_id = session_id_pos->second; - else - session_id_pos->second = session_id = - llvm::formatv("{0}_{1}", m_id, debugger->getID()); - } - lldb_entry->SessionId = session_id; + lldb_entry->SessionId = m_id; + if (Debugger *debugger = lldb_entry->debugger) + lldb_entry->debugger_id = debugger->GetID(); return llvm::Error::success(); } @@ -124,40 +99,46 @@ llvm::Error TelemetryManager::preDispatch(TelemetryInfo *entry) { const Config *getConfig() { return m_config.get(); } void TelemetryManager::AtDebuggerStartup(DebuggerInfo *entry) { - if (auto er = dispatch(entry)) { - LLDB_LOG(GetLog(LLDBLog::Object), "Failed to dispatch entry at startup"); + if (llvm::Error er = dispatch(entry)) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er), + "Failed to dispatch entry at debugger startup: {0}"); } -} -void TelemetryManager::AtDebuggerExit(DebuggerInfo *entry) { - // There must be a reference to the debugger at this point. - assert(entry->debugger != nullptr); - - if (auto *selected_target = - entry->debugger->GetSelectedExecutionContext().GetTargetPtr()) { - if (!selected_target->IsDummyTarget()) { - const lldb::ProcessSP proc = selected_target->GetProcessSP(); - if (proc == nullptr) { - // no process has been launched yet. - entry->exit_desc = {-1, "no process launched."}; - } else { - entry->exit_desc = {proc->GetExitStatus(), ""}; - if (const char *description = proc->GetExitDescription()) - entry->exit_desc->description = std::string(description); + void TelemetryManager::AtDebuggerExit(DebuggerInfo * entry) { + // There must be a reference to the debugger at this point. + assert(entry->debugger != nullptr); + + if (auto *selected_target = + entry->debugger->GetSelectedExecutionContext().GetTargetPtr()) { + if (!selected_target->IsDummyTarget()) { + const lldb::ProcessSP proc = selected_target->GetProcessSP(); + if (proc == nullptr) { + // no process has been launched yet. + entry->exit_desc = {-1, "no process launched."}; + } else { + entry->exit_desc = {proc->GetExitStatus(), ""}; + if (const char *description = proc->GetExitDescription()) + entry->exit_desc->description = std::string(description); + } } } - } - dispatch(entry); -} -std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr; -TelemetryManager *TelemetryManager::getInstance() { return g_instance.get(); } + if (llvm::Error er = dispatch(entry)) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er), + "Failed to dispatch entry at debugger exit: {0}"); + } -void TelemetryManager::setInstance(std::unique_ptr<TelemetryManager> manager) { - g_instance = std::move(manager); -} + std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr; + TelemetryManager *TelemetryManager::getInstance() { + return g_instance.get(); + } + + void TelemetryManager::setInstance( + std::unique_ptr<TelemetryManager> manager) { + g_instance = std::move(manager); + } -} // namespace telemetry + } // namespace telemetry } // namespace lldb_private #endif // LLVM_BUILD_TELEMETRY _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits