[compiler-rt] r182456 - [asan] workaround for asan bug 189 (swapcontext followed by throw gets OOM kill). Also, disable swapcontext_test on non-x86. Fix lint

Kostya Serebryany kcc at google.com
Wed May 22 01:54:31 PDT 2013


Author: kcc
Date: Wed May 22 03:54:30 2013
New Revision: 182456

URL: http://llvm.org/viewvc/llvm-project?rev=182456&view=rev
Log:
[asan] workaround for asan bug 189 (swapcontext followed by throw gets OOM kill). Also, disable swapcontext_test on non-x86. Fix lint

Modified:
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/lit_tests/Linux/swapcontext_test.cc
    compiler-rt/trunk/lib/asan/tests/asan_test.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=182456&r1=182455&r2=182456&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed May 22 03:54:30 2013
@@ -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);
 }
 

Modified: compiler-rt/trunk/lib/asan/lit_tests/Linux/swapcontext_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/Linux/swapcontext_test.cc?rev=182456&r1=182455&r2=182456&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/Linux/swapcontext_test.cc (original)
+++ compiler-rt/trunk/lib/asan/lit_tests/Linux/swapcontext_test.cc Wed May 22 03:54:30 2013
@@ -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;
 }

Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=182456&r1=182455&r2=182456&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Wed May 22 03:54:30 2013
@@ -1221,10 +1221,12 @@ TEST(AddressSanitizer, LongDoubleNegativ
 TEST(AddressSanitizer, pthread_getschedparam) {
   int policy;
   struct sched_param param;
-  EXPECT_DEATH(pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
-               "AddressSanitizer: stack-buffer-overflow");
-  EXPECT_DEATH(pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
-               "AddressSanitizer: stack-buffer-overflow");
+  EXPECT_DEATH(
+      pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
+      "AddressSanitizer: stack-buffer-overflow");
+  EXPECT_DEATH(
+      pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
+      "AddressSanitizer: stack-buffer-overflow");
   int res = pthread_getschedparam(pthread_self(), &policy, &param);
   ASSERT_EQ(0, res);
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=182456&r1=182455&r2=182456&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed May 22 03:54:30 2013
@@ -651,7 +651,8 @@ INTERCEPTOR_WITH_SUFFIX(int, wait, int *
     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);





More information about the llvm-commits mailing list