[asan] use getrusage as an alternative to reading /proc/self/statm. Also move GetRSS...
authorKostya Serebryany <kcc@google.com>
Thu, 29 Jan 2015 02:54:39 +0000 (02:54 +0000)
committerKostya Serebryany <kcc@google.com>
Thu, 29 Jan 2015 02:54:39 +0000 (02:54 +0000)
llvm-svn: 227416

compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
compiler-rt/lib/sanitizer_common/sanitizer_linux.cc
compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
compiler-rt/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc

index cc4232f..f9c831f 100644 (file)
@@ -104,6 +104,9 @@ COMMON_FLAG(uptr, soft_rss_limit_mb, 0,
             " until the RSS goes below the soft limit."
             " This limit does not affect memory allocations other than"
             " malloc/new.")
+COMMON_FLAG(bool, can_use_proc_maps_statm, true,
+            "If false, do not attempt to read /proc/maps/statm."
+            " Mostly useful for testing sanitizers.")
 COMMON_FLAG(
     bool, coverage, false,
     "If set, coverage information will be dumped at program shutdown (if the "
index 0e776b9..56667e4 100644 (file)
@@ -422,33 +422,6 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
 }
 #endif
 
-uptr GetRSS() {
-  uptr fd = OpenFile("/proc/self/statm", false);
-  if ((sptr)fd < 0)
-    return 0;
-  char buf[64];
-  uptr len = internal_read(fd, buf, sizeof(buf) - 1);
-  internal_close(fd);
-  if ((sptr)len <= 0)
-    return 0;
-  buf[len] = 0;
-  // The format of the file is:
-  // 1084 89 69 11 0 79 0
-  // We need the second number which is RSS in pages.
-  char *pos = buf;
-  // Skip the first number.
-  while (*pos >= '0' && *pos <= '9')
-    pos++;
-  // Skip whitespaces.
-  while (!(*pos >= '0' && *pos <= '9') && *pos != 0)
-    pos++;
-  // Read the number.
-  uptr rss = 0;
-  while (*pos >= '0' && *pos <= '9')
-    rss = rss * 10 + *pos++ - '0';
-  return rss * GetPageSizeCached();
-}
-
 static void GetArgsAndEnv(char*** argv, char*** envp) {
 #if !SANITIZER_GO
   if (&__libc_stack_end) {
index 095ec30..1c0a2f1 100644 (file)
@@ -422,6 +422,45 @@ void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
 #endif
 }
 
+// getrusage does not give us the current RSS, only the max RSS.
+// Still, this is better than nothing if /proc/self/statm is not available
+// for some reason, e.g. due to a sandbox.
+static uptr GetRSSFromGetrusage() {
+  struct rusage usage;
+  if (getrusage(RUSAGE_SELF, &usage))  // Failed, probably due to a sandbox.
+    return 0;
+  return usage.ru_maxrss << 10;  // ru_maxrss is in Kb.
+}
+
+uptr GetRSS() {
+  if (!common_flags()->can_use_proc_maps_statm)
+    return GetRSSFromGetrusage();
+  uptr fd = OpenFile("/proc/self/statm", false);
+  if ((sptr)fd < 0)
+    return GetRSSFromGetrusage();
+  char buf[64];
+  uptr len = internal_read(fd, buf, sizeof(buf) - 1);
+  internal_close(fd);
+  if ((sptr)len <= 0)
+    return 0;
+  buf[len] = 0;
+  // The format of the file is:
+  // 1084 89 69 11 0 79 0
+  // We need the second number which is RSS in pages.
+  char *pos = buf;
+  // Skip the first number.
+  while (*pos >= '0' && *pos <= '9')
+    pos++;
+  // Skip whitespaces.
+  while (!(*pos >= '0' && *pos <= '9') && *pos != 0)
+    pos++;
+  // Read the number.
+  uptr rss = 0;
+  while (*pos >= '0' && *pos <= '9')
+    rss = rss * 10 + *pos++ - '0';
+  return rss * GetPageSizeCached();
+}
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_FREEBSD || SANITIZER_LINUX
index 325adaf..225c44e 100644 (file)
@@ -2,7 +2,9 @@
 // RUN: %clangxx -O2 %s -o %t
 //
 // Run with limit should fail:
-// RUN: %tool_options=hard_rss_limit_mb=100 not %run %t 2>&1 | FileCheck %s
+// RUN: %tool_options=hard_rss_limit_mb=100                           not %run %t 2>&1 | FileCheck %s
+// This run uses getrusage:
+// RUN: %tool_options=hard_rss_limit_mb=100:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s
 //
 // Run w/o limit or with a large enough limit should pass:
 // RUN: %tool_options=hard_rss_limit_mb=1000 %run %t
index a92796d..145cc5d 100644 (file)
@@ -5,6 +5,10 @@
 // RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=1     %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_1
 // RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
 
+// This run uses getrusage. We can only test getrusage when allocator_may_return_null=0
+// because getrusage gives us max-rss, not current-rss.
+// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+
 // FIXME: make it work for other sanitizers.
 // XFAIL: lsan
 // XFAIL: tsan