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_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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to