[asan] Keep Itanium mangled names in global metadata
The runtime calls `MaybeDemangleGlobalName` for error reporting and
`__cxxabiv1::__cxa_demangle` is called if available, so demanging Itanium
mangled names in global metadata is unnecessary and wastes data size.
Add `MaybeDemangleGlobalName` in ODR violation detection to support demangled
names in a suppressions file. `MaybeDemangleGlobalName` may call
`DemangleCXXABI` and leak memory. Use an internal allocation to prevent lsan
leak (in case there is no fatal asan error).
The debug feature `report_globals=2` prints information for all instrumented
global variables. `MaybeDemangleGlobalName` would be slow, so don't do that.
The output looks like `Added Global[0x56448f092d60]: beg=0x56448fa66d60 size=4/32 name=_ZL13test_global_2`
and I think the mangled name is fine.
Other mangled schemes e.g. Windows (see win-string-literal.ll) remain the
current behavior.
Reviewed By: hctim
Differential Revision: https://reviews.llvm.org/D138095
GitOrigin-RevId: 00be3578e0841dd9abe408e5b4946180de0bf46b
diff --git a/lib/asan/asan_globals.cpp b/lib/asan/asan_globals.cpp
index b780128..69b64dc 100644
--- a/lib/asan/asan_globals.cpp
+++ b/lib/asan/asan_globals.cpp
@@ -148,9 +148,9 @@
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
if (g->odr_indicator == l->g->odr_indicator &&
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
- !IsODRViolationSuppressed(g->name))
- ReportODRViolation(g, FindRegistrationSite(g),
- l->g, FindRegistrationSite(l->g));
+ !IsODRViolationSuppressed(MaybeDemangleGlobalName(g->name)))
+ ReportODRViolation(g, FindRegistrationSite(g), l->g,
+ FindRegistrationSite(l->g));
}
}
@@ -164,7 +164,7 @@
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) &&
- !IsODRViolationSuppressed(g->name))
+ !IsODRViolationSuppressed(MaybeDemangleGlobalName(g->name)))
ReportODRViolation(g, FindRegistrationSite(g),
l->g, FindRegistrationSite(l->g));
}
diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index b223f6c..d505d96 100644
--- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -49,12 +49,17 @@
// FIXME: __cxa_demangle aggressively insists on allocating memory.
// There's not much we can do about that, short of providing our
// own demangler (libc++abi's implementation could be adapted so that
- // it does not allocate). For now, we just call it anyway, and we leak
- // the returned value.
- if (&__cxxabiv1::__cxa_demangle)
- if (const char *demangled_name =
- __cxxabiv1::__cxa_demangle(name, 0, 0, 0))
- return demangled_name;
+ // it does not allocate). For now, we just call it anyway, and use
+ // InternalAlloc to prevent lsan error.
+ if (&__cxxabiv1::__cxa_demangle) {
+ if (char *demangled_name = __cxxabiv1::__cxa_demangle(name, 0, 0, 0)) {
+ size_t size = internal_strlen(demangled_name) + 1;
+ char *buf = (char *)InternalAlloc(size);
+ internal_memcpy(buf, demangled_name, size);
+ free(demangled_name);
+ return buf;
+ }
+ }
return name;
}
diff --git a/test/asan/TestCases/Linux/odr_indicators.cpp b/test/asan/TestCases/Linux/odr_indicators.cpp
index 583f6e6..cef6b99 100644
--- a/test/asan/TestCases/Linux/odr_indicators.cpp
+++ b/test/asan/TestCases/Linux/odr_indicators.cpp
@@ -11,11 +11,11 @@
// 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=_ZL13test_global_2 {{.*}} 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=_ZN12_GLOBAL__N_113test_global_3E {{.*}} odr_indicator={{0xf+$}}
} // namespace
int main() {