forked from OSchip/llvm-project
[asan] workaround for asan bug 189 (swapcontext followed by throw gets OOM kill). Also, disable swapcontext_test on non-x86. Fix lint
llvm-svn: 182456
This commit is contained in:
parent
13c37b3483
commit
8410a867eb
|
@ -423,6 +423,20 @@ void NOINLINE __asan_handle_no_return() {
|
|||
uptr PageSize = GetPageSizeCached();
|
||||
uptr top = curr_thread->stack_top();
|
||||
uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
|
||||
static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
|
||||
if (top - bottom > kMaxExpectedCleanupSize) {
|
||||
static bool reported_warning = false;
|
||||
if (reported_warning)
|
||||
return;
|
||||
reported_warning = true;
|
||||
Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
|
||||
"stack top: %p; bottom %p; size: %p (%zd)\n"
|
||||
"False positive error reports may follow\n"
|
||||
"For details see "
|
||||
"http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
|
||||
top, bottom, top - bottom, top - bottom);
|
||||
return;
|
||||
}
|
||||
PoisonShadow(bottom, top - bottom, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s
|
||||
// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s
|
||||
//
|
||||
// This test is too sublte to try on non-x86 arch for now.
|
||||
// REQUIRES: x86_64-supported-target,i386-supported-target
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ucontext.h>
|
||||
|
@ -16,9 +19,26 @@
|
|||
ucontext_t orig_context;
|
||||
ucontext_t child_context;
|
||||
|
||||
const int kStackSize = 1 << 20;
|
||||
|
||||
__attribute__((noinline))
|
||||
void Throw() {
|
||||
throw 1;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
void ThrowAndCatch() {
|
||||
try {
|
||||
Throw();
|
||||
} catch(int a) {
|
||||
printf("ThrowAndCatch: %d\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
void Child(int mode) {
|
||||
char x[32] = {0}; // Stack gets poisoned.
|
||||
printf("Child: %p\n", x);
|
||||
ThrowAndCatch(); // Simulate __asan_handle_no_return().
|
||||
// (a) Do nothing, just return to parent function.
|
||||
// (b) Jump into the original function. Stack remains poisoned unless we do
|
||||
// something.
|
||||
|
@ -30,9 +50,7 @@ void Child(int mode) {
|
|||
}
|
||||
}
|
||||
|
||||
int Run(int arg, int mode) {
|
||||
const int kStackSize = 1 << 20;
|
||||
char child_stack[kStackSize + 1];
|
||||
int Run(int arg, int mode, char *child_stack) {
|
||||
printf("Child stack: %p\n", child_stack);
|
||||
// Setup child context.
|
||||
getcontext(&child_context);
|
||||
|
@ -54,13 +72,23 @@ int Run(int arg, int mode) {
|
|||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char stack[kStackSize + 1];
|
||||
// CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
|
||||
int ret = 0;
|
||||
ret += Run(argc - 1, 0);
|
||||
ret += Run(argc - 1, 0, stack);
|
||||
printf("Test1 passed\n");
|
||||
// CHECK: Test1 passed
|
||||
ret += Run(argc - 1, 1);
|
||||
ret += Run(argc - 1, 1, stack);
|
||||
printf("Test2 passed\n");
|
||||
// CHECK: Test2 passed
|
||||
char *heap = new char[kStackSize + 1];
|
||||
ret += Run(argc - 1, 0, heap);
|
||||
printf("Test3 passed\n");
|
||||
// CHECK: Test3 passed
|
||||
ret += Run(argc - 1, 1, heap);
|
||||
printf("Test4 passed\n");
|
||||
// CHECK: Test4 passed
|
||||
|
||||
delete [] heap;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1221,10 +1221,12 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) {
|
|||
TEST(AddressSanitizer, pthread_getschedparam) {
|
||||
int policy;
|
||||
struct sched_param param;
|
||||
EXPECT_DEATH(pthread_getschedparam(pthread_self(), &policy, Ident(¶m) + 2),
|
||||
"AddressSanitizer: stack-buffer-overflow");
|
||||
EXPECT_DEATH(pthread_getschedparam(pthread_self(), Ident(&policy) - 1, ¶m),
|
||||
"AddressSanitizer: stack-buffer-overflow");
|
||||
EXPECT_DEATH(
|
||||
pthread_getschedparam(pthread_self(), &policy, Ident(¶m) + 2),
|
||||
"AddressSanitizer: stack-buffer-overflow");
|
||||
EXPECT_DEATH(
|
||||
pthread_getschedparam(pthread_self(), Ident(&policy) - 1, ¶m),
|
||||
"AddressSanitizer: stack-buffer-overflow");
|
||||
int res = pthread_getschedparam(pthread_self(), &policy, ¶m);
|
||||
ASSERT_EQ(0, res);
|
||||
}
|
||||
|
|
|
@ -651,7 +651,8 @@ INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
|
|||
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
|
||||
return res;
|
||||
}
|
||||
INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, int options) {
|
||||
INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
|
||||
int options) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
|
||||
int res = REAL(waitid)(idtype, id, infop, options);
|
||||
|
|
Loading…
Reference in New Issue