https://github.com/oontvoo updated 
https://github.com/llvm/llvm-project/pull/127834

>From 0d6a36d84df50ccb9eef9ef3dd6f59d4299edeac Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Wed, 19 Feb 2025 12:47:57 -0500
Subject: [PATCH 01/10] [LLDB][Telemetry]Define TargetInfo for collecting data
 about a target

---
 lldb/include/lldb/Core/Telemetry.h | 86 +++++++++++++++++++++++++-
 lldb/source/Core/Telemetry.cpp     | 99 ++++++++++++++++++++++++++----
 2 files changed, 170 insertions(+), 15 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index b72556ecaf3c9..4be81951254de 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 KindType TargetInfo = 0b11010;
+  // 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,14 +60,88 @@ struct LLDBBaseTelemetryInfo : public 
llvm::telemetry::TelemetryInfo {
   void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
+/// Describes an exit status.
+struct ExitDescription {
+  int exit_code;
+  std::string description;
+};
+
+struct TargetTelemetryInfo : public LldbBaseTelemetryInfo {
+  lldb::ModuleSP exec_mod;
+  Target *target_ptr;
+
+  // The same as the executable-module's UUID.
+  std::string target_uuid;
+  std::string file_format;
+
+  std::string binary_path;
+  size_t binary_size;
+
+  std::optional<ExitDescription> exit_desc;
+  TargetTelemetryInfo() = default;
+
+  TargetTelemetryInfo(const TargetTelemetryInfo &other) {
+    exec_mod = other.exec_mod;
+    target_uuid = other.target_uuid;
+    file_format = other.file_format;
+    binary_path = other.binary_path;
+    binary_size = other.binary_size;
+    exit_desc = other.exit_desc;
+  }
+
+  KindType getKind() const override { return LldbEntryKind::TargetInfo; }
+
+  static bool classof(const TelemetryInfo *T) {
+    if (T == nullptr)
+      return false;
+    return T->getKind() == LldbEntryKind::TargetInfo;
+  }
+
+  void serialize(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.
-class TelemetryManager : public llvm::telemetry::Manager {
+class TelemetryMager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
-  virtual llvm::StringRef GetInstanceName() const = 0;
+  const llvm::telemetry::Config *getConfig();
+
+  virtual void AtMainExecutableLoadStart(TargetInfo * entry);
+  virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
+
+      virtual llvm::StringRef GetInstanceName() const = 0;
   static TelemetryManager *getInstance();
 
 protected:
@@ -73,6 +151,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/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index 5222f76704f91..da7aee01680fc 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,91 @@ 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 TargetInfo::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::AtMainExecutableLoadStart(TargetInfo *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::AtMainExecutableLoadEnd(TargetInfo *entry) {
+  // ....
+  dispatch(entry);
+}
+
 std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr;
 TelemetryManager *TelemetryManager::getInstance() { return g_instance.get(); }
 

>From f152b3b35de9d7907d4812254f3e0bde4564e45a Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 24 Feb 2025 16:03:07 -0500
Subject: [PATCH 02/10] introduce helper

---
 lldb/include/lldb/Core/Telemetry.h    | 115 +++++++++++++-------------
 lldb/source/Core/Telemetry.cpp        |  75 +++++++----------
 lldb/source/Target/Target.cpp         |  16 ++++
 lldb/unittests/Core/TelemetryTest.cpp |   6 +-
 4 files changed, 110 insertions(+), 102 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 4be81951254de..29873d91538a0 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -24,17 +24,22 @@
 #include <optional>
 #include <string>
 #include <unordered_map>
+#include <type_traits>
+#include <utility>
+#include <functional>
+#include <stack>
 
 namespace lldb_private {
 namespace telemetry {
 
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000;
-  static const KindType TargetInfo = 0b11010;
+  static const llvm::telemetry::KindType TargetInfo = 0b11010;
   // 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.
 using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock,
                                                 std::chrono::nanoseconds>;
@@ -66,64 +71,26 @@ struct ExitDescription {
   std::string description;
 };
 
-struct TargetTelemetryInfo : public LldbBaseTelemetryInfo {
+
+struct TargetInfo : public LLDBBaseTelemetryInfo {
   lldb::ModuleSP exec_mod;
   Target *target_ptr;
 
   // The same as the executable-module's UUID.
   std::string target_uuid;
-  std::string file_format;
-
-  std::string binary_path;
-  size_t binary_size;
+  std::string executable_path;
+  size_t executable_size;
+  std::string arch_name;
 
   std::optional<ExitDescription> exit_desc;
-  TargetTelemetryInfo() = default;
-
-  TargetTelemetryInfo(const TargetTelemetryInfo &other) {
-    exec_mod = other.exec_mod;
-    target_uuid = other.target_uuid;
-    file_format = other.file_format;
-    binary_path = other.binary_path;
-    binary_size = other.binary_size;
-    exit_desc = other.exit_desc;
-  }
+  TargetInfo() = default;
 
-  KindType getKind() const override { return LldbEntryKind::TargetInfo; }
+  llvm::telemetry::KindType getKind() const override { return 
LLDBEntryKind::TargetInfo; }
 
   static bool classof(const TelemetryInfo *T) {
     if (T == nullptr)
       return false;
-    return T->getKind() == LldbEntryKind::TargetInfo;
-  }
-
-  void serialize(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;
+    return T->getKind() == LLDBEntryKind::TargetInfo;
   }
 
   void serialize(llvm::telemetry::Serializer &serializer) const override;
@@ -132,32 +99,68 @@ struct MiscTelemetryInfo : public LLDBBaseTelemetryInfo {
 /// The base Telemetry manager instance in LLDB.
 /// This class declares additional instrumentation points
 /// applicable to LLDB.
-class TelemetryMager : public llvm::telemetry::Manager {
+class TelemetryManager : public llvm::telemetry::Manager {
 public:
   llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override;
 
-  const llvm::telemetry::Config *getConfig();
+  const llvm::telemetry::Config *GetConfig();
 
+  /// The following methods are for reporting the load of an executable.
+  /// One is invoked at the beginning of the process and the other at
+  /// the end.
+  /// This is done in two passes to avoid losing date in case of any 
error/crash
+  /// during the action.
+  ///
+  /// Invoked at the begining of the load of the main-executable.
   virtual void AtMainExecutableLoadStart(TargetInfo * entry);
+  /// Invoked at the end of the load.
   virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
 
-      virtual llvm::StringRef GetInstanceName() const = 0;
-  static TelemetryManager *getInstance();
+  virtual llvm::StringRef GetInstanceName() const = 0;
+
+  static TelemetryManager *GetInstance();
 
 protected:
   TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config);
 
-  static void setInstance(std::unique_ptr<TelemetryManager> manger);
+  static void SetInstance(std::unique_ptr<TelemetryManager> manger);
 
 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;
 };
 
+class Helper {
+ public:
+  Helper () : m_start(std::chrono::steady_clock::now()) {}
+  ~Helper() {
+    while(! m_exit_funcs.empty()) {
+      (m_exit_funcs.top())();
+      m_exit_funcs.pop();
+    }
+  }
+
+  bool TelemetryEnabled() {
+    TelemetryManager* instance = TelemetryManager::GetInstance();
+  return instance != nullptr && instance->GetConfig()->EnableTelemetry;
+  }
+
+
+  SteadyTimePoint GetStartTime() {return m_start;}
+  SteadyTimePoint GetCurrentTime()  { return std::chrono::steady_clock::now(); 
}
+
+ template <typename Fp>
+ void RunAtScopeExit(Fp&& F){
+   m_exit_funcs.push(std::forward<Fp>(F));
+ }
+
+ private:
+  const SteadyTimePoint m_start;
+  std::stack<std::function<void()>> m_exit_funcs;
+
+};
+
 } // namespace telemetry
 } // namespace lldb_private
 #endif // LLDB_CORE_TELEMETRY_H
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index da7aee01680fc..4e7f9b71c9131 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -65,10 +65,10 @@ void LLDBBaseTelemetryInfo::serialize(Serializer 
&serializer) const {
 void TargetInfo::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);
+  serializer.write("target_uuid", target_uuid);
+  serializer.write("executable_path", executable_path);
+  serializer.write("executable_size", executable_size);
+  serializer.write("arch_name", arch_name);
   if (exit_desc.has_value()) {
     serializer.write("exit_code", exit_desc->exit_code);
     serializer.write("exit_desc", exit_desc->description);
@@ -88,61 +88,50 @@ TelemetryManager::TelemetryManager(std::unique_ptr<Config> 
config)
     : m_config(std::move(config)) {}
 
 llvm::Error TelemetryManager::preDispatch(TelemetryInfo *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;
-
+  // Do nothing for now.
+  // In up-coming patch, this would be where the manager
+  // attach the session_uuid to the entry.
   return llvm::Error::success();
 }
 
-const Config *getConfig() { return m_config.get(); }
+const Config * TelemetryManager::GetConfig() { return m_config.get(); }
+
 
 void TelemetryManager::AtMainExecutableLoadStart(TargetInfo *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 (entry->exec_mod != nullptr) {
+    entry->target_uuid = entry->exec_mod->GetUUID().GetAsString();
+    entry->executalbe_path = 
entry->exec_mod->GetFileSpec().GetPathAsConstString().GetCString();
+    if (auto err = llvm::sys::fs::file_size(
+            entry->exec_mod->GetFileSpec().GetPath(), entry->binary_size)) {
+      // If there was error obtaining it, just reset the size to 0.
+      // Maybe log the error too?
+      entry->binary_size = 0;
     }
+    entry->arch_name = 
entry->exec_mod->GetArchitecture().GetArchitectureName();
   }
 
-  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 main executable load start: 
{0}");
   }
 }
 
 void TelemetryManager::AtMainExecutableLoadEnd(TargetInfo *entry) {
-  // ....
-  dispatch(entry);
+    if (entry->exec_mod != nullptr) {
+      entry->target_uuid = entry->exec_mod->GetUUID().GetAsString();
+      // We don't need the rest of the data since they are already in the 
start entry.
+
+        if (llvm::Error er = dispatch(entry)) {
+          LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er),
+                         "Failed to dispatch entry at main executable load 
start: {0}");
+        }
+    }
 }
 
 std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr;
-TelemetryManager *TelemetryManager::getInstance() { return g_instance.get(); }
+TelemetryManager *TelemetryManager::GetInstance() { return g_instance.get(); }
 
-void TelemetryManager::setInstance(std::unique_ptr<TelemetryManager> manager) {
+void TelemetryManager::SetInstance(std::unique_ptr<TelemetryManager> manager) {
   g_instance = std::move(manager);
 }
 
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index db289fe9c4b64..7ea76694f94d8 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -20,6 +20,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Telemetry.h"
 #include "lldb/Core/SearchFilter.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/SourceManager.h"
@@ -1558,10 +1559,25 @@ void Target::DidExec() {
 
 void Target::SetExecutableModule(ModuleSP &executable_sp,
                                  LoadDependentFiles load_dependent_files) {
+  telemetry::Helper helper;
   Log *log = GetLog(LLDBLog::Target);
   ClearModules(false);
 
   if (executable_sp) {
+    if (helper.TelemetryEnabled()) {
+        telemetry::TargetInfo start_entry;
+        start_entry.start_time = helper.GetStartTime();
+        start_entry.exec_mod =  executable_sp;
+        
telemetry::TelemetryManager::GetInstance()->AtMainExecutableLoadStart(&start_entry);
+
+        helper.RunAtScopeExit([&]() {
+          telemetry::TargetInfo end_entry;
+          end_entry.start_time = helper.GetStartTime();
+          end_entry.end_time = helper.GetCurrentTime();
+          end_entry.exec_mod = executable_sp;
+          
telemetry::TelemetryManager::GetInstance()->AtMainExecutableLoadEnd(&end_entry);
+        });
+    }
     ElapsedTime elapsed(m_stats.GetCreateTime());
     LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",
                        executable_sp->GetFileSpec().GetPath().c_str());
diff --git a/lldb/unittests/Core/TelemetryTest.cpp 
b/lldb/unittests/Core/TelemetryTest.cpp
index 0f2eaccb21a2c..3ee6451429619 100644
--- a/lldb/unittests/Core/TelemetryTest.cpp
+++ b/lldb/unittests/Core/TelemetryTest.cpp
@@ -63,10 +63,10 @@ class FakePlugin : public telemetry::TelemetryManager {
   }
 
   static void Initialize() {
-    telemetry::TelemetryManager::setInstance(std::make_unique<FakePlugin>());
+    telemetry::TelemetryManager::SetInstance(std::make_unique<FakePlugin>());
   }
 
-  static void Terminate() { telemetry::TelemetryManager::setInstance(nullptr); 
}
+  static void Terminate() { telemetry::TelemetryManager::SetInstance(nullptr); 
}
 };
 
 } // namespace lldb_private
@@ -76,7 +76,7 @@ TEST(TelemetryTest, PluginTest) {
   // For tests, we just call it directly.
   lldb_private::FakePlugin::Initialize();
 
-  auto *ins = lldb_private::telemetry::TelemetryManager::getInstance();
+  auto *ins = lldb_private::telemetry::TelemetryManager::GetInstance();
   ASSERT_NE(ins, nullptr);
 
   std::vector<const ::llvm::telemetry::TelemetryInfo *> expected_entries;

>From 4f8555aabec0e264215169eefbf47654bffcd973 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 3 Mar 2025 13:28:09 -0500
Subject: [PATCH 03/10] undo change

---
 lldb/include/lldb/Core/Telemetry.h | 29 -----------------------------
 1 file changed, 29 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 29873d91538a0..34c37d867859b 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -131,35 +131,6 @@ class TelemetryManager : public llvm::telemetry::Manager {
   static std::unique_ptr<TelemetryManager> g_instance;
 };
 
-class Helper {
- public:
-  Helper () : m_start(std::chrono::steady_clock::now()) {}
-  ~Helper() {
-    while(! m_exit_funcs.empty()) {
-      (m_exit_funcs.top())();
-      m_exit_funcs.pop();
-    }
-  }
-
-  bool TelemetryEnabled() {
-    TelemetryManager* instance = TelemetryManager::GetInstance();
-  return instance != nullptr && instance->GetConfig()->EnableTelemetry;
-  }
-
-
-  SteadyTimePoint GetStartTime() {return m_start;}
-  SteadyTimePoint GetCurrentTime()  { return std::chrono::steady_clock::now(); 
}
-
- template <typename Fp>
- void RunAtScopeExit(Fp&& F){
-   m_exit_funcs.push(std::forward<Fp>(F));
- }
-
- private:
-  const SteadyTimePoint m_start;
-  std::stack<std::function<void()>> m_exit_funcs;
-
-};
 
 } // namespace telemetry
 } // namespace lldb_private

>From bb22874973a8c8c5768ad8b612fc37356427e82b Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 3 Mar 2025 14:35:43 -0500
Subject: [PATCH 04/10] update interface

---
 lldb/include/lldb/Core/Telemetry.h | 72 +++++++++++++++++------------
 lldb/source/Core/Telemetry.cpp     | 74 ++++++++++++------------------
 lldb/source/Target/Process.cpp     | 15 ++++++
 lldb/source/Target/Target.cpp      | 29 ++++++------
 4 files changed, 102 insertions(+), 88 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 60f4e0e1aa6f7..4daf00933f86f 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -45,7 +45,7 @@ namespace telemetry {
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000000;
   static const llvm::telemetry::KindType DebuggerInfo = 0b11000100;
-  static const llvm::telemetry::KindType TargetInfo = 0b11001000;  
+  static const llvm::telemetry::KindType TargetInfo = 0b11001000;
 };
 
 /// Defines a convenient type for timestamp of various events.
@@ -82,14 +82,15 @@ struct ExitDescription {
 
 struct TargetInfo : public LLDBBaseTelemetryInfo {
   lldb::ModuleSP exec_mod;
-  Target *target_ptr;
 
   // The same as the executable-module's UUID.
   std::string target_uuid;
-  std::string executable_path;
-  size_t executable_size;
   std::string arch_name;
 
+  // If true, this entry was emitted at the beginning of an event (eg., before 
the executable laod). Otherwise, it was emitted at the end of an event (eg., 
after the module and any dependency were loaded.)
+  bool is_start_entry;
+
+  // Describes the exit of the executable module.
   std::optional<ExitDescription> exit_desc;
   TargetInfo() = default;
 
@@ -98,10 +99,10 @@ struct TargetInfo : public LLDBBaseTelemetryInfo {
   static bool classof(const TelemetryInfo *T) {
    // Subclasses of this is also acceptable
     return (T->getKind() & LLDBEntryKind::TargetInfo) ==
-           LLDBEntryKind::TargetInfo;    
-  }  
+           LLDBEntryKind::TargetInfo;
+  }
 };
-  
+
 struct DebuggerInfo : public LLDBBaseTelemetryInfo {
   std::string lldb_version;
 
@@ -143,10 +144,8 @@ class TelemetryManager : public llvm::telemetry::Manager {
   virtual void AtMainExecutableLoadStart(TargetInfo * entry);
   /// Invoked at the end of the load.
   virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
-  
-  static TelemetryManager *GetInstance();
 
-  static TelemetryManager *GetInstanceIfEnabled();
+  static TelemetryManager *GetInstance();
 
 protected:
   TelemetryManager(std::unique_ptr<llvm::telemetry::Config> config);
@@ -166,39 +165,54 @@ class TelemetryManager : public llvm::telemetry::Manager {
 template <typename Info> struct ScopedDispatcher {
   // The debugger pointer is optional because we may not have a debugger yet.
   // In that case, caller must set the debugger later.
-  ScopedDispatcher(llvm::unique_function<void(Info *info)> callback,
+  ScopedDispatcher(Debugger *debugger = nullptr) {
+    // Start the timer.
+    m_start_time = std::chrono::steady_clock::now();
+    debugger = debugger;
+  }
+  ScopedDispatcher(llvm::unique_function<void(Info *info)> final_callback,
                    Debugger *debugger = nullptr)
-      : m_callback(std::move(callback)) {
+      : m_final_callback(std::move(final_callback)) {
     // Start the timer.
     m_start_time = std::chrono::steady_clock::now();
-    m_info.debugger = debugger;
+    debugger = debugger;
   }
 
-  void SetDebugger(Debugger *debugger) { m_info.debugger = debugger; }
+  void SetDebugger(Debugger *debugger) { debugger = debugger; }
 
-  ~ScopedDispatcher() {
-    // If Telemetry is disabled (either at buildtime or runtime),
-    // then don't do anything.
-    TelemetryManager *manager = TelemetryManager::GetInstanceIfEnabled();
-    if (!manager)
-      return;
+  void DispatchOnExit(llvm::unique_function<void(Info *info)> final_callback) {
+    // We probably should not be overriding previously set cb.
+    assert(!m_final_callback);
+    m_final_callback = std::move(final_callback);
+  }
 
-    m_info.start_time = m_start_time;
-    // Populate common fields that we can only set now.
-    m_info.end_time = std::chrono::steady_clock::now();
-    // The callback will set the remaining fields.
-    m_callback(&m_info);
+  void DispatchNow(llvm::unique_function<void(Info *info)> populate_fields_cb) 
{
+    TelemetryManager *manager = TelemetryManager::GetInstance();
+    if (!manager->GetConfig()->EnableTelemetry)
+      return;
+    Info info;
+    // Populate the common fields we know aboutl
+    info.start_time = m_start_time;
+    info.end_time = std::chrono::steady_clock::now();
+    info.debugger = debugger;
+    // The callback will set the rest.
+    populate_fields_cb(&info);
     // And then we dispatch.
-    if (llvm::Error er = manager->dispatch(&m_info)) {
+    if (llvm::Error er = manager->dispatch(&info)) {
       LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er),
-                     "Failed to dispatch entry of type: {0}", 
m_info.getKind());
+                     "Failed to dispatch entry of type: {0}", info.getKind());
     }
   }
 
+  ~ScopedDispatcher() {
+    if (m_final_callback)
+      DispatchNow(std::move(m_final_callback));
+  }
+
 private:
   SteadyTimePoint m_start_time;
-  llvm::unique_function<void(Info *info)> m_callback;
-  Info m_info;
+  llvm::unique_function<void(Info *info)> m_final_callback;
+  Debugger *debugger;
 };
 
 } // namespace telemetry
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index 4112ed739f2b8..c5b70e0590eb4 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -80,9 +80,8 @@ void TargetInfo::serialize(Serializer &serializer) const {
   LLDBBaseTelemetryInfo::serialize(serializer);
 
   serializer.write("target_uuid", target_uuid);
-  serializer.write("executable_path", executable_path);
-  serializer.write("executable_size", executable_size);
   serializer.write("arch_name", arch_name);
+  serializer.write("is_start_entry", is_start_entry);
   if (exit_desc.has_value()) {
     serializer.write("exit_code", exit_desc->exit_code);
     serializer.write("exit_desc", exit_desc->description);
@@ -109,61 +108,48 @@ llvm::Error TelemetryManager::preDispatch(TelemetryInfo 
*entry) {
     lldb_entry->debugger_id = debugger->GetID();
   return llvm::Error::success();
 }
-  
-void TelemetryManager::AtMainExecutableLoadStart(TargetInfo *entry) {
-  if (entry->exec_mod != nullptr) {
-    entry->target_uuid = entry->exec_mod->GetUUID().GetAsString();
-    entry->executalbe_path = 
entry->exec_mod->GetFileSpec().GetPathAsConstString().GetCString();
-    if (auto err = llvm::sys::fs::file_size(
-            entry->exec_mod->GetFileSpec().GetPath(), entry->binary_size)) {
-      // If there was error obtaining it, just reset the size to 0.
-      // Maybe log the error too?
-      entry->binary_size = 0;
-    }
-    entry->arch_name = 
entry->exec_mod->GetArchitecture().GetArchitectureName();
-  }
 
-  if (llvm::Error er = dispatch(entry)) {
-    LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er),
-                   "Failed to dispatch entry at main executable load start: 
{0}");
+const Config *TelemetryManager::GetConfig() { return m_config.get(); }
+
+class NoOpTelemetryManager : public TelemetryManager {
+public:
+  llvm::Error preDispatch(llvm::telemetry::TelemetryInfo *entry) override {
+    // Does nothing.
+    return llvm::Error::success();
   }
-}
 
-void TelemetryManager::AtMainExecutableLoadEnd(TargetInfo *entry) {
-    if (entry->exec_mod != nullptr) {
-      entry->target_uuid = entry->exec_mod->GetUUID().GetAsString();
-      // We don't need the rest of the data since they are already in the 
start entry.
+  explicit NoOpTelemetryManager()
+      : TelemetryManager(std::make_unique<LLDBConfig>(
+            /*EnableTelemetry*/ false, /*DetailedCommand*/ false)) {}
 
-        if (llvm::Error er = dispatch(entry)) {
-          LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er),
-                         "Failed to dispatch entry at main executable load 
start: {0}");
-        }
-    }
-}
+  virtual llvm::StringRef GetInstanceName() const override {
+    return "NoOpTelemetryManager";
+  }
 
+  llvm::Error dispatch(llvm::telemetry::TelemetryInfo *entry) override {
+    // Does nothing.
+    return llvm::Error::success();
+  }
 
-const Config *TelemetryManager::GetConfig() { return m_config.get(); }
+  static NoOpTelemetryManager *GetInstance() {
+    static std::unique_ptr<NoOpTelemetryManager> g_ins =
+        std::make_unique<NoOpTelemetryManager>();
+    return g_ins.get();
+  }
+};
 
 std::unique_ptr<TelemetryManager> TelemetryManager::g_instance = nullptr;
 TelemetryManager *TelemetryManager::GetInstance() {
-  if (!Config::BuildTimeEnableTelemetry)
-    return nullptr;
+  // If Telemetry is disabled or if there is no default instance, then use the
+  // NoOp manager. We use a dummy instance to avoid having to do nullchecks in
+  // various places.
+  if (!Config::BuildTimeEnableTelemetry || !g_instance)
+    return NoOpTelemetryManager::GetInstance();
   return g_instance.get();
 }
 
-TelemetryManager *TelemetryManager::GetInstanceIfEnabled() {
-  // Telemetry may be enabled at build time but disabled at runtime.
-  if (TelemetryManager *ins = TelemetryManager::GetInstance()) {
-    if (ins->GetConfig()->EnableTelemetry)
-      return ins;
-  }
-
-  return nullptr;
-}
-
 void TelemetryManager::SetInstance(std::unique_ptr<TelemetryManager> manager) {
-  if (Config::BuildTimeEnableTelemetry)
-    g_instance = std::move(manager);
+  g_instance = std::move(manager);
 }
 
 } // namespace telemetry
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f2f5598f0ab53..cee6620612ece 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -22,6 +22,7 @@
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Progress.h"
+#include "lldb/Core/Telemetry.h"
 #include "lldb/Expression/DiagnosticManager.h"
 #include "lldb/Expression/DynamicCheckerFunctions.h"
 #include "lldb/Expression/UserExpression.h"
@@ -1064,6 +1065,20 @@ const char *Process::GetExitDescription() {
 bool Process::SetExitStatus(int status, llvm::StringRef exit_string) {
   // Use a mutex to protect setting the exit status.
   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
+  Debugger* debugger = &(GetTarget().GetDebugger());
+  telemetry::ScopedDispatch<telemetry::TargetInfo> helper (debugger);
+  // Save the Module UUID since the Module might be gone by end of scope.
+  std::string target_uuid = 
GetTarget().GetExecutableModule()->GetUUID().GetAsString();
+
+  helper.DispatchNow([&](telemetry::TargetInfo *info){
+    info->target_uuid = target_uuid;
+    info->is_start_entry = true;
+  });
+
+  helper.DispatchOnExit([&](telemetry::TargetInfo *info) {
+    info->target_uuid = target_uuid;
+    info->exit_desc = {status, exit_string.str()};
+  });
 
   Log *log(GetLog(LLDBLog::State | LLDBLog::Process));
   LLDB_LOG(log, "(plugin = {0} status = {1} ({1:x8}), description=\"{2}\")",
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index abd73370928c0..9fafccbb88a8d 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1560,25 +1560,24 @@ void Target::DidExec() {
 
 void Target::SetExecutableModule(ModuleSP &executable_sp,
                                  LoadDependentFiles load_dependent_files) {
-  telemetry::Helper helper;
+  telemetry::ScopedDispatcher<telemetry::TargetInfo> helper(&m_debugger);
   Log *log = GetLog(LLDBLog::Target);
   ClearModules(false);
 
   if (executable_sp) {
-    if (helper.TelemetryEnabled()) {
-        telemetry::TargetInfo start_entry;
-        start_entry.start_time = helper.GetStartTime();
-        start_entry.exec_mod =  executable_sp;
-        
telemetry::TelemetryManager::GetInstance()->AtMainExecutableLoadStart(&start_entry);
-
-        helper.RunAtScopeExit([&]() {
-          telemetry::TargetInfo end_entry;
-          end_entry.start_time = helper.GetStartTime();
-          end_entry.end_time = helper.GetCurrentTime();
-          end_entry.exec_mod = executable_sp;
-          
telemetry::TelemetryManager::GetInstance()->AtMainExecutableLoadEnd(&end_entry);
-        });
-    }
+    helper.DispatchNow([&](telemetry::TargetInfo *info) {
+      info->exec_mod = executable_sp;
+      info->target_uuid = executable_sp->GetUUID().GetAsString();
+      info->arch_name = executable_sp->GetArchitecture().GetArchitectureName();
+      info->is_start_entry = true;
+    });
+
+    helper.DispatchOnExit([&](telemetry::TargetInfo *info) {
+      info->exec_mod = executable_sp;
+      info->target_uuid = executable_sp->GetUUID().GetAsString();
+
+    });
+
     ElapsedTime elapsed(m_stats.GetCreateTime());
     LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",
                        executable_sp->GetFileSpec().GetPath().c_str());

>From f49c3e2ca42454430466d5beab5ba5bb0a17070d Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 3 Mar 2025 15:12:04 -0500
Subject: [PATCH 05/10] formatting

---
 lldb/include/lldb/Core/Telemetry.h | 19 ++++++++++++-------
 lldb/source/Target/Process.cpp     |  9 +++++----
 lldb/source/Target/Target.cpp      |  3 +--
 3 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 4daf00933f86f..7614021b95d7d 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -26,10 +26,10 @@
 #include <optional>
 #include <string>
 
-#include <unordered_map>
+#include <functional>
 #include <type_traits>
+#include <unordered_map>
 #include <utility>
-#include <functional>
 
 namespace lldb_private {
 namespace telemetry {
@@ -41,7 +41,8 @@ namespace telemetry {
 //  - First two bits (MSB) must be 11 - the common prefix
 //  - Last two bits (LSB) are reserved for grand-children of LLDBTelemetryInfo
 // If any of the subclass has descendents, those descendents
-// must have their LLDBEntryKind in the similar form (ie., share common prefix 
and differ by the last two bits)
+// must have their LLDBEntryKind in the similar form (ie., share common prefix
+// and differ by the last two bits)
 struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
   static const llvm::telemetry::KindType BaseInfo = 0b11000000;
   static const llvm::telemetry::KindType DebuggerInfo = 0b11000100;
@@ -87,17 +88,21 @@ struct TargetInfo : public LLDBBaseTelemetryInfo {
   std::string target_uuid;
   std::string arch_name;
 
-  // If true, this entry was emitted at the beginning of an event (eg., before 
the executable laod). Otherwise, it was emitted at the end of an event (eg., 
after the module and any dependency were loaded.)
+  // If true, this entry was emitted at the beginning of an event (eg., before
+  // the executable laod). Otherwise, it was emitted at the end of an event
+  // (eg., after the module and any dependency were loaded.)
   bool is_start_entry;
 
   // Describes the exit of the executable module.
   std::optional<ExitDescription> exit_desc;
   TargetInfo() = default;
 
-  llvm::telemetry::KindType getKind() const override { return 
LLDBEntryKind::TargetInfo; }
+  llvm::telemetry::KindType getKind() const override {
+    return LLDBEntryKind::TargetInfo;
+  }
 
   static bool classof(const TelemetryInfo *T) {
-   // Subclasses of this is also acceptable
+    // Subclasses of this is also acceptable
     return (T->getKind() & LLDBEntryKind::TargetInfo) ==
            LLDBEntryKind::TargetInfo;
   }
@@ -141,7 +146,7 @@ class TelemetryManager : public llvm::telemetry::Manager {
   /// during the action.
   ///
   /// Invoked at the begining of the load of the main-executable.
-  virtual void AtMainExecutableLoadStart(TargetInfo * entry);
+  virtual void AtMainExecutableLoadStart(TargetInfo *entry);
   /// Invoked at the end of the load.
   virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
 
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index cee6620612ece..6216aabb3ff4e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1065,12 +1065,13 @@ const char *Process::GetExitDescription() {
 bool Process::SetExitStatus(int status, llvm::StringRef exit_string) {
   // Use a mutex to protect setting the exit status.
   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
-  Debugger* debugger = &(GetTarget().GetDebugger());
-  telemetry::ScopedDispatch<telemetry::TargetInfo> helper (debugger);
+  Debugger *debugger = &(GetTarget().GetDebugger());
+  telemetry::ScopedDispatch<telemetry::TargetInfo> helper(debugger);
   // Save the Module UUID since the Module might be gone by end of scope.
-  std::string target_uuid = 
GetTarget().GetExecutableModule()->GetUUID().GetAsString();
+  std::string target_uuid =
+      GetTarget().GetExecutableModule()->GetUUID().GetAsString();
 
-  helper.DispatchNow([&](telemetry::TargetInfo *info){
+  helper.DispatchNow([&](telemetry::TargetInfo *info) {
     info->target_uuid = target_uuid;
     info->is_start_entry = true;
   });
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 9fafccbb88a8d..960027c6e6465 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -20,11 +20,11 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
-#include "lldb/Core/Telemetry.h"
 #include "lldb/Core/SearchFilter.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/SourceManager.h"
 #include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Core/Telemetry.h"
 #include "lldb/DataFormatters/FormatterSection.h"
 #include "lldb/Expression/DiagnosticManager.h"
 #include "lldb/Expression/ExpressionVariable.h"
@@ -1575,7 +1575,6 @@ void Target::SetExecutableModule(ModuleSP &executable_sp,
     helper.DispatchOnExit([&](telemetry::TargetInfo *info) {
       info->exec_mod = executable_sp;
       info->target_uuid = executable_sp->GetUUID().GetAsString();
-
     });
 
     ElapsedTime elapsed(m_stats.GetCreateTime());

>From 3bd88970fdf0e9cf3955f17d79710e959fc8ca98 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 3 Mar 2025 15:43:09 -0500
Subject: [PATCH 06/10] remove unused

---
 lldb/include/lldb/Core/Telemetry.h | 12 +-----------
 lldb/source/Core/Telemetry.cpp     | 20 ++------------------
 lldb/source/Target/Process.cpp     |  2 +-
 3 files changed, 4 insertions(+), 30 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 7614021b95d7d..a5f5ef1df1f94 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -106,6 +106,7 @@ struct TargetInfo : public LLDBBaseTelemetryInfo {
     return (T->getKind() & LLDBEntryKind::TargetInfo) ==
            LLDBEntryKind::TargetInfo;
   }
+  void serialize(llvm::telemetry::Serializer &serializer) const override;
 };
 
 struct DebuggerInfo : public LLDBBaseTelemetryInfo {
@@ -139,17 +140,6 @@ class TelemetryManager : public llvm::telemetry::Manager {
 
   virtual llvm::StringRef GetInstanceName() const = 0;
 
-  /// The following methods are for reporting the load of an executable.
-  /// One is invoked at the beginning of the process and the other at
-  /// the end.
-  /// This is done in two passes to avoid losing date in case of any 
error/crash
-  /// during the action.
-  ///
-  /// Invoked at the begining of the load of the main-executable.
-  virtual void AtMainExecutableLoadStart(TargetInfo *entry);
-  /// Invoked at the end of the load.
-  virtual void AtMainExecutableLoadEnd(TargetInfo *entry);
-
   static TelemetryManager *GetInstance();
 
 protected:
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index c5b70e0590eb4..7e66c6f059a05 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -68,14 +68,6 @@ void DebuggerInfo::serialize(Serializer &serializer) const {
   serializer.write("is_exit_entry", is_exit_entry);
 }
 
-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 TargetInfo::serialize(Serializer &serializer) const {
   LLDBBaseTelemetryInfo::serialize(serializer);
 
@@ -88,14 +80,6 @@ void TargetInfo::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()) {}
@@ -119,8 +103,8 @@ class NoOpTelemetryManager : public TelemetryManager {
   }
 
   explicit NoOpTelemetryManager()
-      : TelemetryManager(std::make_unique<LLDBConfig>(
-            /*EnableTelemetry*/ false, /*DetailedCommand*/ false)) {}
+      : TelemetryManager(std::make_unique<::llvm::telemetry::Config>(
+            /*EnableTelemetry*/ false)) {}
 
   virtual llvm::StringRef GetInstanceName() const override {
     return "NoOpTelemetryManager";
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 6216aabb3ff4e..f5f3f7f902e8a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1066,7 +1066,7 @@ bool Process::SetExitStatus(int status, llvm::StringRef 
exit_string) {
   // Use a mutex to protect setting the exit status.
   std::lock_guard<std::mutex> guard(m_exit_status_mutex);
   Debugger *debugger = &(GetTarget().GetDebugger());
-  telemetry::ScopedDispatch<telemetry::TargetInfo> helper(debugger);
+  telemetry::ScopedDispatcher<telemetry::TargetInfo> helper(debugger);
   // Save the Module UUID since the Module might be gone by end of scope.
   std::string target_uuid =
       GetTarget().GetExecutableModule()->GetUUID().GetAsString();

>From d3cb8d883f77ddc2f85333e8c80380dc3c67fe5a Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Mon, 3 Mar 2025 15:51:48 -0500
Subject: [PATCH 07/10] formatting

---
 lldb/source/Core/Telemetry.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index 7e66c6f059a05..d026df4699e29 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -80,7 +80,6 @@ void TargetInfo::serialize(Serializer &serializer) const {
   }
 }
 
-
 TelemetryManager::TelemetryManager(std::unique_ptr<Config> config)
     : m_config(std::move(config)), m_id(MakeUUID()) {}
 

>From 267345a46b10875d54cbcf742061ec199669459b Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Tue, 4 Mar 2025 09:59:02 -0500
Subject: [PATCH 08/10] qual

---
 lldb/include/lldb/Core/Telemetry.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index a5f5ef1df1f94..3a138dc0d7787 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -170,10 +170,10 @@ template <typename Info> struct ScopedDispatcher {
       : m_final_callback(std::move(final_callback)) {
     // Start the timer.
     m_start_time = std::chrono::steady_clock::now();
-    debugger = debugger;
+    this->debugger = debugger;
   }
 
-  void SetDebugger(Debugger *debugger) { debugger = debugger; }
+  void SetDebugger(Debugger *debugger) { this->debugger = debugger; }
 
   void DispatchOnExit(llvm::unique_function<void(Info *info)> final_callback) {
     // We probably should not be overriding previously set cb.

>From 32d949bcefc6fe489df073878ee34f2f738e0ea9 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Wed, 5 Mar 2025 12:21:27 -0500
Subject: [PATCH 09/10] use UUID for target_uuid

---
 lldb/include/lldb/Core/Telemetry.h | 12 ++++++------
 lldb/source/Core/Telemetry.cpp     |  2 +-
 lldb/source/Target/Process.cpp     |  3 +--
 lldb/source/Target/Target.cpp      |  4 ++--
 4 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index 3a138dc0d7787..fed5c88c0df90 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -84,16 +84,16 @@ struct ExitDescription {
 struct TargetInfo : public LLDBBaseTelemetryInfo {
   lldb::ModuleSP exec_mod;
 
-  // The same as the executable-module's UUID.
-  std::string target_uuid;
+  /// The same as the executable-module's UUID.
+  UUID target_uuid;
   std::string arch_name;
 
-  // If true, this entry was emitted at the beginning of an event (eg., before
-  // the executable laod). Otherwise, it was emitted at the end of an event
-  // (eg., after the module and any dependency were loaded.)
+  /// If true, this entry was emitted at the beginning of an event (eg., before
+  /// the executable is loaded). Otherwise, it was emitted at the end of an
+  /// event (eg., after the module and any dependency were loaded.)
   bool is_start_entry;
 
-  // Describes the exit of the executable module.
+  /// Describes the exit of the executable module.
   std::optional<ExitDescription> exit_desc;
   TargetInfo() = default;
 
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index d026df4699e29..1ebedbf59ec84 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -71,7 +71,7 @@ void DebuggerInfo::serialize(Serializer &serializer) const {
 void TargetInfo::serialize(Serializer &serializer) const {
   LLDBBaseTelemetryInfo::serialize(serializer);
 
-  serializer.write("target_uuid", target_uuid);
+  serializer.write("target_uuid", target_uuid.GetAsString());
   serializer.write("arch_name", arch_name);
   serializer.write("is_start_entry", is_start_entry);
   if (exit_desc.has_value()) {
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f5f3f7f902e8a..52c3ae5195d41 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -1068,8 +1068,7 @@ bool Process::SetExitStatus(int status, llvm::StringRef 
exit_string) {
   Debugger *debugger = &(GetTarget().GetDebugger());
   telemetry::ScopedDispatcher<telemetry::TargetInfo> helper(debugger);
   // Save the Module UUID since the Module might be gone by end of scope.
-  std::string target_uuid =
-      GetTarget().GetExecutableModule()->GetUUID().GetAsString();
+  UUID target_uuid = GetTarget().GetExecutableModule()->GetUUID();
 
   helper.DispatchNow([&](telemetry::TargetInfo *info) {
     info->target_uuid = target_uuid;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 960027c6e6465..7872d27437585 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1567,14 +1567,14 @@ void Target::SetExecutableModule(ModuleSP 
&executable_sp,
   if (executable_sp) {
     helper.DispatchNow([&](telemetry::TargetInfo *info) {
       info->exec_mod = executable_sp;
-      info->target_uuid = executable_sp->GetUUID().GetAsString();
+      info->target_uuid = executable_sp->GetUUID();
       info->arch_name = executable_sp->GetArchitecture().GetArchitectureName();
       info->is_start_entry = true;
     });
 
     helper.DispatchOnExit([&](telemetry::TargetInfo *info) {
       info->exec_mod = executable_sp;
-      info->target_uuid = executable_sp->GetUUID().GetAsString();
+      info->target_uuid = executable_sp->GetUUID();
     });
 
     ElapsedTime elapsed(m_stats.GetCreateTime());

>From 1fdf120fd540d521bbd17eb3b93dff28a4ccd7a4 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <v...@google.com>
Date: Fri, 7 Mar 2025 19:04:26 -0500
Subject: [PATCH 10/10] revert dup

---
 lldb/include/lldb/Core/Telemetry.h | 54 ------------------------------
 1 file changed, 54 deletions(-)

diff --git a/lldb/include/lldb/Core/Telemetry.h 
b/lldb/include/lldb/Core/Telemetry.h
index fed5c88c0df90..879506b154d82 100644
--- a/lldb/include/lldb/Core/Telemetry.h
+++ b/lldb/include/lldb/Core/Telemetry.h
@@ -156,60 +156,6 @@ class TelemetryManager : public llvm::telemetry::Manager {
   static std::unique_ptr<TelemetryManager> g_instance;
 };
 
-/// Helper RAII class for collecting telemetry.
-template <typename Info> struct ScopedDispatcher {
-  // The debugger pointer is optional because we may not have a debugger yet.
-  // In that case, caller must set the debugger later.
-  ScopedDispatcher(Debugger *debugger = nullptr) {
-    // Start the timer.
-    m_start_time = std::chrono::steady_clock::now();
-    debugger = debugger;
-  }
-  ScopedDispatcher(llvm::unique_function<void(Info *info)> final_callback,
-                   Debugger *debugger = nullptr)
-      : m_final_callback(std::move(final_callback)) {
-    // Start the timer.
-    m_start_time = std::chrono::steady_clock::now();
-    this->debugger = debugger;
-  }
-
-  void SetDebugger(Debugger *debugger) { this->debugger = debugger; }
-
-  void DispatchOnExit(llvm::unique_function<void(Info *info)> final_callback) {
-    // We probably should not be overriding previously set cb.
-    assert(!m_final_callback);
-    m_final_callback = std::move(final_callback);
-  }
-
-  void DispatchNow(llvm::unique_function<void(Info *info)> populate_fields_cb) 
{
-    TelemetryManager *manager = TelemetryManager::GetInstance();
-    if (!manager->GetConfig()->EnableTelemetry)
-      return;
-    Info info;
-    // Populate the common fields we know aboutl
-    info.start_time = m_start_time;
-    info.end_time = std::chrono::steady_clock::now();
-    info.debugger = debugger;
-    // The callback will set the rest.
-    populate_fields_cb(&info);
-    // And then we dispatch.
-    if (llvm::Error er = manager->dispatch(&info)) {
-      LLDB_LOG_ERROR(GetLog(LLDBLog::Object), std::move(er),
-                     "Failed to dispatch entry of type: {0}", info.getKind());
-    }
-  }
-
-  ~ScopedDispatcher() {
-    if (m_final_callback)
-      DispatchNow(std::move(m_final_callback));
-  }
-
-private:
-  SteadyTimePoint m_start_time;
-  llvm::unique_function<void(Info *info)> m_final_callback;
-  Debugger *debugger;
-};
-
 } // namespace telemetry
 } // namespace lldb_private
 #endif // LLDB_CORE_TELEMETRY_H

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to