124 lines · c
1// RUN: %clang_scudo %s -o %t2// RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineSizeKb=64" not %run %t unused 2>&13// RUN: %env_scudo_opts="QuarantineSizeMb=1:QuarantineChunksUpToSize=256" not %run %t unused 2>&14// RUN: %env_scudo_opts="QuarantineSizeKb=0:ThreadLocalQuarantineSizeKb=0" %run %t zeroquarantine 2>&15// RUN: %env_scudo_opts=QuarantineSizeKb=64 %run %t smallquarantine 2>&16// RUN: %env_scudo_opts=QuarantineChunksUpToSize=256 %run %t threshold 2>&17// RUN: %env_scudo_opts="QuarantineSizeMb=1" %run %t oldquarantine 2>&18 9// Tests that the quarantine prevents a chunk from being reused right away.10// Also tests that a chunk will eventually become available again for11// allocation when the recycling criteria has been met. Finally, tests the12// threshold up to which a chunk is quarantine, and the old quarantine behavior.13 14#include <assert.h>15#include <malloc.h>16#include <stdlib.h>17#include <string.h>18 19#include <sanitizer/allocator_interface.h>20 21int main(int argc, char **argv) {22 void *p, *old_p;23 size_t allocated_bytes, size = 1U << 8, alignment = 1U << 8;24 25 assert(argc == 2);26 // First, warm up the allocator for the classes used.27 p = malloc(size);28 assert(p);29 free(p);30 p = malloc(size + 1);31 assert(p);32 free(p);33 assert(posix_memalign(&p, alignment, size) == 0);34 assert(p);35 free(p);36 assert(posix_memalign(&p, alignment, size + 1) == 0);37 assert(p);38 free(p);39 40 if (!strcmp(argv[1], "zeroquarantine")) {41 // Verifies that a chunk is deallocated right away when the local and42 // global quarantine sizes are 0.43 allocated_bytes = __sanitizer_get_current_allocated_bytes();44 p = malloc(size);45 assert(p);46 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);47 free(p);48 assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);49 }50 if (!strcmp(argv[1], "smallquarantine")) {51 // The delayed freelist will prevent a chunk from being available right52 // away.53 p = malloc(size);54 assert(p);55 old_p = p;56 free(p);57 p = malloc(size);58 assert(p);59 assert(old_p != p);60 free(p);61 62 // Eventually the chunk should become available again.63 char found = 0;64 for (int i = 0; i < 0x200 && !found; i++) {65 p = malloc(size);66 assert(p);67 found = (p == old_p);68 free(p);69 }70 assert(found);71 }72 if (!strcmp(argv[1], "threshold")) {73 // Verifies that a chunk of size greater than the threshold will be freed74 // right away. Alignment has no impact on the threshold.75 allocated_bytes = __sanitizer_get_current_allocated_bytes();76 p = malloc(size + 1);77 assert(p);78 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);79 free(p);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);83 free(p);84 assert(__sanitizer_get_current_allocated_bytes() == allocated_bytes);85 // Verifies that a chunk of size lower or equal to the threshold will be86 // quarantined.87 p = malloc(size);88 assert(p);89 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);90 free(p);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);95 free(p);96 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);97 }98 if (!strcmp(argv[1], "oldquarantine")) {99 // Verifies that we quarantine everything if the deprecated quarantine100 // option is specified. Alignment has no impact on the threshold.101 allocated_bytes = __sanitizer_get_current_allocated_bytes();102 p = malloc(size);103 assert(p);104 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);105 free(p);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);109 assert(p);110 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);111 free(p);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);116 assert(p);117 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);118 free(p);119 assert(__sanitizer_get_current_allocated_bytes() > allocated_bytes);120 }121 122 return 0;123}124