[sanitizers] Teach the internal demangler about Swift names
authorAnna Zaks <ganna@apple.com>
Fri, 15 Apr 2016 23:51:00 +0000 (23:51 +0000)
committerAnna Zaks <ganna@apple.com>
Fri, 15 Apr 2016 23:51:00 +0000 (23:51 +0000)
Add support for Swift names when symbolicating sanitizer traces. This is
now relevant since TSan and ASan support have been added to Swift on OS X.

Differential Revision: http://reviews.llvm.org/D19135

llvm-svn: 266494

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_internal.h
compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_mac.cc
compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
compiler-rt/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc

index 12c70b6..ada059c 100644 (file)
@@ -28,7 +28,7 @@ const char *ExtractUptr(const char *str, const char *delims, uptr *result);
 const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,
                                       char **result);
 
-const char *DemangleCXXABI(const char *name);
+const char *DemangleSwiftAndCXX(const char *name);
 
 // SymbolizerTool is an interface that is implemented by individual "tools"
 // that can perform symbolication (external llvm-symbolizer, libbacktrace,
index a963b75..d591abc 100644 (file)
@@ -32,7 +32,7 @@ bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
   Dl_info info;
   int result = dladdr((const void *)addr, &info);
   if (!result) return false;
-  const char *demangled = DemangleCXXABI(info.dli_sname);
+  const char *demangled = DemangleSwiftAndCXX(info.dli_sname);
   stack->info.function = demangled ? internal_strdup(demangled) : nullptr;
   return true;
 }
@@ -41,7 +41,7 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) {
   Dl_info info;
   int result = dladdr((const void *)addr, &info);
   if (!result) return false;
-  const char *demangled = DemangleCXXABI(info.dli_sname);
+  const char *demangled = DemangleSwiftAndCXX(info.dli_sname);
   datainfo->name = internal_strdup(demangled);
   datainfo->start = (uptr)info.dli_saddr;
   return true;
index 7de3dbd..2abfc25 100644 (file)
@@ -26,6 +26,7 @@
 #include "sanitizer_symbolizer_libbacktrace.h"
 #include "sanitizer_symbolizer_mac.h"
 
+#include <dlfcn.h>   // for dlsym()
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/wait.h>
@@ -61,6 +62,38 @@ const char *DemangleCXXABI(const char *name) {
   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 *DemangleSwiftAndCXX(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 @@ class InternalSymbolizer : public SymbolizerTool {
 #endif  // SANITIZER_SUPPORTS_WEAK_HOOKS
 
 const char *Symbolizer::PlatformDemangle(const char *name) {
-  return DemangleCXXABI(name);
+  return DemangleSwiftAndCXX(name);
 }
 
 void Symbolizer::PlatformPrepareForSandboxing() {}
index 429ac59..8ff8bbb 100644 (file)
@@ -55,4 +55,14 @@ TEST(Symbolizer, ExtractTokenUpToDelimiter) {
   InternalFree(token);
 }
 
+TEST(Symbolizer, DemangleSwiftAndCXX) {
+  // Swift names are not demangled in default llvm build because Swift
+  // runtime is not linked in.
+  EXPECT_STREQ("_TtSd", DemangleSwiftAndCXX("_TtSd"));
+  // Check that the rest demangles properly.
+  EXPECT_STREQ("f1(char*, int)", DemangleSwiftAndCXX("_Z2f1Pci"));
+  EXPECT_STREQ("foo", DemangleSwiftAndCXX("foo"));
+  EXPECT_STREQ("", DemangleSwiftAndCXX(""));
+}
+
 }  // namespace __sanitizer