[asan] fix one more case where stack-use-after-return is not async-signal-safe (during thread startup). beef-up the test to give it a chance to catch regressions. Also relax the lint to make C++11 more usable.

llvm-svn: 304598
This commit is contained in:
Kostya Serebryany 2017-06-02 21:32:04 +00:00
parent 6aeacaa527
commit ad272b0861
3 changed files with 29 additions and 18 deletions

View File

@ -166,16 +166,19 @@ void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save,
}
inline AsanThread::StackBounds AsanThread::GetStackBounds() const {
if (!atomic_load(&stack_switching_, memory_order_acquire))
return StackBounds{stack_bottom_, stack_top_}; // NOLINT
if (!atomic_load(&stack_switching_, memory_order_acquire)) {
// Make sure the stack bounds are fully initialized.
if (stack_bottom_ >= stack_top_) return {0, 0};
return {stack_bottom_, stack_top_};
}
char local;
const uptr cur_stack = (uptr)&local;
// Note: need to check next stack first, because FinishSwitchFiber
// may be in process of overwriting stack_top_/bottom_. But in such case
// we are already on the next stack.
if (cur_stack >= next_stack_bottom_ && cur_stack < next_stack_top_)
return StackBounds{next_stack_bottom_, next_stack_top_}; // NOLINT
return StackBounds{stack_bottom_, stack_top_}; // NOLINT
return {next_stack_bottom_, next_stack_top_};
return {stack_bottom_, stack_top_};
}
uptr AsanThread::stack_top() {
@ -197,6 +200,7 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
uptr stack_size = this->stack_size();
if (stack_size == 0) // stack_size is not yet available, don't use FakeStack.
return nullptr;
CHECK_LE(stack_size, 0x10000000);
uptr old_val = 0;
// fake_stack_ has 3 states:
// 0 -- not initialized

View File

@ -18,7 +18,7 @@ fi
# Filters
# TODO: remove some of these filters
COMMON_LINT_FILTER=-build/include,-build/header_guard,-legal/copyright,-whitespace/comments,-readability/casting,\
-build/namespaces
-build/namespaces,-readability/braces
ASAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int
ASAN_TEST_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/sizeof,-runtime/int,-runtime/printf,-runtime/threadsafe_fn
ASAN_LIT_TEST_LINT_FILTER=${ASAN_TEST_LINT_FILTER},-whitespace/line_length

View File

@ -1,12 +1,13 @@
// This test checks that the implementation of use-after-return
// is async-signal-safe.
// RUN: %clangxx_asan -O1 %s -o %t -pthread && %run %t
// RUN: %clangxx_asan -std=c++11 -O1 %s -o %t -pthread && %run %t
// REQUIRES: stable-runtime
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <pthread.h>
#include <initializer_list>
int *g;
int n_signals;
@ -17,7 +18,6 @@ void SignalHandler(int, siginfo_t*, void*) {
int local;
g = &local;
n_signals++;
// printf("s: %p\n", &local);
}
static void EnableSigprof(Sigaction SignalHandler) {
@ -49,22 +49,29 @@ void RecursiveFunction(int depth) {
RecursiveFunction(depth - 1);
}
void *Thread(void *) {
RecursiveFunction(18);
void *FastThread(void *) {
RecursiveFunction(1);
return NULL;
}
void *SlowThread(void *) {
RecursiveFunction(1);
return NULL;
}
int main(int argc, char **argv) {
EnableSigprof(SignalHandler);
for (int i = 0; i < 4; i++) {
fprintf(stderr, ".");
const int kNumThread = sizeof(void*) == 8 ? 16 : 8;
pthread_t t[kNumThread];
for (int i = 0; i < kNumThread; i++)
pthread_create(&t[i], 0, Thread, 0);
for (int i = 0; i < kNumThread; i++)
pthread_join(t[i], 0);
for (auto Thread : {&FastThread, &SlowThread}) {
for (int i = 0; i < 1000; i++) {
fprintf(stderr, ".");
const int kNumThread = sizeof(void*) == 8 ? 32 : 8;
pthread_t t[kNumThread];
for (int i = 0; i < kNumThread; i++)
pthread_create(&t[i], 0, Thread, 0);
for (int i = 0; i < kNumThread; i++)
pthread_join(t[i], 0);
}
fprintf(stderr, "\n");
}
fprintf(stderr, "\n");
}