Index: lib/sanitizer_common/sanitizer_symbolizer_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -28,6 +28,8 @@ const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter, char **result); +const char *DemangleCXXABI(const char *name); + // SymbolizerTool is an interface that is implemented by individual "tools" // that can perform symbolication (external llvm-symbolizer, libbacktrace, // Windows DbgHelp symbolizer, etc.). Index: lib/sanitizer_common/sanitizer_symbolizer_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_mac.cc +++ lib/sanitizer_common/sanitizer_symbolizer_mac.cc @@ -31,7 +31,11 @@ Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; - stack->info.function = internal_strdup(info.dli_sname); + if (const char *demangled = DemangleCXXABI(info.dli_sname)) { + stack->info.function = internal_strdup(demangled); + } else { + stack->info.function = internal_strdup(info.dli_sname); + } return true; } Index: lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -38,7 +38,7 @@ namespace __sanitizer { // Attempts to demangle the name via __cxa_demangle from __cxxabiv1. -static const char *DemangleCXXABI(const char *name) { +const char *DemangleCXXABI(const char *name) { // 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 Index: test/asan/TestCases/Darwin/dladdr-demangling.cc =================================================================== --- test/asan/TestCases/Darwin/dladdr-demangling.cc +++ test/asan/TestCases/Darwin/dladdr-demangling.cc @@ -0,0 +1,33 @@ +// In a non-forking sandbox, we fallback to dladdr(). Test that we provide +// properly demangled C++ names in that case. + +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=verbosity=2 not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DLADDR + +#include + +class MyClass { + public: + int my_function(int n) { + char *x = (char*)malloc(n * sizeof(char)); + free(x); + return x[5]; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK-DLADDR: Using dladdr symbolizer as fallback + // CHECK-DLADDR: failed to fork external symbolizer + // CHECK: {{ #0 0x.* in MyClass::my_function\(int\)}} + // CHECK: {{freed by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_free}} + // CHECK: {{ #1 0x.* in MyClass::my_function\(int\)}} + // CHECK: {{previously allocated by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_malloc}} + // CHECK: {{ #1 0x.* in MyClass::my_function\(int\)}} + } +}; + +int main() { + MyClass o; + return o.my_function(10); +}