1 // RUN: %clang_scudo %s -o %t
2 // RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineSizeKb=64" not %run %t unused 2>&1
3 // RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineChunksUpToSize=256" not %run %t unused 2>&1
4 // RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0" %run %t zeroquarantine 2>&1
5 // RUN: %env_scudo_opts=QuarantineSizeKb=64 %run %t smallquarantine 2>&1
6 // RUN: %env_scudo_opts=QuarantineChunksUpToSize=256 %run %t threshold 2>&1
7 // RUN: %env_scudo_opts="QuarantineSizeMb=1" %run %t oldquarantine 2>&1
9 // Tests that the quarantine prevents a chunk from being reused right away.
10 // Also tests that a chunk will eventually become available again for
11 // allocation when the recycling criteria has been met. Finally, tests the
12 // threshold up to which a chunk is quarantine, and the old quarantine behavior.
19 #include <sanitizer/allocator_interface.h>
21 int main(int argc
, char **argv
) {
23 size_t allocated_bytes
, size
= 1U << 8, alignment
= 1U << 8;
26 // First, warm up the allocator for the classes used.
33 assert(posix_memalign(&p
, alignment
, size
) == 0);
36 assert(posix_memalign(&p
, alignment
, size
+ 1) == 0);
40 if (!strcmp(argv
[1], "zeroquarantine")) {
41 // Verifies that a chunk is deallocated right away when the local and
42 // global quarantine sizes are 0.
43 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
46 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
48 assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes
);
50 if (!strcmp(argv
[1], "smallquarantine")) {
51 // The delayed freelist will prevent a chunk from being available right
62 // Eventually the chunk should become available again.
64 for (int i
= 0; i
< 0x200 && !found
; i
++) {
72 if (!strcmp(argv
[1], "threshold")) {
73 // Verifies that a chunk of size greater than the threshold will be freed
74 // right away. Alignment has no impact on the threshold.
75 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
78 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
80 assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes
);
81 assert(posix_memalign(&p
, alignment
, size
+ 1) == 0);
82 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
84 assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes
);
85 // Verifies that a chunk of size lower or equal to the threshold will be
89 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
91 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
92 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
93 assert(posix_memalign(&p
, alignment
, size
) == 0);
94 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
96 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
98 if (!strcmp(argv
[1], "oldquarantine")) {
99 // Verifies that we quarantine everything if the deprecated quarantine
100 // option is specified. Alignment has no impact on the threshold.
101 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
104 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
106 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
107 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
108 assert(posix_memalign(&p
, alignment
, size
) == 0);
110 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
112 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
113 // Secondary backed allocation.
114 allocated_bytes
= __sanitizer_get_current_allocated_bytes();
115 p
= malloc(1U << 19);
117 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);
119 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes
);