build/build-clang/find_symbolizer_linux.patch
author James Graham <james@hoppipolla.co.uk>
Thu, 15 Nov 2018 20:40:50 +0000
changeset 503174 9702f65efe224bcb14f64db9eeb99ca2ad5ef8f8
parent 444744 8d6fd02420f2eb8d09a1c50e060294b44c17d357
permissions -rw-r--r--
Bug 1507532 - Add support for running reftests in fennec, r=KWierso Add a ReftestExecutor implementation matching the one that we use for Desktop Firefox. Differential Revision: https://phabricator.services.mozilla.com/D12034

We currently need this patch because ASan only searches PATH to find the
llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
where we ship an ASan build, including llvm-symbolizer, to the user, we
cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
it up next to the binary. This patch implements the functionality for Linux
only until there is similar functionality provided upstream.

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
index cde54bf..8daade1 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cc
@@ -21,6 +21,10 @@
 #include "sanitizer_common.h"
 #include "sanitizer_file.h"
 
+#if SANITIZER_LINUX
+#include "sanitizer_posix.h"
+#endif
+
 namespace __sanitizer {
 
 void CatastrophicErrorWrite(const char *buffer, uptr length) {
@@ -156,6 +160,34 @@ char *FindPathToBinary(const char *name) {
     if (*end == '\0') break;
     beg = end + 1;
   }
+
+#if SANITIZER_LINUX
+  // If we cannot find the requested binary in PATH, we should try to locate
+  // it next to the binary, in case it is shipped with the build itself
+  // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
+  if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) < 0)
+    return nullptr;
+
+  uptr buf_len = internal_strlen(buffer.data());
+
+  /* Avoid using dirname() here */
+  while (buf_len > 0) {
+    if (buffer[buf_len - 1] == '/')
+      break;
+    buf_len--;
+  }
+
+  if (!buf_len)
+    return nullptr;
+
+  if (buf_len + name_len + 1 <= kMaxPathLength) {
+    internal_memcpy(&buffer[buf_len], name, name_len);
+    buffer[buf_len + name_len] = '\0';
+    if (FileExists(buffer.data()))
+      return internal_strdup(buffer.data());
+  }
+#endif
+
   return nullptr;
 }