Skip to content

[lldb] Hoist UUID generation into the UUID class #133662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Apr 2, 2025

Conversation

JDevlieghere
Copy link
Member

Hoist UUID generation into the UUID class and add a trivial unit test. This also changes the telemetry code to drop the double underscore if we failed to generate a UUID and subsequently logs to the Host instead of Object log channel.

@JDevlieghere JDevlieghere requested review from oontvoo and labath March 30, 2025 23:11
@llvmbot llvmbot added the lldb label Mar 30, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 30, 2025

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Hoist UUID generation into the UUID class and add a trivial unit test. This also changes the telemetry code to drop the double underscore if we failed to generate a UUID and subsequently logs to the Host instead of Object log channel.


Full diff: https://github.com/llvm/llvm-project/pull/133662.diff

4 Files Affected:

  • (modified) lldb/include/lldb/Utility/UUID.h (+9-6)
  • (modified) lldb/source/Core/Telemetry.cpp (+11-10)
  • (modified) lldb/source/Utility/UUID.cpp (+8)
  • (modified) lldb/unittests/Utility/UUIDTest.cpp (+6-2)
diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h
index bc4b4acd5a7d8..42c8844148776 100644
--- a/lldb/include/lldb/Utility/UUID.h
+++ b/lldb/include/lldb/Utility/UUID.h
@@ -12,6 +12,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
 #include <cstddef>
 #include <cstdint>
 #include <string>
@@ -26,7 +27,7 @@ class UUID {
   // will return false for IsValid.
 public:
   UUID() = default;
-  
+
   /// Creates a uuid from the data pointed to by the bytes argument.
   UUID(llvm::ArrayRef<uint8_t> bytes) : m_bytes(bytes) {
     if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) {
@@ -50,13 +51,12 @@ class UUID {
   /// Create a UUID from CvRecordPdb70.
   UUID(CvRecordPdb70 debug_info);
 
-  /// Creates a UUID from the data pointed to by the bytes argument. 
+  /// Creates a UUID from the data pointed to by the bytes argument.
   UUID(const void *bytes, uint32_t num_bytes) {
     if (!bytes)
       return;
-    *this 
-        = UUID(llvm::ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(bytes), 
-               num_bytes));
+    *this = UUID(llvm::ArrayRef<uint8_t>(
+        reinterpret_cast<const uint8_t *>(bytes), num_bytes));
   }
 
   void Clear() { m_bytes.clear(); }
@@ -67,7 +67,7 @@ class UUID {
 
   explicit operator bool() const { return IsValid(); }
   bool IsValid() const { return !m_bytes.empty(); }
-  
+
   std::string GetAsString(llvm::StringRef separator = "-") const;
 
   bool SetFromStringRef(llvm::StringRef str);
@@ -88,6 +88,9 @@ class UUID {
   DecodeUUIDBytesFromString(llvm::StringRef str,
                             llvm::SmallVectorImpl<uint8_t> &uuid_bytes);
 
+  /// Generate a random UUID.
+  static llvm::Expected<UUID> Generate();
+
 private:
   // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations
   // for this case.
diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp
index c7789d43c7899..e9ba7d1845bb4 100644
--- a/lldb/source/Core/Telemetry.cpp
+++ b/lldb/source/Core/Telemetry.cpp
@@ -9,15 +9,18 @@
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Telemetry.h"
 #include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
 #include "lldb/Utility/UUID.h"
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
 #include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Telemetry/Telemetry.h"
 #include <chrono>
 #include <cstdlib>
+#include <ctime>
 #include <memory>
 #include <string>
 #include <utility>
@@ -37,18 +40,16 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) {
 // 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());
-  } else {
-    randomString = UUID(random_bytes).GetAsString();
+  auto timestmap = std::chrono::steady_clock::now().time_since_epoch().count();
+
+  llvm::Expected<UUID> maybe_uuid = UUID::Generate();
+  if (!maybe_uuid) {
+    LLDB_LOG_ERROR(GetLog(LLDBLog::Host), maybe_uuid.takeError(),
+                   "Failed to generate random bytes for UUID: {0}");
+    return llvm::formatv("{0}", timestmap);
   }
 
-  return llvm::formatv(
-      "{0}_{1}", randomString,
-      std::chrono::steady_clock::now().time_since_epoch().count());
+  return llvm::formatv("{0}_{1}", maybe_uuid->GetAsString(), timestmap);
 }
 
 void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const {
diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp
index 370b8b6848c7e..80c829e40b2c9 100644
--- a/lldb/source/Utility/UUID.cpp
+++ b/lldb/source/Utility/UUID.cpp
@@ -11,6 +11,7 @@
 #include "lldb/Utility/Stream.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Format.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 
 #include <cctype>
 #include <cstdio>
@@ -110,3 +111,10 @@ bool UUID::SetFromStringRef(llvm::StringRef str) {
   *this = UUID(bytes);
   return true;
 }
+
+llvm::Expected<UUID> UUID::Generate() {
+  uint8_t random_bytes[16];
+  if (auto ec = llvm::getRandomBytes(random_bytes, 16))
+    return llvm::errorCodeToError(ec);
+  return UUID(random_bytes);
+}
diff --git a/lldb/unittests/Utility/UUIDTest.cpp b/lldb/unittests/Utility/UUIDTest.cpp
index 0852f07a4faa2..66fef4ddc3763 100644
--- a/lldb/unittests/Utility/UUIDTest.cpp
+++ b/lldb/unittests/Utility/UUIDTest.cpp
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "gtest/gtest.h"
-
 #include "lldb/Utility/UUID.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gtest/gtest.h"
 
 using namespace lldb_private;
 
@@ -86,3 +86,7 @@ TEST(UUIDTest, StringConverion) {
   EXPECT_EQ("40414243-4445-4647-4849-4A4B4C4D4E4F-50515253",
             UUID("@ABCDEFGHIJKLMNOPQRS", 20).GetAsString());
 }
+
+TEST(UUIDTest, Generate) {
+  ASSERT_THAT_EXPECTED(UUID::Generate(), llvm::Succeeded());
+}

Hoist UUID generation into the UUID class and add a trivial unit test.
This also changes the telemetry code to drop the double underscore if we
failed to generate a UUID and subsequently logs to the Host instead of
Object log channel.
Copy link
Collaborator

@labath labath left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering how badly do we need this to be "secure". I'm asking because basically the only reason this can fail is if it fails to open /dev/random or something. So, like if we're fine with falling back to a lower entropy source (some c++11 RNG initialized by the timestamp?), then we could make this always return /something/. I don't know if we have other uses for this, but it seems that the telemetry should be fine with that since it just effectively falls back to an empty UUID.

Copy link

github-actions bot commented Apr 2, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@JDevlieghere JDevlieghere merged commit ee60f7c into llvm:main Apr 2, 2025
6 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants