2 // https://code.google.com/p/chromium/issues/detail?id=446692
3 // where asan consumed too much RAM due to transparent hugetables.
5 // RUN: %clangxx_asan -g %s -o %t
6 // RUN: %env_asan_opts=no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s
7 // RUN: %run %t 2>&1 | FileCheck %s
9 // Would be great to run the test with no_huge_pages_for_shadow=0, but
10 // the result will depend on the OS version and settings...
12 // REQUIRES: x86_64-target-arch, shadow-scale-3
14 // WARNING: this test is very subtle and may nto work on some systems.
15 // If this is the case we'll need to futher improve it or disable it.
21 #include <sys/types.h>
26 #include <sanitizer/asan_interface.h>
28 char FileContents
[1 << 16];
30 void FileToString(const char *path
) {
32 int fd
= open(path
, 0);
34 char *p
= FileContents
;
35 ssize_t size
= sizeof(FileContents
) - 1;
38 ssize_t got
= read (fd
, p
, size
);
47 else if (errno
!= EINTR
)
49 } while (size
> 0 && res
< sizeof(FileContents
));
51 FileContents
[res
] = 0;
54 long ReadShadowRss() {
55 const char *path
= "/proc/self/smaps";
57 char *s
= strstr(FileContents
, "2008fff7000-10007fff8000");
60 s
= strstr(s
, "Rss:");
66 const int kAllocSize
= 1 << 28; // 256Mb
67 const int kTwoMb
= 1 << 21;
68 const int kAsanShadowGranularity
= 8;
72 __attribute__((no_sanitize_address
)) void TouchNoAsan(size_t i
) { x
[i
] = 0; }
76 rss
[0] = ReadShadowRss();
77 // use mmap directly to avoid asan touching the shadow.
78 x
= (char *)mmap(0, kAllocSize
, PROT_READ
| PROT_WRITE
,
79 MAP_PRIVATE
| MAP_ANON
, 0, 0);
80 fprintf(stderr
, "X: %p-%p\n", x
, x
+ kAllocSize
);
81 rss
[1] = ReadShadowRss();
83 // Touch the allocated region, but not the shadow.
84 for (size_t i
= 0; i
< kAllocSize
; i
+= kTwoMb
* kAsanShadowGranularity
)
86 rss
[2] = ReadShadowRss();
88 // Touch the shadow just a bit, in 2Mb*Granularity steps.
89 for (size_t i
= 0; i
< kAllocSize
; i
+= kTwoMb
* kAsanShadowGranularity
)
90 __asan_poison_memory_region(x
+ i
, kAsanShadowGranularity
);
91 rss
[3] = ReadShadowRss();
93 // Touch all the shadow.
94 __asan_poison_memory_region(x
, kAllocSize
);
95 rss
[4] = ReadShadowRss();
97 // Print the differences.
98 for (int i
= 0; i
< 4; i
++) {
100 assert(rss
[i
+1] >= rss
[i
]);
101 long diff
= rss
[i
+1] / rss
[i
];
102 fprintf(stderr
, "RSS CHANGE IS %d => %d: %s (%ld vs %ld)\n", i
, i
+ 1,
103 diff
< 10 ? "SMALL" : "LARGE", rss
[i
], rss
[i
+ 1]);
106 // CHECK: RSS CHANGE IS 2 => 3: SMALL
107 // CHECK: RSS CHANGE IS 3 => 4: LARGE