[compiler-rt] r206178 - [asan] added internal flag mmap_limit_mb

Kostya Serebryany kcc at google.com
Mon Apr 14 07:51:01 PDT 2014


Author: kcc
Date: Mon Apr 14 09:51:01 2014
New Revision: 206178

URL: http://llvm.org/viewvc/llvm-project?rev=206178&view=rev
Log:
[asan] added internal flag mmap_limit_mb

Added:
    compiler-rt/trunk/test/asan/TestCases/mmap_limit_mb.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Apr 14 09:51:01 2014
@@ -328,6 +328,7 @@ static void ReserveShadowMemoryRange(upt
   CHECK_EQ((beg % GetPageSizeCached()), 0);
   CHECK_EQ(((end + 1) % GetPageSizeCached()), 0);
   uptr size = end - beg + 1;
+  DecreaseTotalMmap(size);  // Don't count the shadow against mmap_limit_mb.
   void *res = MmapFixedNoReserve(beg, size);
   if (res != (void*)beg) {
     Report("ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Mon Apr 14 09:51:01 2014
@@ -244,6 +244,24 @@ char *StripModuleName(const char *module
   return internal_strdup(short_module_name);
 }
 
+static atomic_uintptr_t g_total_mmaped;
+
+void IncreaseTotalMmap(uptr size) {
+  if (!common_flags()->mmap_limit_mb) return;
+  uptr total_mmaped =
+      atomic_fetch_add(&g_total_mmaped, size, memory_order_relaxed) + size;
+  if ((total_mmaped >> 20) > common_flags()->mmap_limit_mb) {
+    // Since for now mmap_limit_mb is not a user-facing flag, just CHECK.
+    common_flags()->mmap_limit_mb = 0;  // Allow mmap in CHECK.
+    CHECK_LT(total_mmaped >> 20, common_flags()->mmap_limit_mb);
+  }
+}
+
+void DecreaseTotalMmap(uptr size) {
+  if (!common_flags()->mmap_limit_mb) return;
+  atomic_fetch_sub(&g_total_mmaped, size, memory_order_relaxed);
+}
+
 }  // namespace __sanitizer
 
 using namespace __sanitizer;  // NOLINT

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Mon Apr 14 09:51:01 2014
@@ -60,6 +60,8 @@ void *MmapAlignedOrDie(uptr size, uptr a
 // Used to check if we can map shadow memory to a fixed location.
 bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
 void FlushUnneededShadowMemory(uptr addr, uptr size);
+void IncreaseTotalMmap(uptr size);
+void DecreaseTotalMmap(uptr size);
 
 // InternalScopedBuffer can be used instead of large stack arrays to
 // keep frame size low.

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Mon Apr 14 09:51:01 2014
@@ -119,6 +119,9 @@ void ParseCommonFlagsFromString(CommonFl
   ParseFlag(str, &f->intercept_tls_get_addr, "intercept_tls_get_addr",
             "Intercept __tls_get_addr.");
   ParseFlag(str, &f->help, "help", "Print the flag descriptions.");
+  ParseFlag(str, &f->mmap_limit_mb, "mmap_limit_mb",
+            "Limit the amount of mmap-ed memory (excluding shadow) in Mb; "
+            "not a user-facing flag, used mosly for testing the tools");
 
   // Do a sanity check for certain flags.
   if (f->malloc_context_size < 1)

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Mon Apr 14 09:51:01 2014
@@ -52,6 +52,7 @@ struct CommonFlags {
   bool legacy_pthread_cond;
   bool intercept_tls_get_addr;
   bool help;
+  uptr mmap_limit_mb;
 };
 
 inline CommonFlags *common_flags() {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=206178&r1=206177&r2=206178&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Mon Apr 14 09:51:01 2014
@@ -91,6 +91,7 @@ void *MmapOrDie(uptr size, const char *m
     DumpProcessMap();
     CHECK("unable to mmap" && 0);
   }
+  IncreaseTotalMmap(size);
   return (void *)res;
 }
 
@@ -102,6 +103,7 @@ void UnmapOrDie(void *addr, uptr size) {
            SanitizerToolName, size, size, addr);
     CHECK("unable to unmap" && 0);
   }
+  DecreaseTotalMmap(size);
 }
 
 void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
@@ -118,6 +120,7 @@ void *MmapNoReserveOrDie(uptr size, cons
            SanitizerToolName, size, size, mem_type, reserrno);
     CHECK("unable to mmap" && 0);
   }
+  IncreaseTotalMmap(size);
   return (void *)p;
 }
 
@@ -133,6 +136,7 @@ void *MmapFixedNoReserve(uptr fixed_addr
     Report("ERROR: %s failed to "
            "allocate 0x%zx (%zd) bytes at address %zu (errno: %d)\n",
            SanitizerToolName, size, size, fixed_addr, reserrno);
+  IncreaseTotalMmap(size);
   return (void *)p;
 }
 
@@ -150,6 +154,7 @@ void *MmapFixedOrDie(uptr fixed_addr, up
            SanitizerToolName, size, size, fixed_addr, reserrno);
     CHECK("unable to mmap" && 0);
   }
+  IncreaseTotalMmap(size);
   return (void *)p;
 }
 

Added: compiler-rt/trunk/test/asan/TestCases/mmap_limit_mb.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/mmap_limit_mb.cc?rev=206178&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/mmap_limit_mb.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/mmap_limit_mb.cc Mon Apr 14 09:51:01 2014
@@ -0,0 +1,30 @@
+// Test the mmap_limit_mb flag.
+//
+// RUN: %clangxx_asan -std=c++11 -O2 %s -o %t
+// RUN: %t 100 16
+// RUN: %t 100 1000000
+// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 16
+// RUN: ASAN_OPTIONS=mmap_limit_mb=500 %t 100 1000000
+// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 16 2>&1 | FileCheck %s
+// RUN: ASAN_OPTIONS=mmap_limit_mb=500 not %t 500 1000000 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <algorithm>
+#include <vector>
+
+int main(int argc, char **argv) {
+  assert(argc == 3);
+  long total_mb = atoi(argv[1]);
+  long allocation_size = atoi(argv[2]);
+  std::vector<char *> v;
+  for (long total = total_mb << 20; total > 0; total -= allocation_size)
+    v.push_back(new char[allocation_size]);
+  std::for_each(v.begin(), v.end(),
+                [](std::vector<char *>::reference ref) { delete[] ref; });
+  printf("PASS\n");
+  // CHECK: AddressSanitizer CHECK failed{{.*}}total_mmaped{{.*}}mmap_limit_mb
+  return 0;
+}





More information about the llvm-commits mailing list