[msan] Increase stack size as required.

Adjust stack size in pthread_attr_t when the app-requested size does not fit MSan TLS.

llvm-svn: 176939
This commit is contained in:
Evgeniy Stepanov 2013-03-13 09:01:40 +00:00
parent 5697b58ec4
commit 98f5ea0dba
5 changed files with 63 additions and 0 deletions

View File

@ -235,6 +235,7 @@ void __msan_init() {
InstallAtExitHandler();
SetDieCallback(MsanDie);
InitTlsSize();
InitializeInterceptors();
ReplaceOperatorsNewAndDelete();

View File

@ -790,6 +790,35 @@ INTERCEPTOR(int, getrusage, int who, void *usage) {
return res;
}
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);
INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
void * param) {
ENSURE_MSAN_INITED(); // for GetTlsSize()
__sanitizer_pthread_attr_t myattr;
if (attr == 0) {
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);
}
int res = REAL(pthread_create)(th, attr, callback, param);
if (attr == &myattr)
pthread_attr_destroy(&myattr);
return res;
}
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
__msan_unpoison(ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) do { } while (false)
@ -994,6 +1023,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(dladdr);
INTERCEPT_FUNCTION(dlopen);
INTERCEPT_FUNCTION(getrusage);
INTERCEPT_FUNCTION(pthread_create);
inited = 1;
}
} // namespace __msan

View File

@ -1372,6 +1372,27 @@ TEST(MemorySanitizer, SimpleThread) {
delete (int*)p;
}
static void* SmallStackThread_threadfn(void* data) {
return 0;
}
TEST(MemorySanitizer, SmallStackThread) {
pthread_attr_t attr;
pthread_t t;
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);
ASSERT_EQ(0, res);
res = pthread_join(t, &p);
ASSERT_EQ(0, res);
res = pthread_attr_destroy(&attr);
ASSERT_EQ(0, res);
}
TEST(MemorySanitizer, uname) {
struct utsname u;
int res = uname(&u);

View File

@ -18,6 +18,7 @@
#include "sanitizer_platform_limits_posix.h"
#include <dirent.h>
#include <pthread.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
@ -67,4 +68,6 @@ namespace __sanitizer {
}
} // namespace __sanitizer
COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
#endif // __linux__ || __APPLE__

View File

@ -38,6 +38,14 @@ namespace __sanitizer {
uptr __sanitizer_get_msghdr_iov_iov_len(void* msg, int idx);
uptr __sanitizer_get_msghdr_iovlen(void* msg);
uptr __sanitizer_get_socklen_t(void* socklen_ptr);
// This thing depends on the platform. We are only interested in the upper
// limit. Verified with a compiler assert in .cc.
const int pthread_attr_t_max_sz = 128;
union __sanitizer_pthread_attr_t {
char size[pthread_attr_t_max_sz];
void *align;
};
} // namespace __sanitizer
#endif