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,
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;
}
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;
#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>
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_) {
#endif // SANITIZER_SUPPORTS_WEAK_HOOKS
const char *Symbolizer::PlatformDemangle(const char *name) {
- return DemangleCXXABI(name);
+ return DemangleSwiftAndCXX(name);
}
void Symbolizer::PlatformPrepareForSandboxing() {}
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