[compiler-rt] r197026 - [msan] Get stack limits with pthread_create interceptor.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Dec 11 02:55:42 PST 2013


Author: eugenis
Date: Wed Dec 11 04:55:42 2013
New Revision: 197026

URL: http://llvm.org/viewvc/llvm-project?rev=197026&view=rev
Log:
[msan] Get stack limits with pthread_create interceptor.

Before we did it lazily on the first stack unwind in the thread.
It resulted in deadlock when the unwind was caused by memory allocation
inside pthread_getattr_np:
  pthread_getattr_np   <<< not reentable
  GetThreadStackTopAndBottom
  __interceptor_realloc
  pthread_getattr_np
  

Added:
    compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc   (with props)
Modified:
    compiler-rt/trunk/lib/msan/msan.cc
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

Added: compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc?rev=197026&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc Wed Dec 11 04:55:42 2013
@@ -0,0 +1,22 @@
+// RUN: %clangxx_msan -m64 -fsanitize-memory-track-origins -O0 %s -o %t && %t
+
+// Regression test for a deadlock in pthread_getattr_np
+
+#include <assert.h>
+#include <pthread.h>
+
+void *ThreadFn(void *) {
+  pthread_attr_t attr;
+  int res = pthread_getattr_np(pthread_self(), &attr);
+  assert(!res);
+  return 0;
+}
+
+int main(void) {
+  pthread_t t;
+  int res = pthread_create(&t, 0, ThreadFn, 0);
+  assert(!res);
+  res = pthread_join(t, 0);
+  assert(!res);
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/msan/lit_tests/pthread_getattr_np_deadlock.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=197026&r1=197025&r2=197026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Wed Dec 11 04:55:42 2013
@@ -59,9 +59,7 @@ THREADLOCAL u64 __msan_va_arg_overflow_s
 SANITIZER_INTERFACE_ATTRIBUTE
 THREADLOCAL u32 __msan_origin_tls;
 
-static THREADLOCAL struct {
-  uptr stack_top, stack_bottom;
-} __msan_stack_bounds;
+THREADLOCAL MsanStackBounds msan_stack_bounds;
 
 static THREADLOCAL int is_in_symbolizer;
 static THREADLOCAL int is_in_loader;
@@ -168,19 +166,6 @@ static void InitializeFlags(Flags *f, co
   ParseFlagsFromString(f, options);
 }
 
-static void GetCurrentStackBounds(uptr *stack_top, uptr *stack_bottom) {
-  if (__msan_stack_bounds.stack_top == 0) {
-    // Break recursion (GetStackTrace -> GetThreadStackTopAndBottom ->
-    // realloc -> GetStackTrace).
-    __msan_stack_bounds.stack_top = __msan_stack_bounds.stack_bottom = 1;
-    GetThreadStackTopAndBottom(/* at_initialization */false,
-                               &__msan_stack_bounds.stack_top,
-                               &__msan_stack_bounds.stack_bottom);
-  }
-  *stack_top = __msan_stack_bounds.stack_top;
-  *stack_bottom = __msan_stack_bounds.stack_bottom;
-}
-
 void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp,
                    bool request_fast_unwind) {
   if (!StackTrace::WillUseFastUnwind(request_fast_unwind)) {
@@ -188,9 +173,8 @@ void GetStackTrace(StackTrace *stack, up
     SymbolizerScope sym_scope;
     return stack->Unwind(max_s, pc, bp, 0, 0, request_fast_unwind);
   }
-  uptr stack_top, stack_bottom;
-  GetCurrentStackBounds(&stack_top, &stack_bottom);
-  stack->Unwind(max_s, pc, bp, stack_top, stack_bottom, request_fast_unwind);
+  stack->Unwind(max_s, pc, bp, msan_stack_bounds.stack_top,
+                msan_stack_bounds.stack_bottom, request_fast_unwind);
 }
 
 void PrintWarning(uptr pc, uptr bp) {
@@ -340,9 +324,9 @@ void __msan_init() {
   }
   Symbolizer::Get()->AddHooks(EnterSymbolizer, ExitSymbolizer);
 
-  GetThreadStackTopAndBottom(/* at_initialization */true,
-                             &__msan_stack_bounds.stack_top,
-                             &__msan_stack_bounds.stack_bottom);
+  GetThreadStackTopAndBottom(/* at_initialization */ true,
+                             &msan_stack_bounds.stack_top,
+                             &msan_stack_bounds.stack_bottom);
   VPrintf(1, "MemorySanitizer init done\n");
   msan_init_is_running = 0;
   msan_inited = 1;

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=197026&r1=197025&r2=197026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Wed Dec 11 04:55:42 2013
@@ -106,4 +106,10 @@ class ScopedThreadLocalStateBackup {
 #define MSAN_FREE_HOOK(ptr) \
   if (&__msan_free_hook) __msan_free_hook(ptr)
 
+struct MsanStackBounds {
+  uptr stack_top, stack_bottom;
+};
+
+extern THREADLOCAL MsanStackBounds msan_stack_bounds;
+
 #endif  // MSAN_H

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=197026&r1=197025&r2=197026&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed Dec 11 04:55:42 2013
@@ -1088,6 +1088,10 @@ static void *MsanThreadStartFunc(void *a
     Die();
   }
   atomic_store(&p->done, 1, memory_order_release);
+
+  GetThreadStackTopAndBottom(/* at_initialization */ false,
+                             &msan_stack_bounds.stack_top,
+                             &msan_stack_bounds.stack_bottom);
   return callback(param);
 }
 





More information about the llvm-commits mailing list