[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)
Vy Nguyen via lldb-commits
lldb-commits at lists.llvm.org
Wed Feb 19 09:49:24 PST 2025
https://github.com/oontvoo created https://github.com/llvm/llvm-project/pull/127834
None
>From 0d6a36d84df50ccb9eef9ef3dd6f59d4299edeac Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 19 Feb 2025 12:47:57 -0500
Subject: [PATCH] [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(); }
More information about the lldb-commits
mailing list