diff options
| -rw-r--r-- | compiler-rt/lib/asan/asan_stack.cc | 25 | 
1 files changed, 19 insertions, 6 deletions
diff --git a/compiler-rt/lib/asan/asan_stack.cc b/compiler-rt/lib/asan/asan_stack.cc index f5a8e813b99..dde8f7f0e08 100644 --- a/compiler-rt/lib/asan/asan_stack.cc +++ b/compiler-rt/lib/asan/asan_stack.cc @@ -31,11 +31,22 @@ namespace {  // ScopedUnwinding is a scope for stacktracing member of a context  class ScopedUnwinding {   public: -  explicit ScopedUnwinding(AsanThread *t) : thread(t) { t->setUnwinding(true); } -  ~ScopedUnwinding() { thread->setUnwinding(false); } +  explicit ScopedUnwinding(AsanThread *t) : thread(t) { +    if (thread) { +      can_unwind = !thread->isUnwinding(); +      thread->setUnwinding(true); +    } +  } +  ~ScopedUnwinding() { +    if (thread) +      thread->setUnwinding(false); +  } + +  bool CanUnwind() const { return can_unwind; }   private: -  AsanThread *thread; +  AsanThread *thread = nullptr; +  bool can_unwind = true;  };  }  // namespace @@ -52,6 +63,9 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(    Unwind(max_depth, pc, bp, context, 0, 0, false);  #else    AsanThread *t = GetCurrentThread(); +  ScopedUnwinding unwind_scope(t); +  if (!unwind_scope.CanUnwind()) +    return;    if (!t) {      if (!request_fast) {        /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ @@ -59,11 +73,10 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(      }      return;    } -  if (t->isUnwinding()) -    return; +    uptr stack_top = t->stack_top();    uptr stack_bottom = t->stack_bottom(); -  ScopedUnwinding unwind_scope(t); +    if (SANITIZER_MIPS && !IsValidFrame(bp, stack_top, stack_bottom))      return;    if (StackTrace::WillUseFastUnwind(request_fast))  | 

