[compiler-rt] r224353 - [asan] new flag: hard_rss_limit_mb
Alexey Samsonov
vonosmas at gmail.com
Thu Dec 18 11:06:26 PST 2014
On Tue, Dec 16, 2014 at 11:13 AM, Kostya Serebryany <kcc at google.com> wrote:
>
> Author: kcc
> Date: Tue Dec 16 13:13:01 2014
> New Revision: 224353
>
> URL: http://llvm.org/viewvc/llvm-project?rev=224353&view=rev
> Log:
> [asan] new flag: hard_rss_limit_mb
>
> Added:
>
> compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
> Modified:
> compiler-rt/trunk/lib/asan/asan_interceptors.cc
> compiler-rt/trunk/lib/asan/asan_rtl.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
> 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_libc.h
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
> compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
> compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
>
> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Dec 16 13:13:01
> 2014
> @@ -236,6 +236,11 @@ INTERCEPTOR(int, pthread_create, void *t
> }
> return result;
> }
> +
> +INTERCEPTOR(int, pthread_join, void *t, void **arg) {
> + return real_pthread_join(t, arg);
> +}
> +DEFINE_REAL_PTHREAD_FUNCTIONS;
> #endif // ASAN_INTERCEPT_PTHREAD_CREATE
>
> #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
> @@ -902,6 +907,7 @@ void InitializeAsanInterceptors() {
> // Intercept threading-related functions
> #if ASAN_INTERCEPT_PTHREAD_CREATE
> ASAN_INTERCEPT_FUNC(pthread_create);
> + ASAN_INTERCEPT_FUNC(pthread_join);
> #endif
>
> // Intercept atexit function.
>
> 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=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_rtl.cc Tue Dec 16 13:13:01 2014
> @@ -658,6 +658,8 @@ static void AsanInitInternal() {
> InitializeAllocator(common_flags()->allocator_may_return_null,
> flags()->quarantine_size);
>
> + MaybeStartBackgroudThread();
> +
> // On Linux AsanThread::ThreadStart() calls malloc() that's why
> asan_inited
> // should be set to 1 prior to initializing the threads.
> asan_inited = 1;
>
> 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=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Tue Dec 16
> 13:13:01 2014
> @@ -557,6 +557,10 @@ INLINE void GetExtraActivationFlags(char
> INLINE void SanitizerInitializeUnwinder() {}
> #endif
>
> +void *internal_start_thread(void(*func)(void*), void *arg);
> +void internal_join_thread(void *th);
> +void MaybeStartBackgroudThread();
> +
> // Make the compiler think that something is going on there.
> // Use this inside a loop that looks like memset/memcpy/etc to prevent the
> // compiler from recognising it and turning it into an actual call to
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_libcdep.cc Tue
> Dec 16 13:13:01 2014
> @@ -13,6 +13,7 @@
>
> #include "sanitizer_common.h"
> #include "sanitizer_flags.h"
> +#include "sanitizer_stackdepot.h"
> #include "sanitizer_stacktrace.h"
> #include "sanitizer_symbolizer.h"
>
> @@ -59,6 +60,48 @@ void ReportErrorSummary(const char *erro
> #endif
> }
>
> +void BackgroundThread(void *arg) {
> + uptr hard_rss_limit_mb = common_flags()->hard_rss_limit_mb;
> + uptr prev_reported_rss = 0;
> + uptr prev_reported_stack_depot_size = 0;
> + while (true) {
> + SleepForMillis(100);
> + uptr current_rss_mb = GetRSS() >> 20;
> + if (common_flags()->verbosity) {
> + // If RSS has grown 10% since last time, print some information.
> + if (prev_reported_rss * 11 / 10 < current_rss_mb) {
> + Printf("%s: RSS: %zdMb\n", SanitizerToolName, current_rss_mb);
> + prev_reported_rss = current_rss_mb;
> + }
> + // If stack depot has grown 10% since last time, print it too.
> + StackDepotStats *stack_depot_stats = StackDepotGetStats();
> + if (prev_reported_stack_depot_size * 11 / 10 <
> + stack_depot_stats->allocated) {
> + Printf("%s: StackDepot: %zd ids; %zdM allocated\n",
> + SanitizerToolName,
> + stack_depot_stats->n_uniq_ids,
> + stack_depot_stats->allocated >> 20);
> + prev_reported_stack_depot_size = stack_depot_stats->allocated;
> + }
> + }
> + // Check RSS against the limit.
> + if (hard_rss_limit_mb && hard_rss_limit_mb < current_rss_mb) {
> + Report("%s: hard rss limit exhausted (%zdMb vs %zdMb)\n",
> + SanitizerToolName, hard_rss_limit_mb, current_rss_mb);
> + DumpProcessMap();
> + Die();
> + }
> + }
> +}
> +
> +void MaybeStartBackgroudThread() {
> + if (!SANITIZER_LINUX) return; // Need to implement/test on other
> platforms.
> + // Currently, only start the background thread if hard_rss_limit_mb is
> given.
> + if (!common_flags()->hard_rss_limit_mb) return;
> + if (!real_pthread_create) return; // Can't spawn the thread anyway.
> + internal_start_thread(BackgroundThread, nullptr);
> +}
> +
> } // namespace __sanitizer
>
> void NOINLINE
>
> 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=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Tue Dec 16
> 13:13:01 2014
> @@ -140,6 +140,11 @@ void ParseCommonFlagsFromString(CommonFl
> 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");
> + ParseFlag(str, &f->hard_rss_limit_mb, "hard_rss_limit_mb",
> + "RSS limit in Mb."
> + " If non-zero, a background thread is spawned at startup"
> + " which periodically reads RSS and aborts the process if the"
> + " limit is reached");
>
^^
You also need to provide the default value of this flag in
SetCommonFlagsDefaults() function.
> ParseFlag(str, &f->coverage, "coverage",
> "If set, coverage information will be dumped at program shutdown
> (if the "
> "coverage instrumentation was enabled at compile time).");
>
> 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=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Tue Dec 16
> 13:13:01 2014
> @@ -54,6 +54,7 @@ struct CommonFlags {
> bool intercept_tls_get_addr;
> bool help;
> uptr mmap_limit_mb;
> + uptr hard_rss_limit_mb;
> bool coverage;
> bool coverage_direct;
> const char *coverage_dir;
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_libc.h Tue Dec 16
> 13:13:01 2014
> @@ -98,6 +98,25 @@ int internal_fork();
> // Threading
> uptr internal_sched_yield();
>
> +// These functions call appropriate pthread_ functions directly, bypassing
> +// the interceptor. They are weak and may not be present in some tools.
> +SANITIZER_WEAK_ATTRIBUTE
> +int real_pthread_create(void *th, void *attr, void *(*callback)(void *),
> + void *param);
> +SANITIZER_WEAK_ATTRIBUTE
> +int real_pthread_join(void *th, void **ret);
> +
> +#define DEFINE_REAL_PTHREAD_FUNCTIONS
> \
> + namespace __sanitizer {
> \
> + int real_pthread_create(void *th, void *attr, void *(*callback)(void
> *), \
> + void *param) {
> \
> + return REAL(pthread_create)(th, attr, callback, param);
> \
> + }
> \
> + int real_pthread_join(void *th, void **ret) {
> \
> + return REAL(pthread_join(th, ret));
> \
> + }
> \
> + } // namespace __sanitizer
> +
> // Error handling
> bool internal_iserror(uptr retval, int *rverrno = 0);
>
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Tue Dec 16
> 13:13:01 2014
> @@ -938,6 +938,21 @@ bool IsDeadlySignal(int signum) {
> return (signum == SIGSEGV) && common_flags()->handle_segv;
> }
>
> +void *internal_start_thread(void(*func)(void *arg), void *arg) {
> + // Start the thread with signals blocked, otherwise it can steal user
> signals.
> + __sanitizer_sigset_t set, old;
> + internal_sigfillset(&set);
> + internal_sigprocmask(SIG_SETMASK, &set, &old);
> + void *th;
> + real_pthread_create(&th, 0, (void*(*)(void *arg))func, arg);
> + internal_sigprocmask(SIG_SETMASK, &old, 0);
> + return th;
> +}
> +
> +void internal_join_thread(void *th) {
> + real_pthread_join(th, 0);
> +}
> +
> } // namespace __sanitizer
>
> #endif // SANITIZER_FREEBSD || SANITIZER_LINUX
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Tue Dec 16
> 13:13:01 2014
> @@ -325,6 +325,9 @@ uptr GetRSS() {
> return 0;
> }
>
> +void *internal_start_thread(void (*func)(void *arg), void *arg) { return
> 0; }
> +void internal_join_thread(void *th) { return 0; }
> +
> } // namespace __sanitizer
>
> #endif // SANITIZER_MAC
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Tue Dec 16
> 13:13:01 2014
> @@ -379,6 +379,9 @@ uptr GetRSS() {
> return 0;
> }
>
> +void *internal_start_thread(void (*func)(void *arg), void *arg) { return
> 0; }
> +void internal_join_thread(void *th) { return 0; }
> +
> // ---------------------- BlockingMutex ---------------- {{{1
> const uptr LOCK_UNINITIALIZED = 0;
> const uptr LOCK_READY = (uptr)-1;
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Dec 16
> 13:13:01 2014
> @@ -948,6 +948,8 @@ TSAN_INTERCEPTOR(int, pthread_join, void
> return res;
> }
>
> +DEFINE_REAL_PTHREAD_FUNCTIONS;
> +
> TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
> SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
> int tid = ThreadTid(thr, pc, (uptr)th);
> @@ -2565,19 +2567,4 @@ void InitializeInterceptors() {
> FdInit();
> }
>
> -void *internal_start_thread(void(*func)(void *arg), void *arg) {
> - // Start the thread with signals blocked, otherwise it can steal user
> signals.
> - __sanitizer_sigset_t set, old;
> - internal_sigfillset(&set);
> - internal_sigprocmask(SIG_SETMASK, &set, &old);
> - void *th;
> - REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg);
> - internal_sigprocmask(SIG_SETMASK, &old, 0);
> - return th;
> -}
> -
> -void internal_join_thread(void *th) {
> - REAL(pthread_join)(th, 0);
> -}
> -
> } // namespace __tsan
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=224353&r1=224352&r2=224353&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Tue Dec 16 13:13:01 2014
> @@ -252,9 +252,6 @@ void InitializePlatform();
> void FlushShadowMemory();
> void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr
> nlive);
>
> -void *internal_start_thread(void(*func)(void*), void *arg);
> -void internal_join_thread(void *th);
> -
> // Says whether the addr relates to a global var.
> // Guesses with high probability, may yield both false positives and
> negatives.
> bool IsGlobalVar(uptr addr);
>
> Added:
> compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc?rev=224353&view=auto
>
> ==============================================================================
> ---
> compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
> (added)
> +++
> compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
> Tue Dec 16 13:13:01 2014
> @@ -0,0 +1,35 @@
> +// Check hard_rss_limit_mb. Not all sanitizers implement it yet.
> +// 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 w/o limit or with a large enough limit should pass:
> +// RUN: %tool_options=hard_rss_limit_mb=1000 %run %t
> +// RUN: %run %t
> +//
> +// FIXME: make it work for other sanitizers.
> +// XFAIL: lsan
> +// XFAIL: tsan
> +// XFAIL: msan
> +
> +#include <string.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +const int kNumAllocs = 200 * 1000;
> +const int kAllocSize = 1000;
> +volatile char *sink[kNumAllocs];
> +
> +int main(int argc, char **argv) {
> + for (int i = 0; i < kNumAllocs; i++) {
> + if ((i % 1000) == 0) {
> + fprintf(stderr, "[%d]\n", i);
> + }
> + char *x = new char[kAllocSize];
> + memset(x, 0, kAllocSize);
> + sink[i] = x;
> + }
> + sleep(1); // Make sure the background thread has time to kill the
> process.
> +// CHECK: hard rss limit exhausted
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
--
Alexey Samsonov
vonosmas at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20141218/45895117/attachment.html>
More information about the llvm-commits
mailing list