[compiler-rt] r211343 - [asan] when reporting an ODR violation, also print the stack traces where the globals have been registered (thus show the name of shared library or exe to which the global belongs). The reports become a bit too verbose but I do not see any *simple* way to make them more compact. This should be especially helpful when the ODR happens because the same .cc file is used twice in the project in differend DSOs

Kostya Serebryany kcc at google.com
Fri Jun 20 01:24:13 PDT 2014


Author: kcc
Date: Fri Jun 20 03:24:12 2014
New Revision: 211343

URL: http://llvm.org/viewvc/llvm-project?rev=211343&view=rev
Log:
[asan] when reporting an ODR violation, also print the stack traces where the globals have been registered (thus show the name of shared library or exe to which the global belongs). The reports become a bit too verbose but I do not see any *simple* way to make them more compact. This should be especially helpful when the ODR happens because the same .cc file is used twice in the project in differend DSOs

Modified:
    compiler-rt/trunk/lib/asan/asan_globals.cc
    compiler-rt/trunk/lib/asan/asan_report.cc
    compiler-rt/trunk/lib/asan/asan_report.h
    compiler-rt/trunk/test/asan/TestCases/Linux/odr-violation.cc

Modified: compiler-rt/trunk/lib/asan/asan_globals.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_globals.cc?rev=211343&r1=211342&r2=211343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_globals.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_globals.cc Fri Jun 20 03:24:12 2014
@@ -22,6 +22,7 @@
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_mutex.h"
 #include "sanitizer_common/sanitizer_placement_new.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
 
 namespace __asan {
 
@@ -45,6 +46,14 @@ typedef InternalMmapVector<DynInitGlobal
 // Lazy-initialized and never deleted.
 static VectorOfGlobals *dynamic_init_globals;
 
+// We want to remember where a certain range of globals was registered.
+struct GlobalRegistrationSite {
+  u32 stack_id;
+  Global *g_first, *g_last;
+};
+typedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;
+static GlobalRegistrationSiteVector *global_registration_site_vector;
+
 ALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {
   FastPoisonShadow(g->beg, g->size_with_redzone, value);
 }
@@ -63,8 +72,8 @@ ALWAYS_INLINE void PoisonRedZones(const
 }
 
 static void ReportGlobal(const Global &g, const char *prefix) {
-  Report("%s Global: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
-         prefix, (void*)g.beg, g.size, g.size_with_redzone, g.name,
+  Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
+         prefix, &g, (void*)g.beg, g.size, g.size_with_redzone, g.name,
          g.module_name, g.has_dynamic_init);
 }
 
@@ -81,6 +90,16 @@ bool DescribeAddressIfGlobal(uptr addr,
   return res;
 }
 
+u32 FindRegistrationSite(const Global *g) {
+  CHECK(global_registration_site_vector);
+  for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
+    GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
+    if (g >= grs.g_first && g <= grs.g_last)
+      return grs.stack_id;
+  }
+  return 0;
+}
+
 // Register a global variable.
 // This function may be called more than once for every global
 // so we store the globals in a map.
@@ -101,7 +120,8 @@ static void RegisterGlobal(const Global
       for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
         if (g->beg == l->g->beg &&
             (flags()->detect_odr_violation >= 2 || g->size != l->g->size))
-          ReportODRViolation(g, l->g);
+          ReportODRViolation(g, FindRegistrationSite(g),
+                             l->g, FindRegistrationSite(l->g));
       }
     }
   }
@@ -157,7 +177,18 @@ using namespace __asan;  // NOLINT
 // Register an array of globals.
 void __asan_register_globals(__asan_global *globals, uptr n) {
   if (!flags()->report_globals) return;
+  GET_STACK_TRACE_FATAL_HERE;
+  u32 stack_id = StackDepotPut(stack.trace, stack.size);
   BlockingMutexLock lock(&mu_for_globals);
+  if (!global_registration_site_vector)
+    global_registration_site_vector =
+        new(allocator_for_globals) GlobalRegistrationSiteVector(128);
+  GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]};
+  global_registration_site_vector->push_back(site);
+  if (flags()->report_globals >= 2) {
+    PRINT_CURRENT_STACK();
+    Printf("=== ID %d; %p %p\n", stack_id, &globals[0], &globals[n - 1]);
+  }
   for (uptr i = 0; i < n; i++) {
     RegisterGlobal(&globals[i]);
   }

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=211343&r1=211342&r2=211343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Fri Jun 20 03:24:12 2014
@@ -735,7 +735,8 @@ void ReportBadParamsToAnnotateContiguous
   ReportErrorSummary("bad-__sanitizer_annotate_contiguous_container", stack);
 }
 
-void ReportODRViolation(const __asan_global *g1, const __asan_global *g2) {
+void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
+                        const __asan_global *g2, u32 stack_id2) {
   ScopedInErrorReport in_report;
   Decorator d;
   Printf("%s", d.Warning());
@@ -743,6 +744,16 @@ void ReportODRViolation(const __asan_glo
   Printf("%s", d.EndWarning());
   Printf("  [1] size=%zd %s %s\n", g1->size, g1->name, g1->module_name);
   Printf("  [2] size=%zd %s %s\n", g2->size, g2->name, g2->module_name);
+  if (stack_id1 && stack_id2) {
+    Printf("These globals were registered at these points:\n");
+    Printf("  [1]:\n");
+    uptr stack_size;
+    const uptr *stack_trace = StackDepotGet(stack_id1, &stack_size);
+    StackTrace::PrintStack(stack_trace, stack_size);
+    Printf("  [2]:\n");
+    stack_trace = StackDepotGet(stack_id2, &stack_size);
+    StackTrace::PrintStack(stack_trace, stack_size);
+  }
   Report("HINT: if you don't care about these warnings you may set "
          "ASAN_OPTIONS=detect_odr_violation=0\n");
   ReportErrorSummary("odr-violation", g1->module_name, 0, g1->name);

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=211343&r1=211342&r2=211343&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Fri Jun 20 03:24:12 2014
@@ -55,7 +55,8 @@ ReportBadParamsToAnnotateContiguousConta
                                              uptr new_mid, StackTrace *stack);
 
 void NORETURN
-ReportODRViolation(const __asan_global *g1, const __asan_global *g2);
+ReportODRViolation(const __asan_global *g1, u32 stack_id1,
+                   const __asan_global *g2, u32 stack_id2);
 
 // Mac-specific errors and warnings.
 void WarnMacFreeUnallocated(

Modified: compiler-rt/trunk/test/asan/TestCases/Linux/odr-violation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/odr-violation.cc?rev=211343&r1=211342&r2=211343&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/odr-violation.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/odr-violation.cc Fri Jun 20 03:24:12 2014
@@ -2,18 +2,18 @@
 // XFAIL: android
 //
 // Different size: detect a bug if detect_odr_violation>=1
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so
-// RUN: %clangxx_asan %s %t.so -Wl,-R. -o %t
-// RUN: ASAN_OPTIONS=detect_odr_violation=1 not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t 2>&1 | FileCheck %s
-// RUN: ASAN_OPTIONS=detect_odr_violation=0     %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN:                                     not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so
+// RUN: %clangxx_asan %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: ASAN_OPTIONS=detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN: ASAN_OPTIONS=detect_odr_violation=0     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN:                                     not %run %t-ODR-EXE 2>&1 | FileCheck %s
 //
 // Same size: report a bug only if detect_odr_violation>=2.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -DSZ=100
-// RUN: ASAN_OPTIONS=detect_odr_violation=1     %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
-// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t 2>&1 | FileCheck %s
-// RUN:                                     not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so -DSZ=100
+// RUN: ASAN_OPTIONS=detect_odr_violation=1     %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
+// RUN:                                     not %run %t-ODR-EXE 2>&1 | FileCheck %s
 
 // GNU driver doesn't handle .so files properly.
 // REQUIRES: Clang
@@ -34,4 +34,8 @@ int main(int argc, char **argv) {
 
 // CHECK: ERROR: AddressSanitizer: odr-violation
 // CHECK: size=100 G
+// CHECK: size={{4|100}} G
+// CHECK: These globals were registered at these points:
+// CHECK: ODR-EXE
+// CHECK: ODR-SO
 // DISABLED: PASS





More information about the llvm-commits mailing list