[compiler-rt] [scudo] Add primary option to zero block on dealloc. (PR #142394)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 3 21:57:52 PDT 2025
================
@@ -296,6 +319,54 @@ TEST(ScudoPrimaryTest, Primary64OOM) {
Allocator.unmapTestOnly();
}
+TEST(ScudoPrimaryTest, ZeroOnDeallocFlagLimit) {
+ for (scudo::s32 flag_value :
+ {INT_MAX, INT_MAX - 1, 1 << 12, 1 << 10,
+ static_cast<scudo::s32>(
+ scudo::DefaultSizeClassMap::getSizeByClassId(6)),
+ static_cast<scudo::s32>(
+ scudo::DefaultSizeClassMap::getSizeByClassId(6) - 1)}) {
+ // Override the flag value.
+ scudo::getFlags()->zero_on_dealloc_max_size = flag_value;
+ // INT_MAX flag_value stands for unset, then the static parameter is used.
+ const scudo::uptr threshold =
+ flag_value == INT_MAX ? TestConfig6<scudo::DefaultSizeClassMap>::
+ Primary::DefaultZeroOnDeallocMaxSize
+ : static_cast<scudo::uptr>(flag_value);
+
+ using Primary = TestAllocator<TestConfig6, scudo::DefaultSizeClassMap>;
+ Primary Allocator;
+ Allocator.init(/*ReleaseToOsInterval=*/-1);
+ typename Primary::SizeClassAllocatorT SizeClassAllocator;
+ scudo::GlobalStats Stats;
+ Stats.init();
+ SizeClassAllocator.init(&Stats, &Allocator);
+ for (scudo::uptr ClassId = 1;
+ ClassId < Primary::SizeClassMap::LargestClassId; ClassId++) {
+ void *Ptr = SizeClassAllocator.allocate(ClassId);
+ EXPECT_NE(Ptr, nullptr);
+ const scudo::uptr Size = Primary::getSizeByClassId(ClassId);
+ memset(Ptr, 'B', Size);
+
+ SizeClassAllocator.deallocate(ClassId, Ptr);
+ if (Size <= threshold) {
+ // Verify the block is full of zeros.
+ for (scudo::uptr I = 1; I < Size; ++I) {
+ ASSERT_TRUE(static_cast<char *>(Ptr)[I] == 0);
+ }
+ } else {
+ // Verify the block is full of data.
+ for (scudo::uptr I = 1; I < Size; ++I) {
+ ASSERT_TRUE(static_cast<char *>(Ptr)[I] != 0);
+ }
+ }
+ }
----------------
ChiaHungDuan wrote:
It accesses the memory after deallocation which makes me feel wrong. Currently, the simplest way in my mind is to have something like `verifyAllBlocksAreReleasedTestOnly` in primary allocator. Such as `verifyAllBlocksAreZeroedTestOnly` (and we have to implement it in both primary and secondary allocators.)
Or the alternative is to add a hook in `pushBlocks` (in primary) and `deallocate` (in secondary) to do something like
```
void pushBlocks(...) {
if (verifyOnTestOnly) {
if (EnableZeroOnDealloc) {
...
}
}
```
https://github.com/llvm/llvm-project/pull/142394
More information about the llvm-commits
mailing list