https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/133662
>From f0a4b9bc2f20a812f7f37e5f5a2417dbbb4d45e0 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Sun, 30 Mar 2025 16:10:05 -0700 Subject: [PATCH 1/5] [lldb] Hoist UUID generation into the UUID class 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. --- lldb/include/lldb/Utility/UUID.h | 28 ++++++++++++++++------------ lldb/source/Core/Telemetry.cpp | 21 +++++++++++---------- lldb/source/Utility/UUID.cpp | 9 +++++++++ lldb/unittests/Utility/UUIDTest.cpp | 14 ++++++++++++-- 4 files changed, 48 insertions(+), 24 deletions(-) diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h index bc4b4acd5a7d8..05731ea4dc090 100644 --- a/lldb/include/lldb/Utility/UUID.h +++ b/lldb/include/lldb/Utility/UUID.h @@ -12,26 +12,28 @@ #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> +#include <sys/_types/_u_int32_t.h> namespace lldb_private { - class Stream; +class Stream; +/// Represents UUID's of various sizes. In all cases, a uuid of all zeros is +/// treated as an "Invalid UUID" marker, and the UUID created from such data +/// will return false for IsValid. class UUID { - // Represents UUID's of various sizes. In all cases, a uuid of all zeros is - // treated as an "Invalid UUID" marker, and the UUID created from such data - // will return false for IsValid. public: UUID() = default; - - /// Creates a uuid from the data pointed to by the bytes argument. + + /// Create 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; })) { Clear(); - } + } } // Reference: @@ -50,13 +52,12 @@ class UUID { /// Create a UUID from CvRecordPdb70. UUID(CvRecordPdb70 debug_info); - /// Creates a UUID from the data pointed to by the bytes argument. + /// Create 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 +68,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 +89,9 @@ class UUID { DecodeUUIDBytesFromString(llvm::StringRef str, llvm::SmallVectorImpl<uint8_t> &uuid_bytes); + /// Create a random UUID. + static llvm::Expected<UUID> Generate(uint32_t num_bytes = 16); + 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..b5753d955db10 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -11,8 +11,10 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Format.h" +#include "llvm/Support/RandomNumberGenerator.h" #include <cctype> +#include <cstdint> #include <cstdio> #include <cstring> @@ -110,3 +112,10 @@ bool UUID::SetFromStringRef(llvm::StringRef str) { *this = UUID(bytes); return true; } + +llvm::Expected<UUID> UUID::Generate(uint32_t num_bytes) { + llvm::SmallVector<uint8_t, 20> bytes(num_bytes); + if (auto ec = llvm::getRandomBytes(bytes.data(), bytes.size())) + return llvm::errorCodeToError(ec); + return UUID(bytes); +} diff --git a/lldb/unittests/Utility/UUIDTest.cpp b/lldb/unittests/Utility/UUIDTest.cpp index 0852f07a4faa2..32a7d7f3f5ad0 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,13 @@ TEST(UUIDTest, StringConverion) { EXPECT_EQ("40414243-4445-4647-4849-4A4B4C4D4E4F-50515253", UUID("@ABCDEFGHIJKLMNOPQRS", 20).GetAsString()); } + +TEST(UUIDTest, Generate) { + llvm::Expected<UUID> u16 = UUID::Generate(); + ASSERT_THAT_EXPECTED(u16, llvm::Succeeded()); + EXPECT_EQ(u16->GetBytes().size(), 16UL); + + llvm::Expected<UUID> u20 = UUID::Generate(20); + ASSERT_THAT_EXPECTED(u20, llvm::Succeeded()); + EXPECT_EQ(u20->GetBytes().size(), 20UL); +} >From 12e246cc5008d630bdea2dd91d5f9bc03d2d0713 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Mon, 31 Mar 2025 07:56:05 -0700 Subject: [PATCH 2/5] Fall back to C++ RNG --- lldb/include/lldb/Utility/UUID.h | 3 +-- lldb/source/Core/Telemetry.cpp | 11 ++--------- lldb/source/Utility/UUID.cpp | 15 ++++++++++++--- lldb/unittests/Utility/UUIDTest.cpp | 10 ++++------ 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h index 05731ea4dc090..b0356dbf4c144 100644 --- a/lldb/include/lldb/Utility/UUID.h +++ b/lldb/include/lldb/Utility/UUID.h @@ -16,7 +16,6 @@ #include <cstddef> #include <cstdint> #include <string> -#include <sys/_types/_u_int32_t.h> namespace lldb_private { @@ -90,7 +89,7 @@ class UUID { llvm::SmallVectorImpl<uint8_t> &uuid_bytes); /// Create a random UUID. - static llvm::Expected<UUID> Generate(uint32_t num_bytes = 16); + static UUID Generate(uint32_t num_bytes = 16); private: // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index e9ba7d1845bb4..8db29889e0846 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -41,15 +41,8 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) { // user runs the two copies of binary at the same time. static std::string MakeUUID() { 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}", maybe_uuid->GetAsString(), timestmap); + UUID uuid = UUID::Generate(); + return llvm::formatv("{0}_{1}", uuid.GetAsString(), timestmap); } void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index b5753d955db10..121dc9677bc39 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -17,6 +17,7 @@ #include <cstdint> #include <cstdio> #include <cstring> +#include <random> using namespace lldb_private; @@ -113,9 +114,17 @@ bool UUID::SetFromStringRef(llvm::StringRef str) { return true; } -llvm::Expected<UUID> UUID::Generate(uint32_t num_bytes) { +UUID UUID::Generate(uint32_t num_bytes) { llvm::SmallVector<uint8_t, 20> bytes(num_bytes); - if (auto ec = llvm::getRandomBytes(bytes.data(), bytes.size())) - return llvm::errorCodeToError(ec); + auto ec = llvm::getRandomBytes(bytes.data(), bytes.size()); + + // If getRandomBytes failed, fall back to a lower entropy source. + if (ec) { + auto seed = std::chrono::steady_clock::now().time_since_epoch().count(); + std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t> + engine(seed); + std::generate(bytes.begin(), bytes.end(), std::ref(engine)); + } + return UUID(bytes); } diff --git a/lldb/unittests/Utility/UUIDTest.cpp b/lldb/unittests/Utility/UUIDTest.cpp index 32a7d7f3f5ad0..ad0228c6bba69 100644 --- a/lldb/unittests/Utility/UUIDTest.cpp +++ b/lldb/unittests/Utility/UUIDTest.cpp @@ -88,11 +88,9 @@ TEST(UUIDTest, StringConverion) { } TEST(UUIDTest, Generate) { - llvm::Expected<UUID> u16 = UUID::Generate(); - ASSERT_THAT_EXPECTED(u16, llvm::Succeeded()); - EXPECT_EQ(u16->GetBytes().size(), 16UL); + UUID u16 = UUID::Generate(); + EXPECT_EQ(u16.GetBytes().size(), 16UL); - llvm::Expected<UUID> u20 = UUID::Generate(20); - ASSERT_THAT_EXPECTED(u20, llvm::Succeeded()); - EXPECT_EQ(u20->GetBytes().size(), 20UL); + UUID u20 = UUID::Generate(20); + EXPECT_EQ(u20.GetBytes().size(), 20UL); } >From 6585814884379cde5f44220addcc0d8aeb31cacf Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 1 Apr 2025 10:49:36 -0700 Subject: [PATCH 3/5] Include <chrono> --- lldb/source/Utility/UUID.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index 121dc9677bc39..4dfae1051cda0 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/RandomNumberGenerator.h" #include <cctype> +#include <chrono> #include <cstdint> #include <cstdio> #include <cstring> >From 6163ca277c66be3bb696cbde5eef8bbe10b34929 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Tue, 1 Apr 2025 21:40:10 -0700 Subject: [PATCH 4/5] Include climits for CHAR_BIT --- lldb/source/Utility/UUID.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index 4dfae1051cda0..4d196271666b3 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -18,6 +18,7 @@ #include <cstdint> #include <cstdio> #include <cstring> +#include <climits> #include <random> using namespace lldb_private; >From 893c2f335c447652a9d05912ffd4d4192bcd2769 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <jo...@devlieghere.com> Date: Wed, 2 Apr 2025 08:43:23 -0700 Subject: [PATCH 5/5] Formatting --- lldb/source/Utility/UUID.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index 4d196271666b3..0af0c3837627f 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -15,10 +15,10 @@ #include <cctype> #include <chrono> +#include <climits> #include <cstdint> #include <cstdio> #include <cstring> -#include <climits> #include <random> using namespace lldb_private; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits