forked from OSchip/llvm-project
[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:
parent
4c17c1b157
commit
b4a218db34
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue