[compiler-rt] r221595 - [Sanitizers] Enable stack traces on FreeBSD

Viktor Kutuzov vkutuzov at accesssoftek.com
Mon Nov 10 07:22:04 PST 2014


Author: vkutuzov
Date: Mon Nov 10 09:22:04 2014
New Revision: 221595

URL: http://llvm.org/viewvc/llvm-project?rev=221595&view=rev
Log:
[Sanitizers] Enable stack traces on FreeBSD
Differential Revision: http://reviews.llvm.org/D6086

Modified:
    compiler-rt/trunk/lib/asan/asan_posix.cc
    compiler-rt/trunk/lib/asan/asan_stack.h
    compiler-rt/trunk/lib/asan/asan_thread.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h

Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_posix.cc Mon Nov 10 09:22:04 2014
@@ -33,6 +33,7 @@
 namespace __asan {
 
 void AsanOnSIGSEGV(int, void *siginfo, void *context) {
+  ScopedDeadlySignal signal_scope(GetCurrentThread());
   uptr addr = (uptr)((siginfo_t*)siginfo)->si_addr;
   int code = (int)((siginfo_t*)siginfo)->si_code;
   // Write the first message using the bullet-proof write.

Modified: compiler-rt/trunk/lib/asan/asan_stack.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.h (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.h Mon Nov 10 09:22:04 2014
@@ -35,6 +35,10 @@ void GetStackTraceWithPcBpAndContext(Buf
   stack->size = 0;
   if (LIKELY(asan_inited)) {
     if ((t = GetCurrentThread()) && !t->isUnwinding()) {
+      // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
+      // yields the call stack of the signal's handler and not of the code
+      // that raised the signal (as it does on Linux).
+      if (SANITIZER_FREEBSD && t->isInDeadlySignal()) fast = true;
       uptr stack_top = t->stack_top();
       uptr stack_bottom = t->stack_bottom();
       ScopedUnwinding unwind_scope(t);

Modified: compiler-rt/trunk/lib/asan/asan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.h Mon Nov 10 09:22:04 2014
@@ -108,6 +108,10 @@ class AsanThread {
   bool isUnwinding() const { return unwinding_; }
   void setUnwinding(bool b) { unwinding_ = b; }
 
+  // True if we are in a deadly signal handler.
+  bool isInDeadlySignal() const { return in_deadly_signal_; }
+  void setInDeadlySignal(bool b) { in_deadly_signal_ = b; }
+
   AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
   AsanStats &stats() { return stats_; }
 
@@ -133,6 +137,7 @@ class AsanThread {
   AsanThreadLocalMallocStorage malloc_storage_;
   AsanStats stats_;
   bool unwinding_;
+  bool in_deadly_signal_;
 };
 
 // ScopedUnwinding is a scope for stacktracing member of a context
@@ -145,6 +150,20 @@ class ScopedUnwinding {
 
  private:
   AsanThread *thread;
+};
+
+// ScopedDeadlySignal is a scope for handling deadly signals.
+class ScopedDeadlySignal {
+ public:
+  explicit ScopedDeadlySignal(AsanThread *t) : thread(t) {
+    if (thread) thread->setInDeadlySignal(true);
+  }
+  ~ScopedDeadlySignal() {
+    if (thread) thread->setInDeadlySignal(false);
+  }
+
+ private:
+  AsanThread *thread;
 };
 
 struct CreateThreadContextArgs {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h?rev=221595&r1=221594&r2=221595&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_stacktrace.h Mon Nov 10 09:22:04 2014
@@ -29,6 +29,15 @@ static const uptr kStackTraceMax = 256;
 # define SANITIZER_CAN_FAST_UNWIND 1
 #endif
 
+// Fast unwind is the only option on Mac for now; we will need to
+// revisit this macro when slow unwind works on Mac, see
+// https://code.google.com/p/address-sanitizer/issues/detail?id=137
+#if SANITIZER_MAC
+# define SANITIZER_CAN_SLOW_UNWIND 0
+#else
+# define SANITIZER_CAN_SLOW_UNWIND 1
+#endif
+
 struct StackTrace {
   const uptr *trace;
   uptr size;
@@ -40,13 +49,9 @@ struct StackTrace {
   void Print() const;
 
   static bool WillUseFastUnwind(bool request_fast_unwind) {
-    // Check if fast unwind is available. Fast unwind is the only option on Mac.
-    // It is also the only option on FreeBSD as the slow unwinding that
-    // leverages _Unwind_Backtrace() yields the call stack of the signal's
-    // handler and not of the code that raised the signal (as it does on Linux).
     if (!SANITIZER_CAN_FAST_UNWIND)
       return false;
-    else if (SANITIZER_MAC != 0 || SANITIZER_FREEBSD != 0)
+    else if (!SANITIZER_CAN_SLOW_UNWIND)
       return true;
     return request_fast_unwind;
   }





More information about the llvm-commits mailing list