This is an archive of the discontinued LLVM Phabricator instance.

[asan] Keep Itanium mangled names in global metadata
ClosedPublic

Authored by MaskRay on Nov 15 2022, 11:22 PM.

Details

Summary

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.

Diff Detail

Event Timeline

MaskRay created this revision.Nov 15 2022, 11:22 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 15 2022, 11:22 PM
MaskRay requested review of this revision.Nov 15 2022, 11:22 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptNov 15 2022, 11:22 PM
MaskRay updated this revision to Diff 475711.Nov 16 2022, 12:32 AM

always keep original name for __odr_gen_asan_

hctim accepted this revision as: hctim.Nov 16 2022, 10:37 AM

couple nits, otherwise lgtm

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
49–62

Can you maybe update this entire fixme?

Looks like all the current callers would be tolerant to a function-local static buffer, but this feels like a gunfoot, so I guess we'll continue to leak the memory, unless you also want to go ahead and create an InternalAlloc-RAII-wrapper class and patch up the callers.

FIXME: This pointer currently leaks in the callers, but we specifically copy the demangled contents into an InternalAlloc so that LSan doesn't see a leak from the malloc() done by cxa_demangle.

55

nit: if you're here, can you change these parameters to nullptr?

This revision is now accepted and ready to land.Nov 16 2022, 10:37 AM
MaskRay updated this revision to Diff 475882.Nov 16 2022, 11:22 AM
MaskRay marked 2 inline comments as done.

address comments

Thanks for the comment suggestion!

Huh, fascinating - so we used the unmangled name as a symbol name, punctuation, spaces, and all?

(interesting to know that sanitizers end up with their own copies of mangled names too - another thing we could consider deduplicating/maybe sharing with some debug info/symbol table reductions at some point (I guess if we just simplify mangled names enough - use hashes, etc, this'd fall out naturally for the sanitizers (though all demanglers would need to have access to some side table of hash->mangled name table, which I guess sanitizers need at runtime, so couldn't be dropped during linking (previously had considered this strategy since the linker would need to produce good diagnostics - but I guess runtime symbolizers need useful symbol names too, etc)))

Huh, fascinating - so we used the unmangled name as a symbol name, punctuation, spaces, and all?

(interesting to know that sanitizers end up with their own copies of mangled names too - another thing we could consider deduplicating/maybe sharing with some debug info/symbol table reductions at some point (I guess if we just simplify mangled names enough - use hashes, etc, this'd fall out naturally for the sanitizers (though all demanglers would need to have access to some side table of hash->mangled name table, which I guess sanitizers need at runtime, so couldn't be dropped during linking (previously had considered this strategy since the linker would need to produce good diagnostics - but I guess runtime symbolizers need useful symbol names too, etc)))

nice triple-nested parenthetical thought!

yes - this is a room for opportunity :). i think the major thing that would need to happen is for llvm-symbolizer to be able to symbolize an address half way through a GV (although it may be possible to find the start pointer using the sanitizer metadata).

MaskRay added a comment.EditedNov 16 2022, 12:34 PM

Huh, fascinating - so we used the unmangled name as a symbol name, punctuation, spaces, and all?

(interesting to know that sanitizers end up with their own copies of mangled names too - another thing we could consider deduplicating/maybe sharing with some debug info/symbol table reductions at some point (I guess if we just simplify mangled names enough - use hashes, etc, this'd fall out naturally for the sanitizers (though all demanglers would need to have access to some side table of hash->mangled name table, which I guess sanitizers need at runtime, so couldn't be dropped during linking (previously had considered this strategy since the linker would need to produce good diagnostics - but I guess runtime symbolizers need useful symbol names too, etc)))

nice triple-nested parenthetical thought!

yes - this is a room for opportunity :). i think the major thing that would need to happen is for llvm-symbolizer to be able to symbolize an address half way through a GV (although it may be possible to find the start pointer using the sanitizer metadata).

Yes, definitely room for improvement. The instrumentation - runtime protocol is more private than DWARF debug information (which has more consumers and therefore has more restriction on things like string table usage.)
In some operating systems that adopt .ctf, I think .ctf just reuses the ELF symbol table .symtab and .strtab, resulting in some saving. (This is some work going on in binutils, but I don't actively keep an eye on it.)

The compression+hash idea has been deployed elsewhere in llvm-project.
In instrumentaiton-based PGO, __llvm_prf_nm uses compressed content with hashes indexing into it. If asan is happy with requiring a non-SHF_ALLOC section for symbolization: we can use a generalized --compress-debug-sections= : https://sourceware.org/bugzilla/show_bug.cgi?id=27452

This revision was landed with ongoing or failed builds.Nov 18 2022, 5:06 PM
This revision was automatically updated to reflect the committed changes.
gulfem added a subscriber: gulfem.Nov 21 2022, 11:00 AM

We started seeing the following test failures.

Failed Tests (8):
  AddressSanitizer-x86_64-linux :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location.cpp

https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8797107374001425041/overview

The error is message from global-demangle.cpp is as the following:

FAIL: AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp (560 of 12394)
******************** TEST 'AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';      /b/s/w/ir/x/w/staging/llvm_build/./bin/clang  --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only   -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   -O0 /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp -o /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp && not  /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp 2>&1 | FileCheck /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp
--
Exit Code: 1

Command Output (stderr):
--
/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:15:12: error: CHECK: expected string not found in input
 // CHECK: '{{.*}}XXX::YYY::ZZZ{{.*}}' {{.*}} of size 4
           ^
<stdin>:8:56: note: scanning from here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                       ^
<stdin>:8:165: note: possible intended match here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                                                                                                                                    ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ================================================================= 
            2: ==315196==ERROR: AddressSanitizer: global-buffer-overflow on address 0x561bdea237e6 at pc 0x561bdea15d7e bp 0x7ffda4270b00 sp 0x7ffda4270af8 
            3: READ of size 1 at 0x561bdea237e6 thread T0 
            4:  #0 0x561bdea15d7d in main /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 
            5:  #1 0x7fe9bc8a1d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x23d09) (BuildId: 814ca45fb917d1b757796ff5f456237c263711c7) 
            6:  #2 0x561bde940339 in _start (/b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp+0x59339) (BuildId: 4e75c435413f2362) 
            7:  
            8: 0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4 
check:15'0                                                            X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
check:15'1                                                                                                                                                                         ?                                   possible intended match
            9:  '_ZN3XXX3YYY3ZZZE' is ascii string 'abc' 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           10: SUMMARY: AddressSanitizer: global-buffer-overflow /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 in main 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           11: Shadow bytes around the buggy address: 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           12:  0x561bdea23500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           13:  0x561bdea23580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>
MaskRay added a comment.EditedNov 21 2022, 11:52 AM

We started seeing the following test failures.

Failed Tests (8):
  AddressSanitizer-x86_64-linux :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location.cpp

https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8797107374001425041/overview

The error is message from global-demangle.cpp is as the following:

FAIL: AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp (560 of 12394)
******************** TEST 'AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';      /b/s/w/ir/x/w/staging/llvm_build/./bin/clang  --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only   -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   -O0 /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp -o /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp && not  /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp 2>&1 | FileCheck /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp
--
Exit Code: 1

Command Output (stderr):
--
/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:15:12: error: CHECK: expected string not found in input
 // CHECK: '{{.*}}XXX::YYY::ZZZ{{.*}}' {{.*}} of size 4
           ^
<stdin>:8:56: note: scanning from here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                       ^
<stdin>:8:165: note: possible intended match here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                                                                                                                                    ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ================================================================= 
            2: ==315196==ERROR: AddressSanitizer: global-buffer-overflow on address 0x561bdea237e6 at pc 0x561bdea15d7e bp 0x7ffda4270b00 sp 0x7ffda4270af8 
            3: READ of size 1 at 0x561bdea237e6 thread T0 
            4:  #0 0x561bdea15d7d in main /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 
            5:  #1 0x7fe9bc8a1d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x23d09) (BuildId: 814ca45fb917d1b757796ff5f456237c263711c7) 
            6:  #2 0x561bde940339 in _start (/b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp+0x59339) (BuildId: 4e75c435413f2362) 
            7:  
            8: 0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4 
check:15'0                                                            X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
check:15'1                                                                                                                                                                         ?                                   possible intended match
            9:  '_ZN3XXX3YYY3ZZZE' is ascii string 'abc' 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           10: SUMMARY: AddressSanitizer: global-buffer-overflow /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 in main 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           11: Shadow bytes around the buggy address: 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           12:  0x561bdea23500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           13:  0x561bdea23580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>

I'll appreciate some debugging since other sanitizer bots seem fine? Does your build bot not link asan tests with libc++abi or libstdc++ which provides __cxa_demangle? Then a mangled name is expected.
I vaguely remember that Fuchsia does things somewhat differently.

Perhaps you use -static-libstdc++ for both %dynamiclib and the main executable? Then there is no defined __cxa_demangle in the process.
I wonder whether a demangled name in odr-violation diagnostics is useful... Personally whether it is mangled/demangled doesn't concern me.

I wonder whether a demangled name in odr-violation diagnostics is useful... Personally whether it is mangled/demangled doesn't concern me.

Given the amount of "what does this use-after-free report mean, stop bothering me" we get, I'm appreciate a demangled name because it likely reduces the amount of bug reports assigned to me ;).

I wonder whether a demangled name in odr-violation diagnostics is useful... Personally whether it is mangled/demangled doesn't concern me.

Given the amount of "what does this use-after-free report mean, stop bothering me" we get, I'm appreciate a demangled name because it likely reduces the amount of bug reports assigned to me ;).

Thanks for the quick reply! Then I'll probably revert this patch and not consider reinstating it.

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp uses an undefined weak __cxa_demangle which does not pull in an archive definition.
So a -static-libstdc++ mostly-statically executable won't get demangled names.

zequanwu added a subscriber: zequanwu.EditedNov 22 2022, 3:08 PM

Hi, this causes two tests failure on mac.

Failed Tests (2):
   SanitizerCommon-tsan-x86_64-Darwin :: Darwin/symbolizer-function-offset-dladdr.cpp
   ThreadSanitizer-x86_64 :: Darwin/symbolizer-dladdr.cpp

https://reviews.llvm.org/rGdb7c82231c32074440d5426870051228435c6bce doesn't seem to fix the test because our cron job picks 57fd7ffe which includes it and failed on 3 tests:

Failed Tests (3):
   AddressSanitizer-x86_64-darwin :: TestCases/Darwin/interface_symbols_darwin.cpp
   SanitizerCommon-tsan-x86_64-Darwin :: Darwin/symbolizer-function-offset-dladdr.cpp
   ThreadSanitizer-x86_64 :: Darwin/symbolizer-dladdr.cpp

See https://bugs.chromium.org/p/chromium/issues/detail?id=1392533 for details. Please revert those two commits if it takes a while to fix.

Hi, this causes two tests failure on mac.

Failed Tests (2):
   SanitizerCommon-tsan-x86_64-Darwin :: Darwin/symbolizer-function-offset-dladdr.cpp
   ThreadSanitizer-x86_64 :: Darwin/symbolizer-dladdr.cpp

https://reviews.llvm.org/rGdb7c82231c32074440d5426870051228435c6bce doesn't seem to fix the test because our cron job picks 57fd7ffe which includes it and failed on 3 tests:

Failed Tests (3):
   AddressSanitizer-x86_64-darwin :: TestCases/Darwin/interface_symbols_darwin.cpp
   SanitizerCommon-tsan-x86_64-Darwin :: Darwin/symbolizer-function-offset-dladdr.cpp
   ThreadSanitizer-x86_64 :: Darwin/symbolizer-dladdr.cpp

See https://bugs.chromium.org/p/chromium/issues/detail?id=1392533 for details. Please revert those two commits if it takes a while to fix.

I don't have a macOS to check issues but don't think the combination of 00be3578e0841dd9abe408e5b4946180de0bf46b+db7c82231c32074440d5426870051228435c6bce (which just changed a __cxa_demangle call site and the ODR indicator symbol name) can suppress a tsan failure).

compiler-rt/test/asan/TestCases/Darwin/interface_symbols_darwin.cpp looks like a test which is nearly impossible to investigate without a macOS though I don't think it has connection with this patch.

The reverse of the combined commits is the following. Any chance you found the wrong culprit?

diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index 2b4a9e01c8a3..b780128c9adb 100644
--- a/compiler-rt/lib/asan/asan_globals.cpp
+++ b/compiler-rt/lib/asan/asan_globals.cpp
@@ -151,4 +151,4 @@ static void CheckODRViolationViaIndicator(const Global *g) {
         !IsODRViolationSuppressed(g->name))
-      ReportODRViolation(g, FindRegistrationSite(g), l->g,
-                         FindRegistrationSite(l->g));
+      ReportODRViolation(g, FindRegistrationSite(g),
+                         l->g, FindRegistrationSite(l->g));
   }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index d505d96bd653..b223f6cd01e3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -51,13 +51,8 @@ const char *DemangleCXXABI(const char *name) {
   // own demangler (libc++abi's implementation could be adapted so that
-  // 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;
-    }
-  }
+  // 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;
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index a4d4cc73c482..ff05454aa920 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2266,8 +2266,7 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
 
-    // The runtime library tries demangling symbol names in the descriptor but
-    // functionality like __cxa_demangle may be unavailable (e.g.
-    // -static-libstdc++). So we demangle the symbol names here.
-    std::string NameForGlobal = G->getName().str();
+    // TODO: Symbol names in the descriptor can be demangled by the runtime
+    // library. This could save ~0.4% of VM size for a private large binary.
+    std::string NameForGlobal = llvm::demangle(G->getName().str());
     GlobalVariable *Name =
-        createPrivateGlobalForString(M, llvm::demangle(NameForGlobal),
+        createPrivateGlobalForString(M, NameForGlobal,
                                      /*AllowMerging*/ true, kAsanGenPrefix);

We started seeing the following test failures.

Failed Tests (8):
  AddressSanitizer-x86_64-linux :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location.cpp

https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8797107374001425041/overview

The error is message from global-demangle.cpp is as the following:

FAIL: AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp (560 of 12394)
******************** TEST 'AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';      /b/s/w/ir/x/w/staging/llvm_build/./bin/clang  --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only   -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   -O0 /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp -o /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp && not  /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp 2>&1 | FileCheck /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp
--
Exit Code: 1

Command Output (stderr):
--
/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:15:12: error: CHECK: expected string not found in input
 // CHECK: '{{.*}}XXX::YYY::ZZZ{{.*}}' {{.*}} of size 4
           ^
<stdin>:8:56: note: scanning from here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                       ^
<stdin>:8:165: note: possible intended match here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                                                                                                                                    ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ================================================================= 
            2: ==315196==ERROR: AddressSanitizer: global-buffer-overflow on address 0x561bdea237e6 at pc 0x561bdea15d7e bp 0x7ffda4270b00 sp 0x7ffda4270af8 
            3: READ of size 1 at 0x561bdea237e6 thread T0 
            4:  #0 0x561bdea15d7d in main /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 
            5:  #1 0x7fe9bc8a1d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x23d09) (BuildId: 814ca45fb917d1b757796ff5f456237c263711c7) 
            6:  #2 0x561bde940339 in _start (/b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp+0x59339) (BuildId: 4e75c435413f2362) 
            7:  
            8: 0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4 
check:15'0                                                            X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
check:15'1                                                                                                                                                                         ?                                   possible intended match
            9:  '_ZN3XXX3YYY3ZZZE' is ascii string 'abc' 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           10: SUMMARY: AddressSanitizer: global-buffer-overflow /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 in main 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           11: Shadow bytes around the buggy address: 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           12:  0x561bdea23500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           13:  0x561bdea23580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>

I'll appreciate some debugging since other sanitizer bots seem fine? Does your build bot not link asan tests with libc++abi or libstdc++ which provides __cxa_demangle? Then a mangled name is expected.
I vaguely remember that Fuchsia does things somewhat differently.

After https://reviews.llvm.org/rGdb7c82231c32074440d5426870051228435c6bce, we do not see the test asan test failures anymore.
Are you planning to reland this patch or did you abandon it? We encountered the issue while building the Fuchsia toolchain for the host (Linux), and these tests failed on Linux, not Fuchsia.

The reverse of the combined commits is the following. Any chance you found the wrong culprit?

diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp
index 2b4a9e01c8a3..b780128c9adb 100644
--- a/compiler-rt/lib/asan/asan_globals.cpp
+++ b/compiler-rt/lib/asan/asan_globals.cpp
@@ -151,4 +151,4 @@ static void CheckODRViolationViaIndicator(const Global *g) {
         !IsODRViolationSuppressed(g->name))
-      ReportODRViolation(g, FindRegistrationSite(g), l->g,
-                         FindRegistrationSite(l->g));
+      ReportODRViolation(g, FindRegistrationSite(g),
+                         l->g, FindRegistrationSite(l->g));
   }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index d505d96bd653..b223f6cd01e3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -51,13 +51,8 @@ const char *DemangleCXXABI(const char *name) {
   // own demangler (libc++abi's implementation could be adapted so that
-  // 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;
-    }
-  }
+  // 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;
 
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index a4d4cc73c482..ff05454aa920 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2266,8 +2266,7 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
 
-    // The runtime library tries demangling symbol names in the descriptor but
-    // functionality like __cxa_demangle may be unavailable (e.g.
-    // -static-libstdc++). So we demangle the symbol names here.
-    std::string NameForGlobal = G->getName().str();
+    // TODO: Symbol names in the descriptor can be demangled by the runtime
+    // library. This could save ~0.4% of VM size for a private large binary.
+    std::string NameForGlobal = llvm::demangle(G->getName().str());
     GlobalVariable *Name =
-        createPrivateGlobalForString(M, llvm::demangle(NameForGlobal),
+        createPrivateGlobalForString(M, NameForGlobal,
                                      /*AllowMerging*/ true, kAsanGenPrefix);

I just manually double checked. At least this change causes these two tests(symbolizer-function-offset-dladdr.cpp and symbolizer-dladdr.cpp) to fail, not sure about interface_symbols_darwin.cpp.
I have a macbook and can help with debugging the tests.

We started seeing the following test failures.

Failed Tests (8):
  AddressSanitizer-x86_64-linux :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux :: TestCases/global-location.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/Linux/odr-violation.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-demangle.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location-nodebug.cpp
  AddressSanitizer-x86_64-linux-dynamic :: TestCases/global-location.cpp

https://luci-milo.appspot.com/ui/p/fuchsia/builders/toolchain.ci/clang-linux-x64/b8797107374001425041/overview

The error is message from global-demangle.cpp is as the following:

FAIL: AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp (560 of 12394)
******************** TEST 'AddressSanitizer-x86_64-linux :: TestCases/global-demangle.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';      /b/s/w/ir/x/w/staging/llvm_build/./bin/clang  --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only   -Wthread-safety -Wthread-safety-reference -Wthread-safety-beta   -O0 /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp -o /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp && not  /b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp 2>&1 | FileCheck /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp
--
Exit Code: 1

Command Output (stderr):
--
/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:15:12: error: CHECK: expected string not found in input
 // CHECK: '{{.*}}XXX::YYY::ZZZ{{.*}}' {{.*}} of size 4
           ^
<stdin>:8:56: note: scanning from here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                       ^
<stdin>:8:165: note: possible intended match here
0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4
                                                                                                                                                                    ^

Input file: <stdin>
Check file: /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp

-dump-input=help explains the following input dump.

Input was:
<<<<<<
            1: ================================================================= 
            2: ==315196==ERROR: AddressSanitizer: global-buffer-overflow on address 0x561bdea237e6 at pc 0x561bdea15d7e bp 0x7ffda4270b00 sp 0x7ffda4270af8 
            3: READ of size 1 at 0x561bdea237e6 thread T0 
            4:  #0 0x561bdea15d7d in main /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 
            5:  #1 0x7fe9bc8a1d09 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x23d09) (BuildId: 814ca45fb917d1b757796ff5f456237c263711c7) 
            6:  #2 0x561bde940339 in _start (/b/s/w/ir/x/w/staging/llvm_build/runtimes/runtimes-x86_64-unknown-linux-gnu-bins/compiler-rt/test/asan/X86_64LinuxConfig/TestCases/Output/global-demangle.cpp.tmp+0x59339) (BuildId: 4e75c435413f2362) 
            7:  
            8: 0x561bdea237e6 is located 2 bytes after global variable '_ZN3XXX3YYY3ZZZE' defined in '/b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp' (0x561bdea237e0) of size 4 
check:15'0                                                            X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
check:15'1                                                                                                                                                                         ?                                   possible intended match
            9:  '_ZN3XXX3YYY3ZZZE' is ascii string 'abc' 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           10: SUMMARY: AddressSanitizer: global-buffer-overflow /b/s/w/ir/x/w/llvm-llvm-project/compiler-rt/test/asan/TestCases/global-demangle.cpp:12:15 in main 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           11: Shadow bytes around the buggy address: 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           12:  0x561bdea23500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           13:  0x561bdea23580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
check:15'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            .
            .
            .
>>>>>>

I'll appreciate some debugging since other sanitizer bots seem fine? Does your build bot not link asan tests with libc++abi or libstdc++ which provides __cxa_demangle? Then a mangled name is expected.
I vaguely remember that Fuchsia does things somewhat differently.

After https://reviews.llvm.org/rGdb7c82231c32074440d5426870051228435c6bce, we do not see the test asan test failures anymore.
Are you planning to reland this patch or did you abandon it? We encountered the issue while building the Fuchsia toolchain for the host (Linux), and these tests failed on Linux, not Fuchsia.

Thanks for checking. db7c82231c32074440d5426870051228435c6bce restored the original behavior and I do not plan to reland the demangling part of the patch (infeasible since -fsanitize=address user may not link in libc++abi/libstdc++).

Reverted it for now. Debugged a bit using @zequanwu's macOS, running a test under lldb said that free(demangled_name) in compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp segfaulted.
This is really puzzling. It's a standard practice to call free on __cxxabiv1::__cxa_demangle allocated string (realloc under the hood). Both realloc/free are intercepted by sanitizers.

Will appreciate some help why macOS doesn't like free(demangled_name) in compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp ... This doesn't feel like a code issue to me.