[compiler-rt] r183732 - [Sanitizer] add file forgotten in r183730

Alexey Samsonov samsonov at google.com
Tue Jun 11 01:14:24 PDT 2013


Author: samsonov
Date: Tue Jun 11 03:14:24 2013
New Revision: 183732

URL: http://llvm.org/viewvc/llvm-project?rev=183732&view=rev
Log:
[Sanitizer] add file forgotten in r183730

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc?rev=183732&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Tue Jun 11 03:14:24 2013
@@ -0,0 +1,117 @@
+//===-- sanitizer_symbolizer_posix_libcdep.cc -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between AddressSanitizer and ThreadSanitizer
+// run-time libraries.
+// POSIX-specific implementation of symbolizer parts.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+#if SANITIZER_POSIX
+#include "sanitizer_common.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_symbolizer.h"
+
+#include <errno.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+namespace __sanitizer {
+
+bool StartSymbolizerSubprocess(const char *path_to_symbolizer,
+                               int *input_fd, int *output_fd) {
+  if (!FileExists(path_to_symbolizer)) {
+    Report("WARNING: invalid path to external symbolizer!\n");
+    return false;
+  }
+
+  int *infd = NULL;
+  int *outfd = NULL;
+  // The client program may close its stdin and/or stdout and/or stderr
+  // thus allowing socketpair to reuse file descriptors 0, 1 or 2.
+  // In this case the communication between the forked processes may be
+  // broken if either the parent or the child tries to close or duplicate
+  // these descriptors. The loop below produces two pairs of file
+  // descriptors, each greater than 2 (stderr).
+  int sock_pair[5][2];
+  for (int i = 0; i < 5; i++) {
+    if (pipe(sock_pair[i]) == -1) {
+      for (int j = 0; j < i; j++) {
+        internal_close(sock_pair[j][0]);
+        internal_close(sock_pair[j][1]);
+      }
+      Report("WARNING: Can't create a socket pair to start "
+             "external symbolizer (errno: %d)\n", errno);
+      return false;
+    } else if (sock_pair[i][0] > 2 && sock_pair[i][1] > 2) {
+      if (infd == NULL) {
+        infd = sock_pair[i];
+      } else {
+        outfd = sock_pair[i];
+        for (int j = 0; j < i; j++) {
+          if (sock_pair[j] == infd) continue;
+          internal_close(sock_pair[j][0]);
+          internal_close(sock_pair[j][1]);
+        }
+        break;
+      }
+    }
+  }
+  CHECK(infd);
+  CHECK(outfd);
+
+  int pid = fork();
+  if (pid == -1) {
+    // Fork() failed.
+    internal_close(infd[0]);
+    internal_close(infd[1]);
+    internal_close(outfd[0]);
+    internal_close(outfd[1]);
+    Report("WARNING: failed to fork external symbolizer "
+           " (errno: %d)\n", errno);
+    return false;
+  } else if (pid == 0) {
+    // Child subprocess.
+    internal_close(STDOUT_FILENO);
+    internal_close(STDIN_FILENO);
+    internal_dup2(outfd[0], STDIN_FILENO);
+    internal_dup2(infd[1], STDOUT_FILENO);
+    internal_close(outfd[0]);
+    internal_close(outfd[1]);
+    internal_close(infd[0]);
+    internal_close(infd[1]);
+    for (int fd = getdtablesize(); fd > 2; fd--)
+      internal_close(fd);
+    execl(path_to_symbolizer, path_to_symbolizer, (char*)0);
+    internal__exit(1);
+  }
+
+  // Continue execution in parent process.
+  internal_close(outfd[0]);
+  internal_close(infd[1]);
+  *input_fd = infd[0];
+  *output_fd = outfd[1];
+
+  // Check that symbolizer subprocess started successfully.
+  int pid_status;
+  SleepForMillis(kSymbolizerStartupTimeMillis);
+  int exited_pid = waitpid(pid, &pid_status, WNOHANG);
+  if (exited_pid != 0) {
+    // Either waitpid failed, or child has already exited.
+    Report("WARNING: external symbolizer didn't start up correctly!\n");
+    return false;
+  }
+
+  return true;
+}
+
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_POSIX





More information about the llvm-commits mailing list