[compiler-rt] [scudo] Add an option to zero memory on deallocation. (PR #142394)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 07:58:52 PST 2025


================
@@ -1077,6 +1078,87 @@ struct TestQuarantineSizeClassConfig {
   static const scudo::uptr SizeDelta = 0;
 };
 
+#ifdef SCUDO_FUCHSIA
+struct TestZeroOnDeallocConfig {
+  static const bool MaySupportMemoryTagging = false;
+  static const bool EnableZeroOnDealloc = true;
+  static const bool QuarantineDisabled = true;
+
+  template <class A> using TSDRegistryT = scudo::TSDRegistrySharedT<A, 1U, 1U>;
+  struct Primary {
+    // Tiny allocator, its Primary only serves chunks of four sizes.
+    using SizeClassMap =
+        scudo::FixedSizeClassMap<TestQuarantineSizeClassConfig>;
+    static const scudo::uptr RegionSizeLog = DeathRegionSizeLog;
+    static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN;
+    static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX;
+    typedef scudo::uptr CompactPtrT;
+    static const scudo::uptr CompactPtrScale = 0;
+    static const bool EnableRandomOffset = true;
+    static const scudo::uptr MapSizeIncrement = 1UL << 18;
+    static const scudo::uptr GroupSizeLog = 18;
+  };
+
+  template <typename Config>
+  using PrimaryT = scudo::SizeClassAllocator64<Config>;
+
+  struct Secondary {
+    template <typename Config>
+    using CacheT = scudo::MapAllocatorNoCache<Config>;
+  };
+
+  template <typename Config> using SecondaryT = scudo::MapAllocator<Config>;
+};
+
+struct TestNoZeroOnDeallocConfig : public TestZeroOnDeallocConfig {
+  static const bool EnableZeroOnDealloc = false;
+};
+
+TEST(ScudoCombinedTest, ZeroOnDeallocEnabledAndFlag) {
+  ([]() { // Cleanup on exit scope.
+    for (scudo::uptr FlagValue = 128; FlagValue <= 2048; FlagValue *= 2) {
+      // Set the size limit flag via the environment variable.
+      char Options[256];
+      snprintf(Options, sizeof(Options),
+               "SCUDO_OPTIONS=zero_on_dealloc_max_size=%ld",
+               static_cast<long>(FlagValue));
+      putenv(Options);
+
+      // Creates an allocator, configured from the environment.
+      using AllocatorT = TestAllocator<TestZeroOnDeallocConfig>;
+      auto Allocator = std::unique_ptr<AllocatorT>(new AllocatorT());
+
+      for (scudo::uptr AllocatedSize : {FlagValue / 2, FlagValue}) {
+        // Allocates and sets the memory.
+        void *P = Allocator->allocate(AllocatedSize, Origin);
+        ASSERT_NE(P, nullptr);
+        memset(P, 'B', AllocatedSize);
+
+        char *Begin =
+            reinterpret_cast<char *>(Allocator->getBlockBeginTestOnly(P));
+        char *End = reinterpret_cast<char *>(P) + AllocatedSize;
+        // Deallocates and eventually clears the memory.
+        Allocator->deallocate(P, Origin);
+
+        if (End - Begin <= static_cast<long>(FlagValue)) {
+          // Verifies the memory was cleared, including the header.
+          for (char *T = Begin; T < End; ++T) {
+            ASSERT_EQ(*T, 0);
+          }
+        } else {
+          for (scudo::uptr I = 1; I < AllocatedSize; ++I) {
+            // Verifies the memory was left unchanged.
+            ASSERT_EQ(static_cast<char *>(P)[I], 'B');
+          }
----------------
piwicode wrote:

Done. Thanks.

https://github.com/llvm/llvm-project/pull/142394


More information about the llvm-commits mailing list