brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.0 KiB · 0fd7c55 Raw
108 lines · cpp
1// Regression test for2// https://code.google.com/p/chromium/issues/detail?id=4466923// where asan consumed too much RAM due to transparent hugetables.4//5// RUN: %clangxx_asan -g %s -o %t6// RUN: %env_asan_opts=no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s7// RUN: %run %t 2>&1 | FileCheck %s8//9// Would be great to run the test with no_huge_pages_for_shadow=0, but10// the result will depend on the OS version and settings...11//12// REQUIRES: x86_64-target-arch, shadow-scale-313//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.16#include <assert.h>17#include <stdio.h>18#include <stdlib.h>19#include <string.h>20#include <sys/mman.h>21#include <sys/types.h>22#include <sys/stat.h>23#include <fcntl.h>24#include <unistd.h>25#include <errno.h>26#include <sanitizer/asan_interface.h>27 28char FileContents[1 << 16];29 30void FileToString(const char *path) {31  FileContents[0] = 0;32  int fd = open(path, 0);33  if (fd < 0) return;34  char *p = FileContents;35  ssize_t size = sizeof(FileContents) - 1;36  ssize_t res = 0;37  do {38    ssize_t got = read (fd, p, size);39    if (got == 0)40      break;41    else if (got > 0)42      {43        p += got;44        res += got;45        size -= got;46      }47    else if (errno != EINTR)48      break;49  } while (size > 0 && res < sizeof(FileContents));50  if (res >= 0)51    FileContents[res] = 0;52}53 54long ReadShadowRss() {55  const char *path = "/proc/self/smaps";56  FileToString(path);57  char *s = strstr(FileContents, "2008fff7000-10007fff8000");58  if (!s) return 0;59 60  s = strstr(s, "Rss:");61  if (!s) return 0;62  s = s + 4;63  return atol(s);64}65 66const int kAllocSize = 1 << 28;  // 256Mb67const int kTwoMb = 1 << 21;68const int kAsanShadowGranularity = 8;69 70char *x;71 72__attribute__((no_sanitize_address)) void TouchNoAsan(size_t i) { x[i] = 0; }73 74int main() {75  long rss[5];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();82 83  // Touch the allocated region, but not the shadow.84  for (size_t i = 0; i < kAllocSize; i += kTwoMb * kAsanShadowGranularity)85    TouchNoAsan(i);86  rss[2] = ReadShadowRss();87 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();92 93  // Touch all the shadow.94  __asan_poison_memory_region(x, kAllocSize);95  rss[4] = ReadShadowRss();96 97  // Print the differences.98  for (int i = 0; i < 4; i++) {99    assert(rss[i] > 0);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]);104  }105}106// CHECK: RSS CHANGE IS 2 => 3: SMALL107// CHECK: RSS CHANGE IS 3 => 4: LARGE108