[PATCH] D20913: [asan] add primitives that allow coroutine implementations

Philippe Daouadi via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 13 04:29:40 PDT 2016


blastrock added a comment.

In http://reviews.llvm.org/D20913#455864, @dvyukov wrote:

> > Another downside is that getting the current thread's stack bounds is done through a non-portable pthread API, but it does simplify asan code.
>
>
> I only see the APIs in test code. Is it correct?
>  Tests are OK. swapcontext is also non-portable.


Yes, I didn't add non-portable code to the library itself. I said that because it forces users to write non-portable code to annotate their code, but it's acceptable.


================
Comment at: lib/asan/asan_thread.cc:133
@@ +132,3 @@
+  if (!stack_switching_)
+    Report("WARNING: finishing a fiber enter that has not started\n");
+  // order is important so that the range [bottom, top] is empty until we are
----------------
dvyukov wrote:
> If you want to tolerate some user errors here, then I think it's better to return here. next_stack_top/bottom are most likely 0, so we will end up with no stack at all otherwise.
@filcab suggested an assertion instead, I think it would indeed be better since it shows a mis-use of annotations.

================
Comment at: lib/asan/asan_thread.cc:147
@@ +146,3 @@
+  if (!stack_switching_) {
+    if (next_stack_top_ && next_stack_bottom_)
+      return StackBounds{next_stack_bottom_, next_stack_top_};  // NOLINT
----------------
dvyukov wrote:
> Why?
> If I am reading core correctly, this must never happen.
> 
> > I made my implementation more signal-proof by using volatile. I saw later that in some other parts of the code, you prefer using atomic access, I can change the volatiles to that if needed.
> 
> Yes, please.
> Current ordering of memory  accesses if very tricky, esp in FinishSwitchFiber and I see that that is actually important for GetStackBounds correctness.
> 
> I think it is enough to make only stack_switching_ atomic:
> 
>   atomic<int> stack_switching_;
>   
>   void AsanThread::StartSwitchFiber(uptr bottom, uptr size) {
>     next_stack_bottom_ = bottom;
>     next_stack_top_ = bottom + size;
>     atomic_store(&stack_switching_, 1, memory_order_release);
>   }
>     
>   void AsanThread::FinishSwitchFiber() {
>     stack_bottom_ = next_stack_bottom_;
>     stack_top_ = next_stack_top_;
>     atomic_store(&stack_switching_, 0, memory_order_release);
>     next_stack_top_ = 0;
>     next_stack_bottom_ = 0;
>   }
>   
>   inline AsanThread::StackBounds AsanThread::GetStackBounds() const {
>     if (!atomic_load(&stack_switching_, memory_order_acquire))
>       return StackBounds{stack_bottom_, stack_top_};  // NOLINT
>     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
>   }
> 
Oh yes, you're right, this can't happen, I'll remove it.

As for your implementation, I think it would work, and it is indeed simpler.

================
Comment at: test/asan/TestCases/Linux/swapcontext_annotation.cc:5
@@ +4,3 @@
+// function
+// RUN: %clangxx_asan -lpthread -O0 %s -o %t
+// RUN: %run %t x 2>&1 | FileCheck %s
----------------
dvyukov wrote:
> I would expect that we do all that -O0/-O1/-O2 automatically on a higher level. At least we used to as far as I remember. Now all that cmake/lit in incomprehensible, so I am not sure... But I don't see any -O flags in other asan tests.
> 
> Does anybody know is we run asan lit tests with different optimization levels?
> 
I took this snippet from the preivous test swapcontext_test.cc which was already there and did all the optimization levels explicitly. I can check if the test framework already runs all optimization levels by itself.

================
Comment at: test/asan/TestCases/Linux/swapcontext_annotation.cc:67
@@ +66,3 @@
+    perror("swapcontext");
+    _exit(0);
+  }
----------------
dvyukov wrote:
> s/0/1/
> otherwise test can silently break and continue passing on bots
Indeed, though it would be caught anyway because the string "TestX passed" would not appear in output.


http://reviews.llvm.org/D20913





More information about the llvm-commits mailing list