[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