[compiler-rt] r265923 - [sanitizer] Restore stderr when using forkpty() to spawn external symbolizer

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 11 02:27:09 PDT 2016


Author: kuba.brecka
Date: Mon Apr 11 04:27:09 2016
New Revision: 265923

URL: http://llvm.org/viewvc/llvm-project?rev=265923&view=rev
Log:
[sanitizer] Restore stderr when using forkpty() to spawn external symbolizer

In `AtosSymbolizer`, we're using `forkpty()` to create a new pseudo-terminal to communicate with the `atos` tool (we need that to avoid output buffering in interactive mode). This however redirects both stdout and stderr into a single stream, so when we read the output, we can't distinguish between errors and standard replies. Let's save&restore stderr to avoid that.

Differential Revision: http://reviews.llvm.org/D15073


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_mac.cc?rev=265923&r1=265922&r2=265923&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_mac.cc Mon Apr 11 04:27:09 2016
@@ -79,23 +79,6 @@ class AtosSymbolizerProcess : public Sym
   char pid_str_[16];
 };
 
-static const char *kAtosErrorMessages[] = {
-  "atos cannot examine process",
-  "unable to get permission to examine process",
-  "An admin user name and password is required",
-  "could not load inserted library",
-  "architecture mismatch between analysis process",
-};
-
-static bool IsAtosErrorMessage(const char *str) {
-  for (uptr i = 0; i < ARRAY_SIZE(kAtosErrorMessages); i++) {
-    if (internal_strstr(str, kAtosErrorMessages[i])) {
-      return true;
-    }
-  }
-  return false;
-}
-
 static bool ParseCommandOutput(const char *str, uptr addr, char **out_name,
                                char **out_module, char **out_file, uptr *line,
                                uptr *start_address) {
@@ -112,12 +95,6 @@ static bool ParseCommandOutput(const cha
   //   0xdeadbeef (in library.dylib)
   //   0xdeadbeef
 
-  if (IsAtosErrorMessage(trim)) {
-    Report("atos returned an error: %s\n", trim);
-    InternalFree(trim);
-    return false;
-  }
-
   const char *rest = trim;
   char *symbol_name;
   rest = ExtractTokenUpToDelimiter(rest, " (in ", &symbol_name);

Modified: 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=265923&r1=265922&r2=265923&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc Mon Apr 11 04:27:09 2016
@@ -74,6 +74,13 @@ bool SymbolizerProcess::StartSymbolizerS
   if (use_forkpty_) {
 #if SANITIZER_MAC
     fd_t fd = kInvalidFd;
+
+    // forkpty redirects stdout and stderr into a single stream, so we would
+    // receive error messages as standard replies. To avoid that, let's dup
+    // stderr and restore it in the child.
+    int saved_stderr = dup(STDERR_FILENO);
+    CHECK_GE(saved_stderr, 0);
+
     // Use forkpty to disable buffering in the new terminal.
     pid = internal_forkpty(&fd);
     if (pid == -1) {
@@ -83,6 +90,11 @@ bool SymbolizerProcess::StartSymbolizerS
       return false;
     } else if (pid == 0) {
       // Child subprocess.
+
+      // Restore stderr.
+      CHECK_GE(dup2(saved_stderr, STDERR_FILENO), 0);
+      close(saved_stderr);
+
       const char *argv[kArgVMax];
       GetArgV(path_, argv);
       execv(path_, const_cast<char **>(&argv[0]));
@@ -92,6 +104,8 @@ bool SymbolizerProcess::StartSymbolizerS
     // Continue execution in parent process.
     input_fd_ = output_fd_ = fd;
 
+    close(saved_stderr);
+
     // Disable echo in the new terminal, disable CR.
     struct termios termflags;
     tcgetattr(fd, &termflags);




More information about the llvm-commits mailing list