[llvm-commits] [compiler-rt] r163200 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc asan_flags.h asan_report.cc asan_report.h asan_rtl.cc asan_thread.h lit_tests/deep_thread_stack.cc

Alexey Samsonov samsonov at google.com
Wed Sep 5 00:37:15 PDT 2012


Author: samsonov
Date: Wed Sep  5 02:37:15 2012
New Revision: 163200

URL: http://llvm.org/viewvc/llvm-project?rev=163200&view=rev
Log:
[ASan] Add print_full_thread_history runtime option (on by default) that prints all full thread creation paths for threads involved in ASan error report

Added:
    compiler-rt/trunk/lib/asan/lit_tests/deep_thread_stack.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.cc
    compiler-rt/trunk/lib/asan/asan_flags.h
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/asan/asan_report.h
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_thread.h

Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Wed Sep  5 02:37:15 2012
@@ -609,14 +609,14 @@
                alloc_thread->tid());
 
     PrintStack(&alloc_stack);
-    t->summary()->Announce();
-    free_thread->Announce();
-    alloc_thread->Announce();
+    DescribeThread(t->summary());
+    DescribeThread(free_thread);
+    DescribeThread(alloc_thread);
   } else {
     Printf("allocated by thread T%d here:\n", alloc_thread->tid());
     PrintStack(&alloc_stack);
-    t->summary()->Announce();
-    alloc_thread->Announce();
+    DescribeThread(t->summary());
+    DescribeThread(alloc_thread);
   }
 }
 

Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Wed Sep  5 02:37:15 2012
@@ -89,6 +89,10 @@
   bool allow_reexec;
   // Strips this prefix from file paths in error reports.
   const char *strip_path_prefix;
+  // If set, prints not only thread creation stacks for threads in error report,
+  // but also thread creation stacks for threads that created those threads,
+  // etc. up to main thread.
+  bool print_full_thread_history;
 };
 
 Flags *flags();

Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Wed Sep  5 02:37:15 2012
@@ -184,7 +184,7 @@
   Printf("HINT: this may be a false positive if your program uses "
              "some custom stack unwind mechanism\n"
              "      (longjmp and C++ exceptions *are* supported)\n");
-  t->summary()->Announce();
+  DescribeThread(t->summary());
   return true;
 }
 
@@ -201,6 +201,26 @@
   DescribeHeapAddress(addr, access_size);
 }
 
+// ------------------- Thread description -------------------- {{{1
+
+void DescribeThread(AsanThreadSummary *summary) {
+  CHECK(summary);
+  // No need to announce the main thread.
+  if (summary->tid() == 0 || summary->announced()) {
+    return;
+  }
+  summary->set_announced(true);
+  Printf("Thread T%d created by T%d here:\n",
+         summary->tid(), summary->parent_tid());
+  PrintStack(summary->stack());
+  // Recursively described parent thread if needed.
+  if (flags()->print_full_thread_history) {
+    AsanThreadSummary *parent_summary =
+        asanThreadRegistry().FindByTid(summary->parent_tid());
+    DescribeThread(parent_summary);
+  }
+}
+
 // -------------------- Different kinds of reports ----------------- {{{1
 
 // Use ScopedInErrorReport to run common actions just before and
@@ -238,7 +258,7 @@
     // Make sure the current thread is announced.
     AsanThread *curr_thread = asanThreadRegistry().GetCurrent();
     if (curr_thread) {
-      curr_thread->summary()->Announce();
+      DescribeThread(curr_thread->summary());
     }
     // Print memory stats.
     __asan_print_accumulated_stats();

Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Wed Sep  5 02:37:15 2012
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "asan_internal.h"
+#include "asan_thread.h"
 #include "sanitizer/asan_interface.h"
 
 namespace __asan {
@@ -27,6 +28,8 @@
 // Determines memory type on its own.
 void DescribeAddress(uptr addr, uptr access_size);
 
+void DescribeThread(AsanThreadSummary *summary);
+
 // Different kinds of error reports.
 void NORETURN ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr);
 void NORETURN ReportDoubleFree(uptr addr, StackTrace *stack);

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Sep  5 02:37:15 2012
@@ -102,6 +102,7 @@
   ParseFlag(str, &f->disable_core, "disable_core");
   ParseFlag(str, &f->strip_path_prefix, "strip_path_prefix");
   ParseFlag(str, &f->allow_reexec, "allow_reexec");
+  ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history");
 }
 
 extern "C" {
@@ -139,6 +140,7 @@
   f->disable_core = (__WORDSIZE == 64);
   f->strip_path_prefix = "";
   f->allow_reexec = true;
+  f->print_full_thread_history = true;
 
   // Override from user-specified string.
   ParseFlagsFromString(f, __asan_default_options());

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=163200&r1=163199&r2=163200&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_thread.h (original)
+++ compiler-rt/trunk/lib/asan/asan_thread.h Wed Sep  5 02:37:15 2012
@@ -40,16 +40,12 @@
     }
     thread_ = 0;
   }
-  void Announce() {
-    if (tid_ == 0) return;  // no need to announce the main thread.
-    if (!announced_) {
-      announced_ = true;
-      Printf("Thread T%d created by T%d here:\n", tid_, parent_tid_);
-      PrintStack(&stack_);
-    }
-  }
   u32 tid() { return tid_; }
   void set_tid(u32 tid) { tid_ = tid; }
+  u32 parent_tid() { return parent_tid_; }
+  bool announced() { return announced_; }
+  void set_announced(bool announced) { announced_ = announced; }
+  StackTrace *stack() { return &stack_; }
   AsanThread *thread() { return thread_; }
   void set_thread(AsanThread *thread) { thread_ = thread; }
   static void TSDDtor(void *tsd);

Added: compiler-rt/trunk/lib/asan/lit_tests/deep_thread_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/deep_thread_stack.cc?rev=163200&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/deep_thread_stack.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/deep_thread_stack.cc Wed Sep  5 02:37:15 2012
@@ -0,0 +1,61 @@
+// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s
+
+#include <pthread.h>
+
+int *x;
+
+void *AllocThread(void *arg) {
+  x = new int;
+  *x = 42;
+  return NULL;
+}
+
+void *FreeThread(void *arg) {
+  delete x;
+  return NULL;
+}
+
+void *AccessThread(void *arg) {
+  *x = 43;  // BOOM
+  return NULL;
+}
+
+typedef void* (*callback_type)(void* arg);
+
+void *RunnerThread(void *function) {
+  pthread_t thread;
+  pthread_create(&thread, NULL, (callback_type)function, NULL);
+  pthread_join(thread, NULL);
+  return NULL;
+}
+
+void RunThread(callback_type function) {
+  pthread_t runner;
+  pthread_create(&runner, NULL, RunnerThread, (void*)function);
+  pthread_join(runner, NULL);
+}
+
+int main(int argc, char *argv[]) {
+  RunThread(AllocThread);
+  RunThread(FreeThread);
+  RunThread(AccessThread);
+  return (x != 0);
+}
+
+// CHECK: AddressSanitizer heap-use-after-free
+// CHECK: WRITE of size 4 at 0x{{.*}} thread T[[ACCESS_THREAD:[0-9]+]]
+// CHECK: freed by thread T[[FREE_THREAD:[0-9]+]] here:
+// CHECK: previously allocated by thread T[[ALLOC_THREAD:[0-9]+]] here:
+// CHECK: Thread T[[ACCESS_THREAD]] created by T[[ACCESS_RUNNER:[0-9]+]] here:
+// CHECK: Thread T[[ACCESS_RUNNER]] created by T0 here:
+// CHECK: Thread T[[FREE_THREAD]] created by T[[FREE_RUNNER:[0-9]+]] here:
+// CHECK: Thread T[[FREE_RUNNER]] created by T0 here:
+// CHECK: Thread T[[ALLOC_THREAD]] created by T[[ALLOC_RUNNER:[0-9]+]] here:
+// CHECK: Thread T[[ALLOC_RUNNER]] created by T0 here:





More information about the llvm-commits mailing list