<div dir="ltr">FYI: I've disabled this test in r172976 as it occasionally fails on our bots with "Exit Code: 1".<div style>Do you think we can make this less flaky somehow?</div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Fri, Jan 18, 2013 at 8:44 PM, Alexander Potapenko <span dir="ltr"><<a href="mailto:glider@google.com" target="_blank">glider@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: glider<br>
Date: Fri Jan 18 10:44:27 2013<br>
New Revision: 172828<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=172828&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=172828&view=rev</a><br>
Log:<br>
[ASan] Fix the log_path option to use different log files for parent and child processes after fork().<br>
<br>
Added:<br>
    compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc<br>
Modified:<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc<br>
<br>
Added: compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc?rev=172828&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc?rev=172828&view=auto</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc (added)<br>
+++ compiler-rt/trunk/lib/asan/lit_tests/log_path_fork_test.cc Fri Jan 18 10:44:27 2013<br>
@@ -0,0 +1,22 @@<br>
+// RUN: %clangxx_asan  %s -o %t<br>
+// RUN: rm -f %t.log.*<br>
+// Set verbosity to 1 so that the log files are opened prior to fork().<br>
+// RUN: ASAN_OPTIONS="log_path=%t.log verbosity=1" not %t 2> %t.out<br>
+// RUN: for f in %t.log.* ; do FileCheck %s < $f; done<br>
+// RUN: [ `ls %t.log.* | wc -l` == 2 ]<br>
+<br>
+#include <stdlib.h><br>
+#include <string.h><br>
+#include <unistd.h><br>
+<br>
+int main(int argc, char **argv) {<br>
+  void *x = malloc(10);<br>
+  free(x);<br>
+  if (fork() == -1) return 1;<br>
+  // There are two processes at this point, thus there should be two distinct<br>
+  // error logs.<br>
+  free(x);<br>
+  return 0;<br>
+}<br>
+<br>
+// CHECK: ERROR: AddressSanitizer<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=172828&r1=172827&r2=172828&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=172828&r1=172827&r2=172828&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Fri Jan 18 10:44:27 2013<br>
@@ -23,10 +23,16 @@<br>
   return PageSize;<br>
 }<br>
<br>
-// By default, dump to stderr. If report_fd is kInvalidFd, try to obtain file<br>
-// descriptor by opening file in report_path.<br>
+static bool log_to_file = false;  // Set to true by __sanitizer_set_report_path<br>
+<br>
+// By default, dump to stderr. If |log_to_file| is true and |report_fd_pid|<br>
+// isn't equal to the current PID, try to obtain file descriptor by opening<br>
+// file "report_path_prefix.<PID>".<br>
 static fd_t report_fd = kStderrFd;<br>
-static char report_path[4096];  // Set via __sanitizer_set_report_path.<br>
+static char report_path_prefix[4096];  // Set via __sanitizer_set_report_path.<br>
+// PID of process that opened |report_fd|. If a fork() occurs, the PID of the<br>
+// child thread will be different from |report_fd_pid|.<br>
+static int report_fd_pid = 0;<br>
<br>
 static void (*DieCallback)(void);<br>
 void SetDieCallback(void (*callback)(void)) {<br>
@@ -56,15 +62,23 @@<br>
 }<br>
<br>
 static void MaybeOpenReportFile() {<br>
-  if (report_fd != kInvalidFd)<br>
-    return;<br>
-  fd_t fd = internal_open(report_path, true);<br>
+  if (!log_to_file || (report_fd_pid == GetPid())) return;<br>
+  char report_path_full[4096];<br>
+  internal_snprintf(report_path_full, sizeof(report_path_full),<br>
+                    "%s.%d", report_path_prefix, GetPid());<br>
+  fd_t fd = internal_open(report_path_full, true);<br>
   if (fd == kInvalidFd) {<br>
     report_fd = kStderrFd;<br>
-    Report("ERROR: Can't open file: %s\n", report_path);<br>
+    log_to_file = false;<br>
+    Report("ERROR: Can't open file: %s\n", report_path_full);<br>
     Die();<br>
   }<br>
+  if (report_fd != kInvalidFd) {<br>
+    // We're in the child. Close the parent's log.<br>
+    internal_close(report_fd);<br>
+  }<br>
   report_fd = fd;<br>
+  report_fd_pid = GetPid();<br>
 }<br>
<br>
 bool PrintsToTty() {<br>
@@ -184,14 +198,16 @@<br>
 void __sanitizer_set_report_path(const char *path) {<br>
   if (!path) return;<br>
   uptr len = internal_strlen(path);<br>
-  if (len > sizeof(report_path) - 100) {<br>
+  if (len > sizeof(report_path_prefix) - 100) {<br>
     Report("ERROR: Path is too long: %c%c%c%c%c%c%c%c...\n",<br>
            path[0], path[1], path[2], path[3],<br>
            path[4], path[5], path[6], path[7]);<br>
     Die();<br>
   }<br>
-  internal_snprintf(report_path, sizeof(report_path), "%s.%d", path, GetPid());<br>
+  internal_strncpy(report_path_prefix, path, sizeof(report_path_prefix));<br>
+  report_path_prefix[len] = '\0';<br>
   report_fd = kInvalidFd;<br>
+  log_to_file = true;<br>
 }<br>
<br>
 void __sanitizer_set_report_fd(int fd) {<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Alexey Samsonov, MSK</div>
</div>