[PATCH] D15073: [sanitizer] Restore stderr when using forkpty() to spawn external symbolizer

Kuba Brecka via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 30 03:31:32 PST 2015


kubabrecka created this revision.
kubabrecka added reviewers: samsonov, glider, kcc, dvyukov.
kubabrecka added subscribers: llvm-commits, zaks.anna.

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.

http://reviews.llvm.org/D15073

Files:
  lib/sanitizer_common/sanitizer_symbolizer_mac.cc
  lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc

Index: lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
===================================================================
--- lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
+++ lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
@@ -74,6 +74,13 @@
   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,10 @@
       return false;
     } else if (pid == 0) {
       // Child subprocess.
+
+      // Restore stderr.
+      CHECK_GE(dup2(saved_stderr, STDERR_FILENO), 0);
+
       const char *argv[kArgVMax];
       GetArgV(path_, argv);
       execv(path_, const_cast<char **>(&argv[0]));
@@ -92,6 +103,8 @@
     // 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);
Index: lib/sanitizer_common/sanitizer_symbolizer_mac.cc
===================================================================
--- lib/sanitizer_common/sanitizer_symbolizer_mac.cc
+++ lib/sanitizer_common/sanitizer_symbolizer_mac.cc
@@ -79,23 +79,6 @@
   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 @@
   //   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);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D15073.41379.patch
Type: text/x-patch
Size: 2609 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151130/d52b7880/attachment-0001.bin>


More information about the llvm-commits mailing list