[libFuzzer] make the fork mode less verbose

llvm-svn: 353794
GitOrigin-RevId: 2b9a8f37a484aa7f976829c055147f20b82d39d9
diff --git a/FuzzerDriver.cpp b/FuzzerDriver.cpp
index 8ad99d0..dc67512 100644
--- a/FuzzerDriver.cpp
+++ b/FuzzerDriver.cpp
@@ -484,11 +484,12 @@
     GetSizedFilesFromDir(Dir, &Corpus);
   std::sort(Corpus.begin(), Corpus.end());
   auto CFPath = TempPath(".fork");
+  auto LogPath = TempPath(".log");
 
   Vector<std::string> Files;
   Set<uint32_t> Features;
   if (!Corpus.empty()) {
-    CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath);
+    CrashResistantMerge(Args, {}, Corpus, &Files, {}, &Features, CFPath, false);
     RemoveFile(CFPath);
   }
   auto TempDir = TempPath("Dir");
@@ -500,8 +501,8 @@
   BaseCmd.removeFlag("fork");
   for (auto &C : Corpora) // Remove all corpora from the args.
     BaseCmd.removeArgument(C);
-  BaseCmd.addFlag("runs", "1000000");
-  BaseCmd.addFlag("max_total_time", "30");
+  if (!BaseCmd.hasFlag("max_total_time"))
+    BaseCmd.addFlag("max_total_time", "60");
   BaseCmd.addArgument(TempDir);
   int ExitCode = 0;
   for (size_t i = 0; i < 1000000; i++) {
@@ -511,10 +512,11 @@
       Cmd.addFlag("seed_inputs",
                   Files[Rand.SkewTowardsLast(Files.size())] + "," +
                       Files[Rand.SkewTowardsLast(Files.size())]);
-    Printf("RUN %s\n", Cmd.toString().c_str());
+    Cmd.setOutputFile(LogPath);
+    Cmd.combineOutAndErr();
     RmFilesInDir(TempDir);
     ExitCode = ExecuteCommand(Cmd);
-    Printf("Exit code: %d\n", ExitCode);
+    // Printf("done [%d] %s\n", ExitCode, Cmd.toString().c_str());
     if (ExitCode == Options.InterruptExitCode)
       break;
     Vector<SizedFile> TempFiles;
@@ -522,7 +524,7 @@
     Set<uint32_t> NewFeatures;
     GetSizedFilesFromDir(TempDir, &TempFiles);
     CrashResistantMerge(Args, {}, TempFiles, &FilesToAdd, Features,
-                        &NewFeatures, CFPath);
+                        &NewFeatures, CFPath, false);
     RemoveFile(CFPath);
     for (auto &Path : FilesToAdd) {
       auto NewPath = F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
@@ -539,7 +541,11 @@
     if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode)
       continue;
     // And exit if we don't ignore this crash.
-    if (ExitCode != 0) break;
+    if (ExitCode != 0) {
+      Printf("INFO: log from the inner process:\n%s",
+             FileToString(LogPath).c_str());
+      break;
+    }
   }
 
   RmFilesInDir(TempDir);
@@ -568,7 +574,7 @@
   Vector<std::string> NewFiles;
   Set<uint32_t> NewFeatures;
   CrashResistantMerge(Args, OldCorpus, NewCorpus, &NewFiles, {}, &NewFeatures,
-                      CFPath);
+                      CFPath, true);
   for (auto &Path : NewFiles)
     F->WriteToOutputCorpus(FileToVector(Path, Options.MaxLen));
   // We are done, delete the control file if it was a temporary one.
diff --git a/FuzzerIO.cpp b/FuzzerIO.cpp
index a18fba7..ba4153b 100644
--- a/FuzzerIO.cpp
+++ b/FuzzerIO.cpp
@@ -125,6 +125,15 @@
   fflush(OutputFile);
 }
 
+void VPrintf(bool Verbose, const char *Fmt, ...) {
+  if (!Verbose) return;
+  va_list ap;
+  va_start(ap, Fmt);
+  vfprintf(OutputFile, Fmt, ap);
+  va_end(ap);
+  fflush(OutputFile);
+}
+
 void RmFilesInDir(const std::string &Path) {
   Vector<std::string> Files;
   ListFilesInDirRecursive(Path, 0, &Files, /*TopDir*/true);
diff --git a/FuzzerIO.h b/FuzzerIO.h
index b31aea9..a78d505 100644
--- a/FuzzerIO.h
+++ b/FuzzerIO.h
@@ -46,6 +46,7 @@
 void CloseStdout();
 
 void Printf(const char *Fmt, ...);
+void VPrintf(bool Verbose, const char *Fmt, ...);
 
 // Print using raw syscalls, useful when printing at early init stages.
 void RawPrint(const char *Str);
diff --git a/FuzzerMerge.cpp b/FuzzerMerge.cpp
index c61169a..9a86512 100644
--- a/FuzzerMerge.cpp
+++ b/FuzzerMerge.cpp
@@ -255,42 +255,43 @@
 
 // Outer process. Does not call the target code and thus should not fail.
 void CrashResistantMerge(const Vector<std::string> &Args,
-                    const Vector<SizedFile> &OldCorpus,
-                    const Vector<SizedFile> &NewCorpus,
-                    Vector<std::string> *NewFiles,
-                    const Set<uint32_t> &InitialFeatures,
-                    Set<uint32_t> *NewFeatures,
-                    const std::string &CFPath) {
+                         const Vector<SizedFile> &OldCorpus,
+                         const Vector<SizedFile> &NewCorpus,
+                         Vector<std::string> *NewFiles,
+                         const Set<uint32_t> &InitialFeatures,
+                         Set<uint32_t> *NewFeatures, const std::string &CFPath,
+                         bool V /*Verbose*/) {
   size_t NumAttempts = 0;
   if (FileSize(CFPath)) {
-    Printf("MERGE-OUTER: non-empty control file provided: '%s'\n",
+    VPrintf(V, "MERGE-OUTER: non-empty control file provided: '%s'\n",
            CFPath.c_str());
     Merger M;
     std::ifstream IF(CFPath);
     if (M.Parse(IF, /*ParseCoverage=*/false)) {
-      Printf("MERGE-OUTER: control file ok, %zd files total,"
+      VPrintf(V, "MERGE-OUTER: control file ok, %zd files total,"
              " first not processed file %zd\n",
              M.Files.size(), M.FirstNotProcessedFile);
       if (!M.LastFailure.empty())
-        Printf("MERGE-OUTER: '%s' will be skipped as unlucky "
+        VPrintf(V, "MERGE-OUTER: '%s' will be skipped as unlucky "
                "(merge has stumbled on it the last time)\n",
                M.LastFailure.c_str());
       if (M.FirstNotProcessedFile >= M.Files.size()) {
-        Printf("MERGE-OUTER: nothing to do, merge has been completed before\n");
+        VPrintf(
+            V, "MERGE-OUTER: nothing to do, merge has been completed before\n");
         exit(0);
       }
 
       NumAttempts = M.Files.size() - M.FirstNotProcessedFile;
     } else {
-      Printf("MERGE-OUTER: bad control file, will overwrite it\n");
+      VPrintf(V, "MERGE-OUTER: bad control file, will overwrite it\n");
     }
   }
 
   if (!NumAttempts) {
     // The supplied control file is empty or bad, create a fresh one.
     NumAttempts = OldCorpus.size() + NewCorpus.size();
-    Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n", NumAttempts,
-           OldCorpus.size());
+    VPrintf(V, "MERGE-OUTER: %zd files, %zd in the initial corpus\n",
+            NumAttempts, OldCorpus.size());
     WriteNewControlFile(CFPath, OldCorpus, NewCorpus);
   }
 
@@ -301,13 +302,17 @@
   BaseCmd.removeFlag("fork");
   for (size_t Attempt = 1; Attempt <= NumAttempts; Attempt++) {
     Fuzzer::MaybeExitGracefully();
-    Printf("MERGE-OUTER: attempt %zd\n", Attempt);
+    VPrintf(V, "MERGE-OUTER: attempt %zd\n", Attempt);
     Command Cmd(BaseCmd);
     Cmd.addFlag("merge_control_file", CFPath);
     Cmd.addFlag("merge_inner", "1");
+    if (!V) {
+      Cmd.setOutputFile("/dev/null");  // TODO: need to handle this on Windows?
+      Cmd.combineOutAndErr();
+    }
     auto ExitCode = ExecuteCommand(Cmd);
     if (!ExitCode) {
-      Printf("MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
+      VPrintf(V, "MERGE-OUTER: succesfull in %zd attempt(s)\n", Attempt);
       break;
     }
   }
@@ -315,14 +320,16 @@
   Merger M;
   std::ifstream IF(CFPath);
   IF.seekg(0, IF.end);
-  Printf("MERGE-OUTER: the control file has %zd bytes\n", (size_t)IF.tellg());
+  VPrintf(V, "MERGE-OUTER: the control file has %zd bytes\n",
+          (size_t)IF.tellg());
   IF.seekg(0, IF.beg);
   M.ParseOrExit(IF, true);
   IF.close();
-  Printf("MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
-         M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
+  VPrintf(V,
+          "MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n",
+          M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb());
   size_t NumNewFeatures = M.Merge(InitialFeatures, NewFeatures, NewFiles);
-  Printf("MERGE-OUTER: %zd new files with %zd new features added\n",
+  VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added\n",
          NewFiles->size(), NumNewFeatures);
 }
 
diff --git a/FuzzerMerge.h b/FuzzerMerge.h
index 97f85cb..065dbd4 100644
--- a/FuzzerMerge.h
+++ b/FuzzerMerge.h
@@ -76,7 +76,8 @@
                          Vector<std::string> *NewFiles,
                          const Set<uint32_t> &InitialFeatures,
                          Set<uint32_t> *NewFeatures,
-                         const std::string &CFPath);
+                         const std::string &CFPath,
+                         bool Verbose);
 
 }  // namespace fuzzer