forked from OSchip/llvm-project
[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:
parent
6aeacaa527
commit
ad272b0861
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue