[sanitizer] Don't adjust the size of the user-allocated stack.

Moved this code to sanitizer_common.

llvm-svn: 177383
This commit is contained in:
Evgeniy Stepanov 2013-03-19 09:30:52 +00:00
parent 4c17c1b157
commit b4a218db34
5 changed files with 65 additions and 24 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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__

View File

@ -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

View File

@ -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;