From 33ac04a215a70d2f39f1ddec1bba5a42c0fd8bee Mon Sep 17 00:00:00 2001 From: Yabin Cui Date: Tue, 22 Sep 2015 11:16:15 -0700 Subject: [PATCH] Increase alternative signal stack size on 64-bit devices. Bug: 23041777 Bug: 24187462 Change-Id: I7d84c0cc775a74753a3e8e101169c0fb5dbf7437 --- libc/bionic/pthread_internal.h | 7 ++++++- tests/pthread_test.cpp | 24 ++++++++++++++++++++++++ tests/stack_unwinding_test.cpp | 2 +- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 3b91e6a19..6a39a214a 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -130,8 +130,13 @@ __LIBC_HIDDEN__ void pthread_key_clean_all(void); */ #define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ) -/* Leave room for a guard page in the internally created signal stacks. */ +// Leave room for a guard page in the internally created signal stacks. +#if defined(__LP64__) +// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777. +#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE) +#else #define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE) +#endif /* Needed by fork. */ __LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare(); diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 3c686ef20..11afad141 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1632,3 +1633,26 @@ TEST_F(pthread_DeathTest, pthread_mutex_unlock_null_64) { GTEST_LOG_(INFO) << "This test tests bionic implementation details on 64 bit devices."; #endif } + +extern _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx, void* arg); + +static volatile bool signal_handler_on_altstack_done; + +static void SignalHandlerOnAltStack(int signo, siginfo_t*, void*) { + ASSERT_EQ(SIGUSR1, signo); + // Check if we have enough stack space for unwinding. + int count = 0; + _Unwind_Backtrace(FrameCounter, &count); + ASSERT_GT(count, 0); + // Check if we have enough stack space for logging. + std::string s(2048, '*'); + GTEST_LOG_(INFO) << s; + signal_handler_on_altstack_done = true; +} + +TEST(pthread, big_enough_signal_stack_for_64bit_arch) { + signal_handler_on_altstack_done = false; + ScopedSignalHandler handler(SIGUSR1, SignalHandlerOnAltStack, SA_SIGINFO | SA_ONSTACK); + kill(getpid(), SIGUSR1); + ASSERT_TRUE(signal_handler_on_altstack_done); +} diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp index d1b3402cd..afd9e7f0e 100644 --- a/tests/stack_unwinding_test.cpp +++ b/tests/stack_unwinding_test.cpp @@ -34,7 +34,7 @@ #define noinline __attribute__((__noinline__)) #define __unused __attribute__((__unused__)) -static _Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) { +_Unwind_Reason_Code FrameCounter(_Unwind_Context* ctx __unused, void* arg) { int* count_ptr = reinterpret_cast(arg); #if SHOW_FRAME_LOCATIONS