Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-26 Thread Andrii Grynenko via cfe-commits
andriigrynenko added inline comments.


Comment at: test/asan/TestCases/Linux/swapcontext_annotation.cc:176-199
@@ -164,7 +175,26 @@
 ret += Run(argc - 1, 0, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 1, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 2, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild stack: [[NEXT_CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild from: [[CHILD_STACK]] 524288
+// CHECK: Main context from: [[NEXT_CHILD_STACK]] 524288
 ret += Run(argc - 1, 0, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 1, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 2, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild stack: [[NEXT_CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild from: [[CHILD_STACK]] 524288
+// CHECK: Main context from: [[NEXT_CHILD_STACK]] 524288
+
+// CHECK: Iteration 0 passed
+printf("Iteration %d passed\n", i);
   }

dvyukov wrote:
> andriigrynenko wrote:
> > This only checks the first iteration of the loop. Can I do it better with 
> > FileCheck ? 
> Yes, you can add CHECKs for the second iteration as well.
> 
@dvyukov: What I meant is that I didn't see a way to have some kind of loop in 
these CHECKs. I don't want to copy-paste these same CHECKs 30 times :)


https://reviews.llvm.org/D24628



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-26 Thread Andrii Grynenko via cfe-commits
andriigrynenko updated this revision to Diff 72571.
andriigrynenko added a comment.

Do CHECKs for all iterations of the loop.


https://reviews.llvm.org/D24628

Files:
  include/sanitizer/common_interface_defs.h
  lib/asan/asan_thread.cc
  lib/asan/asan_thread.h
  test/asan/TestCases/Linux/swapcontext_annotation.cc

Index: test/asan/TestCases/Linux/swapcontext_annotation.cc
===
--- test/asan/TestCases/Linux/swapcontext_annotation.cc
+++ test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -1,12 +1,17 @@
 // Check that ASan plays well with annotated makecontext/swapcontext.
 
-// RUN: %clangxx_asan -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
+// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck <( seq 60 | xargs -i -- grep LOOPCHECK %s ) --check-prefix LOOPCHECK
+
 //
 // This test is too subtle to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
 
 #include 
 #include 
@@ -25,9 +30,12 @@
 
 const int kStackSize = 1 << 20;
 
-void *main_thread_stack;
+const void *main_thread_stack;
 size_t main_thread_stacksize;
 
+const void *from_stack;
+size_t from_stacksize;
+
 __attribute__((noinline, noreturn)) void LongJump(jmp_buf env) {
   longjmp(env, 1);
   _exit(1);
@@ -44,14 +52,18 @@
 
 void NextChild() {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(nullptr, &from_stack, &from_stacksize);
+
+  printf("NextChild from: %p %zu\n", from_stack, from_stacksize);
 
   char x[32] = {0};  // Stack gets poisoned.
   printf("NextChild: %p\n", x);
 
   CallNoReturn();
 
-  __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+  __sanitizer_start_switch_fiber(nullptr,
+ main_thread_stack,
+ main_thread_stacksize);
   CallNoReturn();
   if (swapcontext(&next_child_context, &orig_context) < 0) {
 perror("swapcontext");
@@ -61,30 +73,39 @@
 
 void Child(int mode) {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(nullptr,
+  &main_thread_stack,
+  &main_thread_stacksize);
   char x[32] = {0};  // Stack gets poisoned.
   printf("Child: %p\n", x);
   CallNoReturn();
   // (a) Do nothing, just return to parent function.
   // (b) Jump into the original function. Stack remains poisoned unless we do
   // something.
   // (c) Jump to another function which will then jump back to the main function
   if (mode == 0) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(nullptr,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
   } else if (mode == 1) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(nullptr,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
 if (swapcontext(&child_context, &orig_context) < 0) {
   perror("swapcontext");
   _exit(1);
 }
   } else if (mode == 2) {
+printf("NextChild stack: %p\n", next_child_stack);
+
 getcontext(&next_child_context);
 next_child_context.uc_stack.ss_sp = next_child_stack;
 next_child_context.uc_stack.ss_size = kStackSize / 2;
 makecontext(&next_child_context, (void (*)())NextChild, 0);
-__sanitizer_start_switch_fiber(next_child_context.uc_stack.ss_sp,
+__sanitizer_start_switch_fiber(nullptr,
+   next_child_context.uc_stack.ss_sp,
next_child_context.uc_stack.ss_size);
 CallNoReturn();
 if (swapcontext(&child_context, &next_child_c

[PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-15 Thread Andrii Grynenko via cfe-commits
andriigrynenko created this revision.
andriigrynenko added reviewers: kcc, blastrock, dvyukov, filcab.
andriigrynenko added a subscriber: cfe-commits.
andriigrynenko set the repository for this revision to rL LLVM.
Herald added a subscriber: kubabrecka.

This patch extends __sanitizer_finish_switch_fiber method to optionally return 
previous stack base and size. 

This solves the problem of coroutines/fibers library not knowing the original 
stack context from which the library is used. It's incorrect to assume that 
such context is always the default stack of current thread (e.g. one such 
library may be used from a fiber/coroutine created by another library). Bulding 
a separate stack tracking mechanism would not only duplicate AsanThread, but 
also require each coroutines/fibers library to integrate with it.

Repository:
  rL LLVM

https://reviews.llvm.org/D24628

Files:
  compiler-rt/include/sanitizer/common_interface_defs.h
  compiler-rt/lib/asan/asan_thread.cc
  compiler-rt/lib/asan/asan_thread.h

Index: compiler-rt/lib/asan/asan_thread.h
===
--- compiler-rt/lib/asan/asan_thread.h
+++ compiler-rt/lib/asan/asan_thread.h
@@ -94,7 +94,8 @@
   }
 
   void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
-  void FinishSwitchFiber(FakeStack *fake_stack_save);
+  void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
+ uptr *size_old);
 
   bool has_fake_stack() {
 return !atomic_load(&stack_switching_, memory_order_relaxed) &&
Index: compiler-rt/lib/asan/asan_thread.cc
===
--- compiler-rt/lib/asan/asan_thread.cc
+++ compiler-rt/lib/asan/asan_thread.cc
@@ -141,7 +141,9 @@
 current_fake_stack->Destroy(this->tid());
 }
 
-void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save) {
+void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save,
+   uptr *bottom_old,
+   uptr *size_old) {
   if (!atomic_load(&stack_switching_, memory_order_relaxed)) {
 Report("ERROR: finishing a fiber switch that has not started\n");
 Die();
@@ -152,6 +154,12 @@
 fake_stack_ = fake_stack_save;
   }
 
+  if (bottom_old) {
+*bottom_old = stack_bottom_;
+  }
+  if (size_old) {
+*size_old = stack_top_ - stack_bottom_;
+  }
   stack_bottom_ = next_stack_bottom_;
   stack_top_ = next_stack_top_;
   atomic_store(&stack_switching_, 0, memory_order_release);
@@ -447,12 +455,16 @@
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_finish_switch_fiber(void* fakestack) {
+void __sanitizer_finish_switch_fiber(void* fakestack,
+ const void **bottom_old,
+ uptr *size_old) {
   AsanThread *t = GetCurrentThread();
   if (!t) {
 VReport(1, "__asan_finish_switch_fiber called from unknown thread\n");
 return;
   }
-  t->FinishSwitchFiber((FakeStack*)fakestack);
+  t->FinishSwitchFiber((FakeStack*)fakestack,
+   (uptr*)bottom_old,
+   (uptr*)size_old);
 }
 }
Index: compiler-rt/include/sanitizer/common_interface_defs.h
===
--- compiler-rt/include/sanitizer/common_interface_defs.h
+++ compiler-rt/include/sanitizer/common_interface_defs.h
@@ -169,7 +169,9 @@
   // use-after-return detection.
   void __sanitizer_start_switch_fiber(void **fake_stack_save,
   const void *bottom, size_t size);
-  void __sanitizer_finish_switch_fiber(void *fake_stack_save);
+  void __sanitizer_finish_switch_fiber(void *fake_stack_save,
+   const void **bottom_old,
+   size_t *size_old);
 #ifdef __cplusplus
 }  // extern "C"
 #endif


Index: compiler-rt/lib/asan/asan_thread.h
===
--- compiler-rt/lib/asan/asan_thread.h
+++ compiler-rt/lib/asan/asan_thread.h
@@ -94,7 +94,8 @@
   }
 
   void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
-  void FinishSwitchFiber(FakeStack *fake_stack_save);
+  void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
+ uptr *size_old);
 
   bool has_fake_stack() {
 return !atomic_load(&stack_switching_, memory_order_relaxed) &&
Index: compiler-rt/lib/asan/asan_thread.cc
===
--- compiler-rt/lib/asan/asan_thread.cc
+++ compiler-rt/lib/asan/asan_thread.cc
@@ -141,7 +141,9 @@
 current_fake_stack->Destroy(this->tid());
 }
 
-void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save) {
+void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save,
+   uptr *bottom_old,
+   uptr *size_old) {
   if (!atomic_load(&stack_swi

Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-16 Thread Andrii Grynenko via cfe-commits
andriigrynenko updated this revision to Diff 71677.
andriigrynenko added a comment.

fix the unit test


https://reviews.llvm.org/D24628

Files:
  include/sanitizer/common_interface_defs.h
  lib/asan/asan_thread.cc
  lib/asan/asan_thread.h
  test/asan/TestCases/Linux/swapcontext_annotation.cc

Index: test/asan/TestCases/Linux/swapcontext_annotation.cc
===
--- test/asan/TestCases/Linux/swapcontext_annotation.cc
+++ test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -6,7 +6,7 @@
 // RUN: %clangxx_asan -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
 //
 // This test is too subtle to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
 
 #include 
 #include 
@@ -44,14 +44,16 @@
 
 void NextChild() {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(NULL, NULL, NULL);
 
   char x[32] = {0};  // Stack gets poisoned.
   printf("NextChild: %p\n", x);
 
   CallNoReturn();
 
-  __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+  __sanitizer_start_switch_fiber(NULL,
+ main_thread_stack,
+ main_thread_stacksize);
   CallNoReturn();
   if (swapcontext(&next_child_context, &orig_context) < 0) {
 perror("swapcontext");
@@ -61,19 +63,23 @@
 
 void Child(int mode) {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(NULL, NULL, NULL);
   char x[32] = {0};  // Stack gets poisoned.
   printf("Child: %p\n", x);
   CallNoReturn();
   // (a) Do nothing, just return to parent function.
   // (b) Jump into the original function. Stack remains poisoned unless we do
   // something.
   // (c) Jump to another function which will then jump back to the main function
   if (mode == 0) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(NULL,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
   } else if (mode == 1) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(NULL,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
 if (swapcontext(&child_context, &orig_context) < 0) {
   perror("swapcontext");
@@ -84,7 +90,8 @@
 next_child_context.uc_stack.ss_sp = next_child_stack;
 next_child_context.uc_stack.ss_size = kStackSize / 2;
 makecontext(&next_child_context, (void (*)())NextChild, 0);
-__sanitizer_start_switch_fiber(next_child_context.uc_stack.ss_sp,
+__sanitizer_start_switch_fiber(NULL,
+   next_child_context.uc_stack.ss_sp,
next_child_context.uc_stack.ss_size);
 CallNoReturn();
 if (swapcontext(&child_context, &next_child_context) < 0) {
@@ -105,15 +112,16 @@
   }
   makecontext(&child_context, (void (*)())Child, 1, mode);
   CallNoReturn();
-  __sanitizer_start_switch_fiber(child_context.uc_stack.ss_sp,
+  __sanitizer_start_switch_fiber(NULL,
+ child_context.uc_stack.ss_sp,
  child_context.uc_stack.ss_size);
   CallNoReturn();
   if (swapcontext(&orig_context, &child_context) < 0) {
 perror("swapcontext");
 _exit(1);
   }
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(NULL, NULL, NULL);
   CallNoReturn();
 
   // Touch childs's stack to make sure it's unpoisoned.
Index: lib/asan/asan_thread.h
===
--- lib/asan/asan_thread.h
+++ lib/asan/asan_thread.h
@@ -94,7 +94,8 @@
   }
 
   void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
-  void FinishSwitchFiber(FakeStack *fake_stack_save);
+  void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
+ uptr *size_old);
 
   bool has_fake_stack() {
 return !atomic_load(&stack_switching_, memory_order_relaxed) &&
Index: lib/asan/asan_thread.cc
===
--- lib/asan/asan_thread.cc
+++ lib/asan/asan_thread.cc
@@ -141,7 +141,9 @@
 current_fake_stack->Destroy(this->tid());
 }
 
-void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save) {
+void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save,
+   uptr *bottom_old,
+   uptr *size_old) {
   if (!atomic_load(&stack_switching_, memory_order_relaxed)) {
 Report("ERROR: finishing a fiber switch that has not started\n");
 Die();
@@ -152,6 +154,12 @@
 fake_stack_ = fake_stack_save;
   }
 
+  if (bottom_old) {
+*bottom_old = stack_bottom_;
+  }
+  i

Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-16 Thread Andrii Grynenko via cfe-commits
andriigrynenko added inline comments.


Comment at: test/asan/TestCases/Linux/swapcontext_annotation.cc:9
@@ -8,3 +8,3 @@
 // This test is too subtle to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
 

The test was actually broken in trunk (not updated for the fakestack argument). 
Apparently it was never run (considered unsupported) because of wrong targets 
here. 


https://reviews.llvm.org/D24628



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-16 Thread Andrii Grynenko via cfe-commits
andriigrynenko updated this revision to Diff 71698.
andriigrynenko added a comment.

update unit test to use non-null values


https://reviews.llvm.org/D24628

Files:
  include/sanitizer/common_interface_defs.h
  lib/asan/asan_thread.cc
  lib/asan/asan_thread.h
  test/asan/TestCases/Linux/swapcontext_annotation.cc

Index: test/asan/TestCases/Linux/swapcontext_annotation.cc
===
--- test/asan/TestCases/Linux/swapcontext_annotation.cc
+++ test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -6,10 +6,11 @@
 // RUN: %clangxx_asan -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
 //
 // This test is too subtle to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -25,7 +26,7 @@
 
 const int kStackSize = 1 << 20;
 
-void *main_thread_stack;
+const void *main_thread_stack;
 size_t main_thread_stacksize;
 
 __attribute__((noinline, noreturn)) void LongJump(jmp_buf env) {
@@ -44,14 +45,16 @@
 
 void NextChild() {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(NULL, NULL, NULL);
 
   char x[32] = {0};  // Stack gets poisoned.
   printf("NextChild: %p\n", x);
 
   CallNoReturn();
 
-  __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+  __sanitizer_start_switch_fiber(NULL,
+ main_thread_stack,
+ main_thread_stacksize);
   CallNoReturn();
   if (swapcontext(&next_child_context, &orig_context) < 0) {
 perror("swapcontext");
@@ -61,19 +64,25 @@
 
 void Child(int mode) {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(NULL,
+  &main_thread_stack,
+  &main_thread_stacksize);
   char x[32] = {0};  // Stack gets poisoned.
   printf("Child: %p\n", x);
   CallNoReturn();
   // (a) Do nothing, just return to parent function.
   // (b) Jump into the original function. Stack remains poisoned unless we do
   // something.
   // (c) Jump to another function which will then jump back to the main function
   if (mode == 0) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(NULL,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
   } else if (mode == 1) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(NULL,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
 if (swapcontext(&child_context, &orig_context) < 0) {
   perror("swapcontext");
@@ -84,7 +93,8 @@
 next_child_context.uc_stack.ss_sp = next_child_stack;
 next_child_context.uc_stack.ss_size = kStackSize / 2;
 makecontext(&next_child_context, (void (*)())NextChild, 0);
-__sanitizer_start_switch_fiber(next_child_context.uc_stack.ss_sp,
+__sanitizer_start_switch_fiber(NULL,
+   next_child_context.uc_stack.ss_sp,
next_child_context.uc_stack.ss_size);
 CallNoReturn();
 if (swapcontext(&child_context, &next_child_context) < 0) {
@@ -105,15 +115,17 @@
   }
   makecontext(&child_context, (void (*)())Child, 1, mode);
   CallNoReturn();
-  __sanitizer_start_switch_fiber(child_context.uc_stack.ss_sp,
+  void* fake_stack_save;
+  __sanitizer_start_switch_fiber(&fake_stack_save,
+ child_context.uc_stack.ss_sp,
  child_context.uc_stack.ss_size);
   CallNoReturn();
   if (swapcontext(&orig_context, &child_context) < 0) {
 perror("swapcontext");
 _exit(1);
   }
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(fake_stack_save, NULL, NULL);
   CallNoReturn();
 
   // Touch childs's stack to make sure it's unpoisoned.
@@ -125,17 +137,7 @@
 
 void handler(int sig) { CallNoReturn(); }
 
-void InitStackBounds() {
-  pthread_attr_t attr;
-  pthread_attr_init(&attr);
-  pthread_getattr_np(pthread_self(), &attr);
-  pthread_attr_getstack(&attr, &main_thread_stack, &main_thread_stacksize);
-  pthread_attr_destroy(&attr);
-}
-
 int main(int argc, char **argv) {
-  InitStackBounds();
-
   // set up a signal that will spam and trigger __asan_handle_no_return at
   // tricky moments
   struct sigaction act = {};
Index: lib/asan/asan_thread.h
===
--- lib/asan/asan_thread.h
+++ lib/asan/asan_thread.h
@@ -94,7 +94,8 @@
   }
 
   void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
-  void FinishSwitchFiber(FakeStack *fake_stack_save);
+  void FinishSwitchFiber(Fak

Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-16 Thread Andrii Grynenko via cfe-commits
andriigrynenko updated this revision to Diff 71717.
andriigrynenko added a comment.

Addressing comments.


https://reviews.llvm.org/D24628

Files:
  include/sanitizer/common_interface_defs.h
  lib/asan/asan_thread.cc
  lib/asan/asan_thread.h
  test/asan/TestCases/Linux/swapcontext_annotation.cc

Index: test/asan/TestCases/Linux/swapcontext_annotation.cc
===
--- test/asan/TestCases/Linux/swapcontext_annotation.cc
+++ test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -1,12 +1,12 @@
 // Check that ASan plays well with annotated makecontext/swapcontext.
 
-// RUN: %clangxx_asan -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx_asan -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -std=c++11 -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
 //
 // This test is too subtle to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
 
 #include 
 #include 
@@ -25,9 +25,12 @@
 
 const int kStackSize = 1 << 20;
 
-void *main_thread_stack;
+const void *main_thread_stack;
 size_t main_thread_stacksize;
 
+const void *from_stack;
+size_t from_stacksize;
+
 __attribute__((noinline, noreturn)) void LongJump(jmp_buf env) {
   longjmp(env, 1);
   _exit(1);
@@ -44,14 +47,18 @@
 
 void NextChild() {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(nullptr, &from_stack, &from_stacksize);
+
+  printf("NextChild from: %p %zu\n", from_stack, from_stacksize);
 
   char x[32] = {0};  // Stack gets poisoned.
   printf("NextChild: %p\n", x);
 
   CallNoReturn();
 
-  __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+  __sanitizer_start_switch_fiber(nullptr,
+ main_thread_stack,
+ main_thread_stacksize);
   CallNoReturn();
   if (swapcontext(&next_child_context, &orig_context) < 0) {
 perror("swapcontext");
@@ -61,30 +68,39 @@
 
 void Child(int mode) {
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(nullptr,
+  &main_thread_stack,
+  &main_thread_stacksize);
   char x[32] = {0};  // Stack gets poisoned.
   printf("Child: %p\n", x);
   CallNoReturn();
   // (a) Do nothing, just return to parent function.
   // (b) Jump into the original function. Stack remains poisoned unless we do
   // something.
   // (c) Jump to another function which will then jump back to the main function
   if (mode == 0) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(nullptr,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
   } else if (mode == 1) {
-__sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+__sanitizer_start_switch_fiber(nullptr,
+   main_thread_stack,
+   main_thread_stacksize);
 CallNoReturn();
 if (swapcontext(&child_context, &orig_context) < 0) {
   perror("swapcontext");
   _exit(1);
 }
   } else if (mode == 2) {
+printf("NextChild stack: %p\n", next_child_stack);
+
 getcontext(&next_child_context);
 next_child_context.uc_stack.ss_sp = next_child_stack;
 next_child_context.uc_stack.ss_size = kStackSize / 2;
 makecontext(&next_child_context, (void (*)())NextChild, 0);
-__sanitizer_start_switch_fiber(next_child_context.uc_stack.ss_sp,
+__sanitizer_start_switch_fiber(nullptr,
+   next_child_context.uc_stack.ss_sp,
next_child_context.uc_stack.ss_size);
 CallNoReturn();
 if (swapcontext(&child_context, &next_child_context) < 0) {
@@ -105,16 +121,21 @@
   }
   makecontext(&child_context, (void (*)())Child, 1, mode);
   CallNoReturn();
-  __sanitizer_start_switch_fiber(child_context.uc_stack.ss_sp,
+  void* fake_stack_save;
+  __sanitizer_start_switch_fiber(&fake_stack_save,
+ child_context.uc_stack.ss_sp,
  child_context.uc_stack.ss_size);
   CallNoReturn();
   if (swapcontext(&orig_context, &child_context) < 0) {
 perror("swapcontext");
 _exit(1);
   }
   CallNoReturn();
-  __sanitizer_finish_switch_fiber();
+  __sanitizer_finish_switch_fiber(fake_stack_save,
+   

Re: [PATCH] D24628: [ASAN] Pass previous stack information through __sanitizer_finish_switch_fiber

2016-09-16 Thread Andrii Grynenko via cfe-commits
andriigrynenko added inline comments.


Comment at: test/asan/TestCases/Linux/swapcontext_annotation.cc:176-199
@@ -164,7 +175,26 @@
 ret += Run(argc - 1, 0, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 1, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 2, stack);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild stack: [[NEXT_CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild from: [[CHILD_STACK]] 524288
+// CHECK: Main context from: [[NEXT_CHILD_STACK]] 524288
 ret += Run(argc - 1, 0, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 1, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: Main context from: [[CHILD_STACK]] 524288
 ret += Run(argc - 1, 2, heap);
+// CHECK: Child stack: [[CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild stack: [[NEXT_CHILD_STACK:0x[0-9a-f]*]]
+// CHECK: NextChild from: [[CHILD_STACK]] 524288
+// CHECK: Main context from: [[NEXT_CHILD_STACK]] 524288
+
+// CHECK: Iteration 0 passed
+printf("Iteration %d passed\n", i);
   }

This only checks the first iteration of the loop. Can I do it better with 
FileCheck ? 


https://reviews.llvm.org/D24628



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits