diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -306,6 +306,7 @@ GetThreadStackAndTls(tid() == kMainTid, &stack_bottom_, &stack_size, &tls_begin_, &tls_size); stack_top_ = RoundDownTo(stack_bottom_ + stack_size, ASAN_SHADOW_GRANULARITY); + stack_bottom_ = RoundDownTo(stack_bottom_, ASAN_SHADOW_GRANULARITY); tls_end_ = tls_begin_ + tls_size; dtls_ = DTLS_Get(); diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/odd_stack_size.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/odd_stack_size.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/odd_stack_size.cpp @@ -0,0 +1,30 @@ +// RUN: %clangxx -O1 %s -o %t && %run %t +// UNSUPPORTED: android + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + if (getenv("SANITIZER_TEST_REEXECED")) + exit(0); + struct rlimit rl; + assert(!getrlimit(RLIMIT_STACK, &rl)); + struct rlimit rl_new = rl; + rl_new.rlim_cur = 17351; + assert(!setrlimit(RLIMIT_STACK, &rl_new)); + int pid = fork(); + assert(pid >= 0); + if (pid == 0) { + const char *envp[] = {"SANITIZER_TEST_REEXECED=1", nullptr}; + execve(argv[0], argv, const_cast(envp)); + assert(false); + } + int status; + while (waitpid(-1, &status, __WALL) != pid) { + } + assert(WIFEXITED(status) && WEXITSTATUS(status) == 0); + return 0; +}