[asan] Fix deadlock in stack unwinder on android/x86.

Fixes PR17116.
Patch by 林作健 (manjian2006 at gmail.com).


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@190590 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h
index 88b7844..a17a7b4 100644
--- a/lib/asan/asan_thread.h
+++ b/lib/asan/asan_thread.h
@@ -87,11 +87,17 @@
     return fake_stack_;
   }
 
+  // True is this thread is currently unwinding stack (i.e. collecting a stack
+  // trace). Used to prevent deadlocks on platforms where libc unwinder calls
+  // malloc internally. See PR17116 for more details.
+  bool isUnwinding() const { return unwinding; }
+  void setUnwinding(bool b) { unwinding = b; }
+
   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
   AsanStats &stats() { return stats_; }
 
  private:
-  AsanThread() {}
+  AsanThread() : unwinding(false) {}
   void SetThreadStackAndTls();
   void ClearShadowForThreadStackAndTLS();
   AsanThreadContext *context_;
@@ -105,6 +111,19 @@
   FakeStack *fake_stack_;
   AsanThreadLocalMallocStorage malloc_storage_;
   AsanStats stats_;
+  bool unwinding;
+};
+
+// 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); }
+
+ private:
+  AsanThread *thread;
 };
 
 struct CreateThreadContextArgs {