getMainExecutable: handle realpath() failure, falling back to getprogpath().
authorSam McCall <sam.mccall@gmail.com>
Tue, 2 Jul 2019 15:42:37 +0000 (15:42 +0000)
committerSam McCall <sam.mccall@gmail.com>
Tue, 2 Jul 2019 15:42:37 +0000 (15:42 +0000)
Summary:
Previously, we'd pass a nullptr to std::string and crash().

This case happens when the binary is deleted while being used (e.g. rebuilding clangd).

Reviewers: kadircet

Subscribers: ilya-biryukov, kristina, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64068

llvm-svn: 364936

llvm/lib/Support/Unix/Path.inc

index 761d183..c64c0df 100644 (file)
@@ -222,20 +222,20 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
     // the program, and not the eventual binary file. Therefore, call realpath
     // so this behaves the same on all platforms.
 #if _POSIX_VERSION >= 200112 || defined(__GLIBC__)
-    char *real_path = realpath(exe_path, NULL);
-    std::string ret = std::string(real_path);
-    free(real_path);
-    return ret;
+    if (char *real_path = realpath(exe_path, NULL)) {
+      std::string ret = std::string(real_path);
+      free(real_path);
+      return ret;
+    }
 #else
     char real_path[MAXPATHLEN];
-    realpath(exe_path, real_path);
-    return std::string(real_path);
+    if (realpath(exe_path, real_path))
+      return std::string(real_path);
 #endif
-  } else {
-    // Fall back to the classical detection.
-    if (getprogpath(exe_path, argv0))
-      return exe_path;
   }
+  // Fall back to the classical detection.
+  if (getprogpath(exe_path, argv0))
+    return exe_path;
 #elif defined(HAVE_DLFCN_H) && defined(HAVE_DLADDR)
   // Use dladdr to get executable path if available.
   Dl_info DLInfo;