summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-03-19 09:30:52 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-03-19 09:30:52 +0000
commitb9bf700ae7fe59e25976e0abe9636150f3a39cd2 (patch)
tree0fe7869231a6258001ca3b472a20f7a7347e3ae0
parentc9de451e97b85e9712939ac2bfb02295645e2e0f (diff)
downloadcompiler-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.cc15
-rw-r--r--lib/msan/tests/msan_test.cc30
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc24
-rw-r--r--lib/sanitizer_common/sanitizer_linux.h3
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc17
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;