Index: lib/sanitizer_common/sanitizer_symbolizer_internal.h =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -28,7 +28,7 @@ const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter, char **result); -const char *DemangleCXXABI(const char *name); +const char *DemangleCXXAndSwift(const char *name); // SymbolizerTool is an interface that is implemented by individual "tools" // that can perform symbolication (external llvm-symbolizer, libbacktrace, Index: lib/sanitizer_common/sanitizer_symbolizer_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_symbolizer_mac.cc +++ lib/sanitizer_common/sanitizer_symbolizer_mac.cc @@ -32,7 +32,7 @@ Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; - const char *demangled = DemangleCXXABI(info.dli_sname); + const char *demangled = DemangleCXXAndSwift(info.dli_sname); stack->info.function = demangled ? internal_strdup(demangled) : nullptr; return true; } @@ -41,7 +41,7 @@ Dl_info info; int result = dladdr((const void *)addr, &info); if (!result) return false; - const char *demangled = DemangleCXXABI(info.dli_sname); + const char *demangled = DemangleCXXAndSwift(info.dli_sname); datainfo->name = internal_strdup(demangled); datainfo->start = (uptr)info.dli_saddr; 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 @@ -26,6 +26,7 @@ #include "sanitizer_symbolizer_libbacktrace.h" #include "sanitizer_symbolizer_mac.h" +#include // for dlsym() #include #include #include @@ -61,6 +62,38 @@ return name; } +// Attempts to demangle a Swift name. The demangler will return nullptr +/// if a non-Swift name is passed in. +const char *DemangleSwift(const char *name) { + // Not to call dlsym every time we demangle, check if we are dealing with + // Swift mangled name first. + if (name[0] != '_' || name[1] != 'T') { + return nullptr; + } + + // As of now, there are no headers for the Swift runtime. Once they are + // present, we will weakly link since we do not require Swift runtime to be + // linked. + typedef char *(*swift_demangle_ft)(const char *mangledName, + size_t mangledNameLength, + char *outputBuffer, + size_t *outputBufferSize, + uint32_t flags); + swift_demangle_ft swift_demangle_f = + (swift_demangle_ft) dlsym(RTLD_DEFAULT, "swift_demangle"); + if (swift_demangle_f) + return swift_demangle_f(name, internal_strlen(name), 0, 0, 0); + + return nullptr; +} + +const char *DemangleCXXAndSwift(const char *name) { + CHECK(name); + if (const char *swift_demangled_name = DemangleSwift(name)) + return swift_demangled_name; + return DemangleCXXABI(name); +} + bool SymbolizerProcess::StartSymbolizerSubprocess() { if (!FileExists(path_)) { if (!reported_invalid_path_) { @@ -364,7 +397,7 @@ #endif // SANITIZER_SUPPORTS_WEAK_HOOKS const char *Symbolizer::PlatformDemangle(const char *name) { - return DemangleCXXABI(name); + return DemangleCXXAndSwift(name); } void Symbolizer::PlatformPrepareForSandboxing() {} Index: lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc +++ lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc @@ -55,4 +55,13 @@ InternalFree(token); } +TEST(Symbolizer, DemangleCXXAndSwift) { + // The Swift name will only be demangled if the Swift runtime is linked in. + EXPECT_STREQ("_TtSd", DemangleCXXAndSwift("_TtSd")); + // Check that the rest demangles properly. + EXPECT_STREQ("f1(char*, int)", DemangleCXXAndSwift("_Z2f1Pci")); + EXPECT_STREQ("foo", DemangleCXXAndSwift("foo")); + EXPECT_STREQ("", DemangleCXXAndSwift("")); +} + } // namespace __sanitizer