https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89215
--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Seems to be upstream bug, also in asan etc., Demangle(name) in there doesn't really differentiate between cases where it allocated the memory or just returned the passed in string or did something else. E.g. const char *MaybeDemangleGlobalName(const char *name) { // We can spoil names of globals with C linkage, so use an heuristic // approach to check if the name should be demangled. bool should_demangle = false; if (name[0] == '_' && name[1] == 'Z') should_demangle = true; else if (SANITIZER_WINDOWS && name[0] == '\01' && name[1] == '?') should_demangle = true; return should_demangle ? Symbolizer::GetOrInit()->Demangle(name) : name; } Not really sure if changing say: Buffer->append("'%s'", Symbolizer::GetOrInit()->Demangle(A.String)); to: char *str = Symbolizer::GetOrInit()->Demangle(A.String); Buffer->append("'%s'", str); if (str != A.String) InternalFree(str); would be safe, after all, some demangling could be done with the internal allocator, other with some other allocator, and libsanitizer supports many different demangling styles.