diff options
author | Yabin Cui <yabinc@google.com> | 2015-01-08 12:32:42 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2015-01-08 14:27:24 -0800 |
commit | 917d390510e442b9b030d54992ebf41cc1e7f853 (patch) | |
tree | fd11b414b2b5f550c20944d916b07533d125b061 | |
parent | b5e508cfee2355bad0502587e4fce8f4173584d6 (diff) | |
download | bionic-917d390510e442b9b030d54992ebf41cc1e7f853.zip bionic-917d390510e442b9b030d54992ebf41cc1e7f853.tar.gz bionic-917d390510e442b9b030d54992ebf41cc1e7f853.tar.bz2 |
Make pthread stack size match real range.
Bug: 18908062
Change-Id: I7037ac8273ebe54dd19b1561c7a376819049124c
-rw-r--r-- | libc/bionic/pthread_create.cpp | 1 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 32 |
2 files changed, 28 insertions, 5 deletions
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 7e74dac..e4abee9 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -158,6 +158,7 @@ static int __allocate_thread(pthread_attr_t* attr, pthread_internal_t** threadp, // thread stack (including guard page) stack_top -= sizeof(pthread_internal_t); pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(stack_top); + attr->stack_size = stack_top - reinterpret_cast<uint8_t*>(attr->stack_base); // No need to check stack_top alignment. The size of pthread_internal_t is 16-bytes aligned, // and user allocated stack is guaranteed by pthread_attr_setstack. diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 1418c76..2398f23 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -32,7 +32,6 @@ #include <time.h> #include <unistd.h> - TEST(pthread, pthread_key_create) { pthread_key_t key; ASSERT_EQ(0, pthread_key_create(&key, NULL)); @@ -633,18 +632,18 @@ TEST(pthread, pthread_attr_setstacksize) { ASSERT_EQ(default_stack_size, stack_size); ASSERT_GE(GetActualStackSize(attributes), default_stack_size); - // Large enough and a multiple of the page size. + // Large enough and a multiple of the page size; may be rounded up by pthread_create. ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024)); ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); ASSERT_EQ(32*1024U, stack_size); - ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); + ASSERT_GE(GetActualStackSize(attributes), 32*1024U); - // Large enough but not a multiple of the page size; will be rounded up by pthread_create. + // Large enough but not aligned; will be rounded up by pthread_create. ASSERT_EQ(0, pthread_attr_setstacksize(&attributes, 32*1024 + 1)); ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size)); ASSERT_EQ(32*1024U + 1, stack_size); #if defined(__BIONIC__) - ASSERT_EQ(GetActualStackSize(attributes), 32*1024U + 1); + ASSERT_GT(GetActualStackSize(attributes), 32*1024U + 1); #else // __BIONIC__ // glibc rounds down, in violation of POSIX. They document this in their BUGS section. ASSERT_EQ(GetActualStackSize(attributes), 32*1024U); @@ -939,6 +938,29 @@ TEST(pthread, pthread_attr_getstack__main_thread) { ASSERT_EQ(6666U, stack_size); } +static void pthread_attr_getstack_18908062_helper(void*) { + char local_variable; + pthread_attr_t attributes; + pthread_getattr_np(pthread_self(), &attributes); + void* stack_base; + size_t stack_size; + pthread_attr_getstack(&attributes, &stack_base, &stack_size); + + // Test whether &local_variable is in [stack_base, stack_base + stack_size). + ASSERT_LE(reinterpret_cast<char*>(stack_base), &local_variable); + ASSERT_LT(&local_variable, reinterpret_cast<char*>(stack_base) + stack_size); +} + +// Check whether something on stack is in the range of +// [stack_base, stack_base + stack_size). see b/18908062. +TEST(pthread, pthread_attr_getstack_18908062) { + pthread_t t; + ASSERT_EQ(0, pthread_create(&t, NULL, + reinterpret_cast<void* (*)(void*)>(pthread_attr_getstack_18908062_helper), + NULL)); + pthread_join(t, NULL); +} + #if defined(__BIONIC__) static void* pthread_gettid_np_helper(void* arg) { *reinterpret_cast<pid_t*>(arg) = gettid(); |