Skip to content

Commit ff21b50

Browse files
authored
Reapply LLDB-Telemetry TargetInfo branch (pr/127834) (#132043)
New changes: add check to avoid accessing invalid obj
1 parent e86d627 commit ff21b50

File tree

5 files changed

+135
-9
lines changed

5 files changed

+135
-9
lines changed

lldb/include/lldb/Core/Telemetry.h

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
#include <atomic>
2424
#include <chrono>
2525
#include <ctime>
26+
#include <functional>
2627
#include <memory>
2728
#include <optional>
2829
#include <string>
30+
#include <type_traits>
31+
#include <utility>
2932

3033
namespace lldb_private {
3134
namespace telemetry {
@@ -46,12 +49,18 @@ struct LLDBConfig : public ::llvm::telemetry::Config {
4649
// Specifically:
4750
// - Length: 8 bits
4851
// - First two bits (MSB) must be 11 - the common prefix
52+
// - Last two bits (LSB) are reserved for grand-children of LLDBTelemetryInfo
4953
// If any of the subclass has descendents, those descendents
50-
// must have their LLDBEntryKind in the similar form (ie., share common prefix)
54+
// must have their LLDBEntryKind in the similar form (ie., share common prefix
55+
// and differ by the last two bits)
5156
struct LLDBEntryKind : public ::llvm::telemetry::EntryKind {
52-
static const llvm::telemetry::KindType BaseInfo = 0b11000000;
53-
static const llvm::telemetry::KindType CommandInfo = 0b11010000;
54-
static const llvm::telemetry::KindType DebuggerInfo = 0b11000100;
57+
// clang-format off
58+
static const llvm::telemetry::KindType BaseInfo = 0b11000000;
59+
static const llvm::telemetry::KindType CommandInfo = 0b11010000;
60+
static const llvm::telemetry::KindType DebuggerInfo = 0b11001000;
61+
static const llvm::telemetry::KindType ExecModuleInfo = 0b11000100;
62+
static const llvm::telemetry::KindType ProcessExitInfo = 0b11001100;
63+
// clang-format on
5564
};
5665

5766
/// Defines a convenient type for timestamp of various events.
@@ -89,7 +98,7 @@ struct CommandInfo : public LLDBBaseTelemetryInfo {
8998
/// session. Necessary because we'd send off an entry right before a command's
9099
/// execution and another right after. This is to avoid losing telemetry if
91100
/// the command does not execute successfully.
92-
uint64_t command_id;
101+
uint64_t command_id = 0;
93102
/// The command name(eg., "breakpoint set")
94103
std::string command_name;
95104
/// These two fields are not collected by default due to PII risks.
@@ -116,7 +125,7 @@ struct CommandInfo : public LLDBBaseTelemetryInfo {
116125

117126
void serialize(llvm::telemetry::Serializer &serializer) const override;
118127

119-
static uint64_t GetNextId();
128+
static uint64_t GetNextID();
120129

121130
private:
122131
// We assign each command (in the same session) a unique id so that their
@@ -146,6 +155,59 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo {
146155
void serialize(llvm::telemetry::Serializer &serializer) const override;
147156
};
148157

158+
struct ExecutableModuleInfo : public LLDBBaseTelemetryInfo {
159+
lldb::ModuleSP exec_mod;
160+
/// The same as the executable-module's UUID.
161+
UUID uuid;
162+
/// PID of the process owned by this target.
163+
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
164+
/// The triple of this executable module.
165+
std::string triple;
166+
167+
/// If true, this entry was emitted at the beginning of an event (eg., before
168+
/// the executable is set). Otherwise, it was emitted at the end of an
169+
/// event (eg., after the module and any dependency were loaded.)
170+
bool is_start_entry = false;
171+
172+
ExecutableModuleInfo() = default;
173+
174+
llvm::telemetry::KindType getKind() const override {
175+
return LLDBEntryKind::ExecModuleInfo;
176+
}
177+
178+
static bool classof(const TelemetryInfo *T) {
179+
// Subclasses of this is also acceptable
180+
return (T->getKind() & LLDBEntryKind::ExecModuleInfo) ==
181+
LLDBEntryKind::ExecModuleInfo;
182+
}
183+
void serialize(llvm::telemetry::Serializer &serializer) const override;
184+
};
185+
186+
/// Describes an exit status.
187+
struct ExitDescription {
188+
int exit_code;
189+
std::string description;
190+
};
191+
192+
struct ProcessExitInfo : public LLDBBaseTelemetryInfo {
193+
// The executable-module's UUID.
194+
UUID module_uuid;
195+
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
196+
bool is_start_entry = false;
197+
std::optional<ExitDescription> exit_desc;
198+
199+
llvm::telemetry::KindType getKind() const override {
200+
return LLDBEntryKind::ProcessExitInfo;
201+
}
202+
203+
static bool classof(const TelemetryInfo *T) {
204+
// Subclasses of this is also acceptable
205+
return (T->getKind() & LLDBEntryKind::ProcessExitInfo) ==
206+
LLDBEntryKind::ProcessExitInfo;
207+
}
208+
void serialize(llvm::telemetry::Serializer &serializer) const override;
209+
};
210+
149211
/// The base Telemetry manager instance in LLDB.
150212
/// This class declares additional instrumentation points
151213
/// applicable to LLDB.

lldb/source/Core/Telemetry.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,36 @@ void CommandInfo::serialize(Serializer &serializer) const {
7676
serializer.write("error_data", error_data.value());
7777
}
7878

79+
std::atomic<uint64_t> CommandInfo::g_command_id_seed = 1;
80+
uint64_t CommandInfo::GetNextID() { return g_command_id_seed.fetch_add(1); }
81+
7982
void DebuggerInfo::serialize(Serializer &serializer) const {
8083
LLDBBaseTelemetryInfo::serialize(serializer);
8184

8285
serializer.write("lldb_version", lldb_version);
8386
serializer.write("is_exit_entry", is_exit_entry);
8487
}
8588

86-
std::atomic<uint64_t> CommandInfo::g_command_id_seed = 0;
87-
uint64_t CommandInfo::GetNextId() { return g_command_id_seed.fetch_add(1); }
89+
void ExecutableModuleInfo::serialize(Serializer &serializer) const {
90+
LLDBBaseTelemetryInfo::serialize(serializer);
91+
92+
serializer.write("uuid", uuid.GetAsString());
93+
serializer.write("pid", pid);
94+
serializer.write("triple", triple);
95+
serializer.write("is_start_entry", is_start_entry);
96+
}
97+
98+
void ProcessExitInfo::serialize(Serializer &serializer) const {
99+
LLDBBaseTelemetryInfo::serialize(serializer);
100+
101+
serializer.write("module_uuid", module_uuid.GetAsString());
102+
serializer.write("pid", pid);
103+
serializer.write("is_start_entry", is_start_entry);
104+
if (exit_desc.has_value()) {
105+
serializer.write("exit_code", exit_desc->exit_code);
106+
serializer.write("exit_desc", exit_desc->description);
107+
}
108+
}
88109

89110
TelemetryManager::TelemetryManager(std::unique_ptr<LLDBConfig> config)
90111
: m_config(std::move(config)), m_id(MakeUUID()) {}

lldb/source/Interpreter/CommandInterpreter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,7 @@ bool CommandInterpreter::HandleCommand(const char *command_line,
18911891
telemetry::TelemetryManager::GetInstance()
18921892
->GetConfig()
18931893
->detailed_command_telemetry;
1894-
const int command_id = telemetry::CommandInfo::GetNextId();
1894+
const int command_id = telemetry::CommandInfo::GetNextID();
18951895

18961896
std::string command_string(command_line);
18971897
std::string original_command_string(command_string);

lldb/source/Target/Process.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Core/ModuleSpec.h"
2323
#include "lldb/Core/PluginManager.h"
2424
#include "lldb/Core/Progress.h"
25+
#include "lldb/Core/Telemetry.h"
2526
#include "lldb/Expression/DiagnosticManager.h"
2627
#include "lldb/Expression/DynamicCheckerFunctions.h"
2728
#include "lldb/Expression/UserExpression.h"
@@ -1066,6 +1067,27 @@ const char *Process::GetExitDescription() {
10661067
bool Process::SetExitStatus(int status, llvm::StringRef exit_string) {
10671068
// Use a mutex to protect setting the exit status.
10681069
std::lock_guard<std::mutex> guard(m_exit_status_mutex);
1070+
telemetry::ScopedDispatcher<telemetry::ProcessExitInfo> helper;
1071+
1072+
UUID module_uuid;
1073+
// Need this check because the pointer may not be valid at this point.
1074+
if (TargetSP target_sp = m_target_wp.lock()) {
1075+
helper.SetDebugger(&target_sp->GetDebugger());
1076+
if (ModuleSP mod = target_sp->GetExecutableModule())
1077+
module_uuid = mod->GetUUID();
1078+
}
1079+
1080+
helper.DispatchNow([&](telemetry::ProcessExitInfo *info) {
1081+
info->module_uuid = module_uuid;
1082+
info->pid = m_pid;
1083+
info->is_start_entry = true;
1084+
info->exit_desc = {status, exit_string.str()};
1085+
});
1086+
1087+
helper.DispatchOnExit([&](telemetry::ProcessExitInfo *info) {
1088+
info->module_uuid = module_uuid;
1089+
info->pid = m_pid;
1090+
});
10691091

10701092
Log *log(GetLog(LLDBLog::State | LLDBLog::Process));
10711093
LLDB_LOG(log, "(plugin = {0} status = {1} ({1:x8}), description=\"{2}\")",

lldb/source/Target/Target.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "lldb/Core/Section.h"
2525
#include "lldb/Core/SourceManager.h"
2626
#include "lldb/Core/StructuredDataImpl.h"
27+
#include "lldb/Core/Telemetry.h"
2728
#include "lldb/DataFormatters/FormatterSection.h"
2829
#include "lldb/Expression/DiagnosticManager.h"
2930
#include "lldb/Expression/ExpressionVariable.h"
@@ -1559,10 +1560,30 @@ void Target::DidExec() {
15591560

15601561
void Target::SetExecutableModule(ModuleSP &executable_sp,
15611562
LoadDependentFiles load_dependent_files) {
1563+
telemetry::ScopedDispatcher<telemetry::ExecutableModuleInfo> helper(
1564+
&m_debugger);
15621565
Log *log = GetLog(LLDBLog::Target);
15631566
ClearModules(false);
15641567

15651568
if (executable_sp) {
1569+
lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
1570+
if (ProcessSP proc = GetProcessSP())
1571+
pid = proc->GetID();
1572+
1573+
helper.DispatchNow([&](telemetry::ExecutableModuleInfo *info) {
1574+
info->exec_mod = executable_sp;
1575+
info->uuid = executable_sp->GetUUID();
1576+
info->pid = pid;
1577+
info->triple = executable_sp->GetArchitecture().GetTriple().getTriple();
1578+
info->is_start_entry = true;
1579+
});
1580+
1581+
helper.DispatchOnExit([&](telemetry::ExecutableModuleInfo *info) {
1582+
info->exec_mod = executable_sp;
1583+
info->uuid = executable_sp->GetUUID();
1584+
info->pid = pid;
1585+
});
1586+
15661587
ElapsedTime elapsed(m_stats.GetCreateTime());
15671588
LLDB_SCOPED_TIMERF("Target::SetExecutableModule (executable = '%s')",
15681589
executable_sp->GetFileSpec().GetPath().c_str());

0 commit comments

Comments
 (0)