diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-03-19 09:30:52 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-03-19 09:30:52 +0000 |
commit | b9bf700ae7fe59e25976e0abe9636150f3a39cd2 (patch) | |
tree | 0fe7869231a6258001ca3b472a20f7a7347e3ae0 | |
parent | c9de451e97b85e9712939ac2bfb02295645e2e0f (diff) | |
download | compiler-rt-b9bf700ae7fe59e25976e0abe9636150f3a39cd2.tar.gz compiler-rt-b9bf700ae7fe59e25976e0abe9636150f3a39cd2.tar.bz2 compiler-rt-b9bf700ae7fe59e25976e0abe9636150f3a39cd2.tar.xz |
[sanitizer] Don't adjust the size of the user-allocated stack.
Moved this code to sanitizer_common.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@177383 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/msan/msan_interceptors.cc | 15 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 30 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 24 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.h | 3 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 17 |
5 files changed, 65 insertions, 24 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 287d2d26..677b8a8f 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -22,6 +22,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_linux.h" #include <stdarg.h> // ACHTUNG! No other system header includes in this file. @@ -826,7 +827,7 @@ INTERCEPTOR(int, getrusage, int who, void *usage) { extern "C" int pthread_attr_init(void *attr); extern "C" int pthread_attr_destroy(void *attr); extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize); -extern "C" int pthread_attr_getstacksize(void *attr, uptr *stacksize); +extern "C" int pthread_attr_getstack(void *attr, uptr *stack, uptr *stacksize); INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), void * param) { @@ -836,16 +837,8 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), pthread_attr_init(&myattr); attr = &myattr; } - uptr stacksize = 0; - pthread_attr_getstacksize(attr, &stacksize); - // We place the huge ThreadState object into TLS, account for that. - const uptr minstacksize = GetTlsSize() + 128*1024; - if (stacksize < minstacksize) { - if (flags()->verbosity) - Printf("MemorySanitizer: increasing stacksize %zu->%zu\n", stacksize, - minstacksize); - pthread_attr_setstacksize(attr, minstacksize); - } + + AdjustStackSizeLinux(attr, flags()->verbosity); int res = REAL(pthread_create)(th, attr, callback, param); if (attr == &myattr) diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 3380c13f..feaca962 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -1413,13 +1413,13 @@ TEST(MemorySanitizer, scanf) { delete d; } -static void* SimpleThread_threadfn(void* data) { +static void *SimpleThread_threadfn(void* data) { return new int; } TEST(MemorySanitizer, SimpleThread) { pthread_t t; - void* p; + void *p; int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL); assert(!res); res = pthread_join(t, &p); @@ -1429,20 +1429,20 @@ TEST(MemorySanitizer, SimpleThread) { delete (int*)p; } -static void* SmallStackThread_threadfn(void* data) { +static void *SmallStackThread_threadfn(void* data) { return 0; } TEST(MemorySanitizer, SmallStackThread) { pthread_attr_t attr; pthread_t t; - void* p; + void *p; int res; res = pthread_attr_init(&attr); ASSERT_EQ(0, res); res = pthread_attr_setstacksize(&attr, 64 * 1024); ASSERT_EQ(0, res); - res = pthread_create(&t, &attr, SimpleThread_threadfn, NULL); + res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL); ASSERT_EQ(0, res); res = pthread_join(t, &p); ASSERT_EQ(0, res); @@ -1450,6 +1450,26 @@ TEST(MemorySanitizer, SmallStackThread) { ASSERT_EQ(0, res); } +TEST(MemorySanitizer, PreAllocatedStackThread) { + pthread_attr_t attr; + pthread_t t; + int res; + res = pthread_attr_init(&attr); + ASSERT_EQ(0, res); + void *stack; + const size_t kStackSize = 64 * 1024; + res = posix_memalign(&stack, 4096, kStackSize); + ASSERT_EQ(0, res); + res = pthread_attr_setstack(&attr, stack, kStackSize); + ASSERT_EQ(0, res); + // A small self-allocated stack can not be extended by the tool. + // In this case pthread_create is expected to fail. + res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL); + EXPECT_NE(0, res); + res = pthread_attr_destroy(&attr); + ASSERT_EQ(0, res); +} + TEST(MemorySanitizer, uname) { struct utsname u; int res = uname(&u); diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index dd36ca32..a7e0f0d4 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -706,6 +706,30 @@ uptr GetTlsSize() { return g_tls_size; } +void AdjustStackSizeLinux(void *attr_, int verbosity) { + pthread_attr_t *attr = (pthread_attr_t *)attr_; + uintptr_t stackaddr = 0; + size_t stacksize = 0; + pthread_attr_getstack(attr, (void**)&stackaddr, &stacksize); + // GLibC will return (0 - stacksize) as the stack address in the case when + // stacksize is set, but stackaddr is not. + bool stack_set = (stackaddr != 0) && (stackaddr + stacksize != 0); + // We place a lot of tool data into TLS, account for that. + const uptr minstacksize = GetTlsSize() + 128*1024; + if (stacksize < minstacksize) { + if (!stack_set) { + if (verbosity && stacksize != 0) + Printf("Sanitizer: increasing stacksize %zu->%zu\n", stacksize, + minstacksize); + pthread_attr_setstacksize(attr, minstacksize); + } else { + Printf("Sanitizer: pre-allocated stack size is insufficient: " + "%zu < %zu\n", stacksize, minstacksize); + Printf("Sanitizer: pthread_create is likely to fail.\n"); + } + } +} + } // namespace __sanitizer #endif // __linux__ diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h index b4ac3108..33d39bf5 100644 --- a/lib/sanitizer_common/sanitizer_linux.h +++ b/lib/sanitizer_common/sanitizer_linux.h @@ -48,6 +48,9 @@ class ThreadLister { struct linux_dirent* entry_; int bytes_read_; }; + +void AdjustStackSizeLinux(void *attr, int verbosity); + } // namespace __sanitizer #endif // SANITIZER_LINUX_H diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 8bc2762d..e2ef9561 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -15,6 +15,7 @@ #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stacktrace.h" @@ -738,14 +739,14 @@ TSAN_INTERCEPTOR(int, pthread_create, } int detached = 0; pthread_attr_getdetachstate(attr, &detached); - uptr stacksize = 0; - pthread_attr_getstacksize(attr, &stacksize); - // We place the huge ThreadState object into TLS, account for that. - const uptr minstacksize = GetTlsSize() + 128*1024; - if (stacksize < minstacksize) { - DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize, minstacksize); - pthread_attr_setstacksize(attr, minstacksize); - } + +#if defined(TSAN_DEBUG_OUTPUT) + int verbosity = (TSAN_DEBUG_OUTPUT); +#else + int verbosity = 0; +#endif + AdjustStackSizeLinux(attr, verbosity); + ThreadParam p; p.callback = callback; p.param = param; |