[compiler-rt] [asan] Report executable/DSO name for report_globals=2 and odr-violation checking (PR #71879)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 15:51:29 PST 2023


https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/71879

For an odr-violation error due to a source file linked into two DSOs, or
one DSO and the main executable, it can be difficult to identify the DSO
name. Let's print the module name in the error report.

```
echo 'extern long var; int main() { return var; }' > a.cc
echo 'long var;' > b.cc
clang++ -fpic -fsanitize=address -shared b.cc -o b.so
clang++ -fsanitize=address a.cc b.cc ./b.so -o a
```

w/o this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
  [1] size=8 'var' b.cc
  [2] size=8 'var' b.cc
...
```
w/ this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
  [1] size=8 'var' b.cc in /tmp/c/a
  [2] size=8 'var' b.cc in ./b.so
```

In addition, update the `report_globals=2` message to include the module
name
```
==1451005==Added Global[0x7fcfe59ae040]: beg=0x7fcfe59ae140 size=8/32 name=var source=b.cc module=./b.so dyn_init=0 odr_indicator=0x55754f939260
```


>From ddb807b4a14022f87482680335ca628d7bbd01fc Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Thu, 9 Nov 2023 15:17:25 -0800
Subject: [PATCH] [asan] Report executable/DSO name for report_globals=2 and
 odr-violation checking

For an odr-violation error due to a source file linked into two DSOs, or
one DSO and the main executable, it can be difficult to identify the DSO
name. Let's print the module name in the error report.

```
echo 'extern long var; int main() { return var; }' > a.cc
echo 'long var;' > b.cc
clang++ -fpic -fsanitize=address -shared b.cc -o b.so
clang++ -fsanitize=address a.cc b.cc ./b.so -o a
```

w/o this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
  [1] size=8 'var' b.cc
  [2] size=8 'var' b.cc
...
```
w/ this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
  [1] size=8 'var' b.cc in /tmp/c/a
  [2] size=8 'var' b.cc in ./b.so
```

In addition, update the `report_globals=2` message to include the module
name
```
==1451005==Added Global[0x7fcfe59ae040]: beg=0x7fcfe59ae140 size=8/32 name=var source=b.cc module=./b.so dyn_init=0 odr_indicator=0x55754f939260
```
---
 compiler-rt/lib/asan/asan_descriptions.cpp         |  2 +-
 compiler-rt/lib/asan/asan_errors.cpp               |  4 ++--
 compiler-rt/lib/asan/asan_globals.cpp              | 14 +++++++++-----
 compiler-rt/lib/asan/asan_report.h                 |  2 +-
 .../test/asan/TestCases/Linux/odr-violation.cpp    |  2 +-
 .../test/asan/TestCases/Linux/odr_indicators.cpp   |  6 +++---
 6 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp
index 5f3d15bcc9e2b0b..ef6f3e0a096f828 100644
--- a/compiler-rt/lib/asan/asan_descriptions.cpp
+++ b/compiler-rt/lib/asan/asan_descriptions.cpp
@@ -291,7 +291,7 @@ static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
   }
   str.AppendF(" global variable '%s' defined in '",
               MaybeDemangleGlobalName(g.name));
-  PrintGlobalLocation(&str, g);
+  PrintGlobalLocation(&str, g, /*print_module_name=*/false);
   str.AppendF("' (0x%zx) of size %zu\n", g.beg, g.size);
   str.Append(d.Default());
   PrintGlobalNameIfASCII(&str, g);
diff --git a/compiler-rt/lib/asan/asan_errors.cpp b/compiler-rt/lib/asan/asan_errors.cpp
index 49f5b38c3338f61..3f2d13e3146406d 100644
--- a/compiler-rt/lib/asan/asan_errors.cpp
+++ b/compiler-rt/lib/asan/asan_errors.cpp
@@ -362,8 +362,8 @@ void ErrorODRViolation::Print() {
   Printf("%s", d.Default());
   InternalScopedString g1_loc;
   InternalScopedString g2_loc;
-  PrintGlobalLocation(&g1_loc, global1);
-  PrintGlobalLocation(&g2_loc, global2);
+  PrintGlobalLocation(&g1_loc, global1, /*print_module_name=*/true);
+  PrintGlobalLocation(&g2_loc, global2, /*print_module_name=*/true);
   Printf("  [1] size=%zd '%s' %s\n", global1.size,
          MaybeDemangleGlobalName(global1.name), g1_loc.data());
   Printf("  [2] size=%zd '%s' %s\n", global2.size,
diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index 14c36bdc8e64296..1923d23c4200258 100644
--- a/compiler-rt/lib/asan/asan_globals.cpp
+++ b/compiler-rt/lib/asan/asan_globals.cpp
@@ -80,14 +80,16 @@ static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
 }
 
 static void ReportGlobal(const Global &g, const char *prefix) {
+  DataInfo info;
+  bool symbolized = Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info);
   Report(
-      "%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu "
+      "%s Global[%p]: beg=%p size=%zu/%zu name=%s source=%s module=%s "
+      "dyn_init=%zu "
       "odr_indicator=%p\n",
       prefix, (void *)&g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
-      g.module_name, g.has_dynamic_init, (void *)g.odr_indicator);
+      g.module_name, info.module, g.has_dynamic_init, (void *)g.odr_indicator);
 
-  DataInfo info;
-  if (Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info) && info.line != 0) {
+  if (symbolized && info.line != 0) {
     Report("  location: name=%s, %d\n", info.file, static_cast<int>(info.line));
   } else if (g.gcc_location != 0) {
     // Fallback to Global::gcc_location
@@ -297,7 +299,7 @@ void PrintGlobalNameIfASCII(InternalScopedString *str, const __asan_global &g) {
                (char *)g.beg);
 }
 
-void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) {
+void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g, bool print_module_name) {
   DataInfo info;
   if (Symbolizer::GetOrInit()->SymbolizeData(g.beg, &info) && info.line != 0) {
     str->AppendF("%s:%d", info.file, static_cast<int>(info.line));
@@ -312,6 +314,8 @@ void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) {
   } else {
     str->AppendF("%s", g.module_name);
   }
+  if (print_module_name && info.module)
+    str->AppendF(" in %s", info.module);
 }
 
 } // namespace __asan
diff --git a/compiler-rt/lib/asan/asan_report.h b/compiler-rt/lib/asan/asan_report.h
index 248e30dd42bdc72..e1d9770369fbfdb 100644
--- a/compiler-rt/lib/asan/asan_report.h
+++ b/compiler-rt/lib/asan/asan_report.h
@@ -35,7 +35,7 @@ int GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,
 
 const char *MaybeDemangleGlobalName(const char *name);
 void PrintGlobalNameIfASCII(InternalScopedString *str, const __asan_global &g);
-void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g);
+void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g, bool print_module_name);
 
 void PrintMemoryByte(InternalScopedString *str, const char *before, u8 byte,
                      bool in_shadow, const char *after = "\n");
diff --git a/compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp b/compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
index 017aa4e12ce4800..b16f42cfa125d5f 100644
--- a/compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
+++ b/compiler-rt/test/asan/TestCases/Linux/odr-violation.cpp
@@ -58,7 +58,7 @@ namespace foo { char G[SZ]; }
 #include <stdio.h>
 namespace foo { char G[100]; }
 // CHECK: ERROR: AddressSanitizer: odr-violation
-// CHECK: size=100 'foo::G' {{.*}}odr-violation.cpp:[[@LINE-2]]
+// CHECK: size=100 'foo::G' {{.*}}odr-violation.cpp:[[@LINE-2]] in {{.*}}.tmp-ODR-EXE
 // CHECK: size={{4|100}} 'foo::G'
 int main(int argc, char **argv) {
   printf("PASS: %p\n", &foo::G);
diff --git a/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp
index 583f6e662fda864..8af3ec09be78c4f 100644
--- a/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp
+++ b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp
@@ -11,16 +11,16 @@ int test_global_1;
 // INDICATOR1-DAG: Added Global{{.*}} name=test_global_1{{.*}} odr_indicator={{0x0*[^0]+.*$}}
 
 static int test_global_2;
-// CHECK-DAG: Added Global{{.*}} name=test_global_2{{.*}} odr_indicator={{0xf+$}}
+// CHECK-DAG: Added Global{{.*}} name=test_global_2{{.*}} source={{.*}} module={{.*}}.cpp.tmp {{.*}} odr_indicator={{0xf+$}}
 
 namespace {
 static int test_global_3;
-// CHECK-DAG: Added Global{{.*}} name={{.*}}::test_global_3{{.*}} odr_indicator={{0xf+$}}
+// CHECK-DAG: Added Global{{.*}} name={{.*}}::test_global_3{{.*}} source={{.*}} module={{.*}}.cpp.tmp {{.*}} odr_indicator={{0xf+$}}
 } // namespace
 
 int main() {
   const char f[] = "%d %d %d\n";
-  // CHECK-DAG: Added Global{{.*}} name=__const.main.f{{.*}} odr_indicator={{0xf+$}}
+  // CHECK-DAG: Added Global{{.*}} name=__const.main.f{{.*}} source={{.*}} module={{.*}}.cpp.tmp {{.*}} odr_indicator={{0xf+$}}
   printf(f, test_global_1, test_global_2, test_global_3);
   return 0;
 }



More information about the llvm-commits mailing list