@@ -80,6 +80,19 @@ struct TestNoCacheConfig {
8080 };
8181};
8282
83+ struct TestNoCacheNoGuardPageConfig {
84+ static const bool MaySupportMemoryTagging = false ;
85+ template <typename > using TSDRegistryT = void ;
86+ template <typename > using PrimaryT = void ;
87+ template <typename Config> using SecondaryT = scudo::MapAllocator<Config>;
88+
89+ struct Secondary {
90+ template <typename Config>
91+ using CacheT = scudo::MapAllocatorNoCache<Config>;
92+ static const bool EnableGuardPages = false ;
93+ };
94+ };
95+
8396struct TestCacheConfig {
8497 static const bool MaySupportMemoryTagging = false ;
8598 template <typename > using TSDRegistryT = void ;
@@ -100,6 +113,27 @@ struct TestCacheConfig {
100113 };
101114};
102115
116+ struct TestCacheNoGuardPageConfig {
117+ static const bool MaySupportMemoryTagging = false ;
118+ template <typename > using TSDRegistryT = void ;
119+ template <typename > using PrimaryT = void ;
120+ template <typename > using SecondaryT = void ;
121+
122+ struct Secondary {
123+ struct Cache {
124+ static const scudo::u32 EntriesArraySize = 128U ;
125+ static const scudo::u32 QuarantineSize = 0U ;
126+ static const scudo::u32 DefaultMaxEntriesCount = 64U ;
127+ static const scudo::uptr DefaultMaxEntrySize = 1UL << 20 ;
128+ static const scudo::s32 MinReleaseToOsIntervalMs = INT32_MIN;
129+ static const scudo::s32 MaxReleaseToOsIntervalMs = INT32_MAX;
130+ };
131+
132+ template <typename Config> using CacheT = scudo::MapAllocatorCache<Config>;
133+ static const bool EnableGuardPages = false ;
134+ };
135+ };
136+
103137template <typename Config> static void testBasic () {
104138 using SecondaryT = scudo::MapAllocator<scudo::SecondaryConfig<Config>>;
105139 AllocatorInfoType<Config> Info;
@@ -146,15 +180,17 @@ template <typename Config> static void testBasic() {
146180
147181TEST (ScudoSecondaryTest, Basic) {
148182 testBasic<TestNoCacheConfig>();
183+ testBasic<TestNoCacheNoGuardPageConfig>();
149184 testBasic<TestCacheConfig>();
185+ testBasic<TestCacheNoGuardPageConfig>();
150186 testBasic<scudo::DefaultConfig>();
151187}
152188
153189// This exercises a variety of combinations of size and alignment for the
154190// MapAllocator. The size computation done here mimic the ones done by the
155191// combined allocator.
156- TEST (ScudoSecondaryTest, AllocatorCombinations ) {
157- AllocatorInfoType<TestNoCacheConfig > Info;
192+ template < typename Config> void testAllocatorCombinations ( ) {
193+ AllocatorInfoType<Config > Info;
158194
159195 constexpr scudo::uptr MinAlign = FIRST_32_SECOND_64 (8 , 16 );
160196 constexpr scudo::uptr HeaderSize = scudo::roundUp (8 , MinAlign);
@@ -180,8 +216,13 @@ TEST(ScudoSecondaryTest, AllocatorCombinations) {
180216 }
181217}
182218
183- TEST (ScudoSecondaryTest, AllocatorIterate) {
184- AllocatorInfoType<TestNoCacheConfig> Info;
219+ TEST (ScudoSecondaryTest, AllocatorCombinations) {
220+ testAllocatorCombinations<TestNoCacheConfig>();
221+ testAllocatorCombinations<TestNoCacheNoGuardPageConfig>();
222+ }
223+
224+ template <typename Config> void testAllocatorIterate () {
225+ AllocatorInfoType<Config> Info;
185226
186227 std::vector<void *> V;
187228 for (scudo::uptr I = 0 ; I < 32U ; I++)
@@ -201,8 +242,13 @@ TEST(ScudoSecondaryTest, AllocatorIterate) {
201242 }
202243}
203244
204- TEST (ScudoSecondaryTest, AllocatorWithReleaseThreadsRace) {
205- AllocatorInfoType<TestNoCacheConfig> Info (/* ReleaseToOsInterval=*/ 0 );
245+ TEST (ScudoSecondaryTest, AllocatorIterate) {
246+ testAllocatorIterate<TestNoCacheConfig>();
247+ testAllocatorIterate<TestNoCacheNoGuardPageConfig>();
248+ }
249+
250+ template <typename Config> void testAllocatorWithReleaseThreadsRace () {
251+ AllocatorInfoType<Config> Info (/* ReleaseToOsInterval=*/ 0 );
206252
207253 std::mutex Mutex;
208254 std::condition_variable Cv;
@@ -243,6 +289,54 @@ TEST(ScudoSecondaryTest, AllocatorWithReleaseThreadsRace) {
243289 T.join ();
244290}
245291
292+ TEST (ScudoSecondaryTest, AllocatorWithReleaseThreadsRace) {
293+ testAllocatorWithReleaseThreadsRace<TestNoCacheConfig>();
294+ testAllocatorWithReleaseThreadsRace<TestNoCacheNoGuardPageConfig>();
295+ }
296+
297+ template <typename Config>
298+ void testGetMappedSize (scudo::uptr Size, scudo::uptr *mapped,
299+ scudo::uptr *guard_page_size) {
300+ AllocatorInfoType<Config> Info;
301+
302+ scudo::uptr Stats[scudo::StatCount] = {};
303+ Info.GlobalStats .get (Stats);
304+ *mapped = Stats[scudo::StatMapped];
305+ Stats[scudo::StatMapped] = 0 ;
306+
307+ void *Ptr = Info.Allocator ->allocate (Info.Options , Size);
308+ EXPECT_NE (Ptr, nullptr );
309+
310+ Info.GlobalStats .get (Stats);
311+ EXPECT_GE (Stats[scudo::StatMapped], *mapped);
312+ *mapped = Stats[scudo::StatMapped] - *mapped;
313+
314+ Info.Allocator ->deallocate (Info.Options , Ptr);
315+
316+ *guard_page_size = Info.Allocator ->getGuardPageSize ();
317+ }
318+
319+ TEST (ScudoSecondaryTest, VerifyGuardPageOption) {
320+ static scudo::uptr AllocSize = 1000 * PageSize;
321+
322+ scudo::uptr guard_mapped = 0 ;
323+ scudo::uptr guard_page_size = 0 ;
324+ testGetMappedSize<TestNoCacheConfig>(AllocSize, &guard_mapped,
325+ &guard_page_size);
326+ EXPECT_GT (guard_page_size, 0U );
327+ EXPECT_GE (guard_mapped, AllocSize + 2 * guard_page_size);
328+
329+ scudo::uptr no_guard_mapped = 0 ;
330+ scudo::uptr no_guard_page_size = 0 ;
331+ testGetMappedSize<TestNoCacheNoGuardPageConfig>(AllocSize, &no_guard_mapped,
332+ &no_guard_page_size);
333+ EXPECT_EQ (no_guard_page_size, 0U );
334+ EXPECT_GE (no_guard_mapped, AllocSize);
335+
336+ EXPECT_GE (guard_mapped, no_guard_mapped);
337+ EXPECT_GE (guard_mapped, no_guard_mapped + guard_page_size * 2 );
338+ }
339+
246340// Value written to cache entries that are unmapped.
247341static scudo::u32 UnmappedMarker = 0xDEADBEEF ;
248342
0 commit comments