From: Kostya Serebryany Date: Thu, 29 Jan 2015 02:54:39 +0000 (+0000) Subject: [asan] use getrusage as an alternative to reading /proc/self/statm. Also move GetRSS... X-Git-Tag: llvmorg-3.7.0-rc1~13764 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3c052cc0518896cadb8796af63709e65075bbd19;p=platform%2Fupstream%2Fllvm.git [asan] use getrusage as an alternative to reading /proc/self/statm. Also move GetRSS to sanitizer_linux_libcdep.cc (no change in the function itself) llvm-svn: 227416 --- diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc index cc4232fb..f9c831f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc @@ -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 " diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index 0e776b9..56667e4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -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) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 095ec30..1c0a2f1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -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 diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc b/compiler-rt/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc index 325adaf..225c44e 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc @@ -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 diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc b/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc index a92796d..145cc5d 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc @@ -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