1// Tests ASAN_OPTIONS=allocator_release_to_os=1
2
3// RUN: %clangxx_asan -std=c++11 %s -o %t
4// RUN: %env_asan_opts=allocator_release_to_os_interval_ms=0 %run %t 2>&1 | FileCheck %s --check-prefix=RELEASE
5// RUN: %env_asan_opts=allocator_release_to_os_interval_ms=-1 %run %t 2>&1 | FileCheck %s --check-prefix=NO_RELEASE
6// RUN: %env_asan_opts=allocator_release_to_os_interval_ms=-1 %run %t force 2>&1 | FileCheck %s --check-prefix=FORCE_RELEASE
7
8// REQUIRES: x86_64-target-arch
9// REQUIRES: page-size-4096
10
11#include <algorithm>
12#include <assert.h>
13#include <random>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#include <sanitizer/allocator_interface.h>
20#include <sanitizer/asan_interface.h>
21
22void MallocReleaseStress() {
23 const size_t kNumChunks = 10000;
24 const size_t kAllocSize = 100;
25 const size_t kNumIter = 100;
26 uintptr_t *chunks[kNumChunks] = {0};
27 std::mt19937 r;
28
29 for (size_t iter = 0; iter < kNumIter; iter++) {
30 std::shuffle(first: chunks, last: chunks + kNumChunks, g&: r);
31 size_t to_replace = rand() % kNumChunks;
32 for (size_t i = 0; i < kNumChunks; i++) {
33 if (chunks[i])
34 assert(chunks[i][0] == (uintptr_t)chunks[i]);
35 if (i < to_replace) {
36 delete [] chunks[i];
37 chunks[i] = new uintptr_t[kAllocSize];
38 chunks[i][0] = (uintptr_t)chunks[i];
39 }
40 }
41 }
42 for (auto p : chunks)
43 delete[] p;
44}
45
46int main(int argc, char **argv) {
47 MallocReleaseStress();
48 if (argc > 1 && !strcmp(s1: "force", s2: argv[1]))
49 __sanitizer_purge_allocator();
50 __asan_print_accumulated_stats();
51}
52
53// RELEASE: mapped:{{.*}}releases: {{[1-9]}}
54// NO_RELEASE: mapped:{{.*}}releases: 0
55// FORCE_RELEASE: mapped:{{.*}}releases: {{[1-9]}}
56

source code of compiler-rt/test/asan/TestCases/Linux/release_to_os_test.cpp