1We currently need this patch because ASan only searches PATH to find the
2llvm-symbolizer binary to symbolize ASan traces. On testing machines, this
3can be installed in PATH easily. However, for e.g. the ASan Nightly Project,
4where we ship an ASan build, including llvm-symbolizer, to the user, we
5cannot expect llvm-symbolizer to be on PATH. Instead, we should try to look
6it up next to the binary. This patch implements the functionality for Linux
7only until there is similar functionality provided upstream.
8
9diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
10index 79930d79425..cfb4f90c0d5 100644
11--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
12+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
13@@ -20,6 +20,10 @@
14 #include "sanitizer_common.h"
15 #include "sanitizer_file.h"
16
17+#if SANITIZER_LINUX
18+#include "sanitizer_posix.h"
19+#endif
20+
21 namespace __sanitizer {
22
23 void CatastrophicErrorWrite(const char *buffer, uptr length) {
24@@ -194,6 +198,34 @@ char *FindPathToBinary(const char *name) {
25     if (*end == '\0') break;
26     beg = end + 1;
27   }
28+
29+#if SANITIZER_LINUX
30+  // If we cannot find the requested binary in PATH, we should try to locate
31+  // it next to the binary, in case it is shipped with the build itself
32+  // (e.g. llvm-symbolizer shipped with sanitizer build to symbolize on client.
33+  if (internal_readlink("/proc/self/exe", buffer.data(), kMaxPathLength) < 0)
34+    return nullptr;
35+
36+  uptr buf_len = internal_strlen(buffer.data());
37+
38+  /* Avoid using dirname() here */
39+  while (buf_len > 0) {
40+    if (buffer[buf_len - 1] == '/')
41+      break;
42+    buf_len--;
43+  }
44+
45+  if (!buf_len)
46+    return nullptr;
47+
48+  if (buf_len + name_len + 1 <= kMaxPathLength) {
49+    internal_memcpy(&buffer[buf_len], name, name_len);
50+    buffer[buf_len + name_len] = '\0';
51+    if (FileExists(buffer.data()))
52+      return internal_strdup(buffer.data());
53+  }
54+#endif
55+
56   return nullptr;
57 }
58
59