[compiler-rt] r354175 - [libFuzzer] form mode: add -ignore_crashes flag, honor the max_total_time flag, print the number of ooms/timeouts/crashes, fix a typo

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 15 13:51:15 PST 2019


Author: kcc
Date: Fri Feb 15 13:51:15 2019
New Revision: 354175

URL: http://llvm.org/viewvc/llvm-project?rev=354175&view=rev
Log:
[libFuzzer] form mode: add -ignore_crashes flag, honor the max_total_time flag, print the number of ooms/timeouts/crashes, fix a typo

Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
    compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerIO.h
    compiler-rt/trunk/lib/fuzzer/FuzzerIOPosix.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerIOWindows.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
    compiler-rt/trunk/test/fuzzer/fork.test

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Fri Feb 15 13:51:15 2019
@@ -606,6 +606,7 @@ int FuzzerDriver(int *argc, char ***argv
   Options.TimeoutExitCode = Flags.timeout_exitcode;
   Options.IgnoreTimeouts = Flags.ignore_timeouts;
   Options.IgnoreOOMs = Flags.ignore_ooms;
+  Options.IgnoreCrashes = Flags.ignore_crashes;
   Options.MaxTotalTimeSec = Flags.max_total_time;
   Options.DoCrossOver = Flags.cross_over;
   Options.MutateDepth = Flags.mutate_depth;

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Fri Feb 15 13:51:15 2019
@@ -45,6 +45,7 @@ FUZZER_FLAG_INT(fork, 0, "Experimental m
                 "in a subprocess")
 FUZZER_FLAG_INT(ignore_timeouts, 1, "Ignore timeouts in fork mode")
 FUZZER_FLAG_INT(ignore_ooms, 1, "Ignore OOMs in fork mode")
+FUZZER_FLAG_INT(ignore_crashes, 0, "Ignore crashes in fork mode")
 FUZZER_FLAG_INT(merge, 0, "If 1, the 2-nd, 3-rd, etc corpora will be "
   "merged into the 1-st corpus. Only interesting units will be taken. "
   "This flag can be used to minimize a corpus.")

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFork.cpp Fri Feb 15 13:51:15 2019
@@ -17,6 +17,7 @@
 #include "FuzzerUtil.h"
 
 #include <atomic>
+#include <chrono>
 #include <fstream>
 #include <mutex>
 #include <queue>
@@ -76,10 +77,22 @@ struct GlobalEnv {
   Set<uint32_t> Features, Cov;
   Vector<std::string> Files;
   Random *Rand;
+  std::chrono::system_clock::time_point ProcessStartTime;
   int Verbosity = 0;
 
+  size_t NumTimeouts = 0;
+  size_t NumOOMs = 0;
+  size_t NumCrashes = 0;
+
+
   size_t NumRuns = 0;
 
+  size_t secondsSinceProcessStartUp() const {
+    return std::chrono::duration_cast<std::chrono::seconds>(
+               std::chrono::system_clock::now() - ProcessStartTime)
+        .count();
+  }
+
   FuzzJob *CreateNewJob(size_t JobId) {
     Command Cmd(Args);
     Cmd.removeFlag("fork");
@@ -146,10 +159,12 @@ struct GlobalEnv {
 
     auto Stats = ParseFinalStatsFromLog(Job->LogPath);
     NumRuns += Stats.number_of_executed_units;
-    if (!FilesToAdd.empty())
-      Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd\n", NumRuns,
+    if (!FilesToAdd.empty() || Job->ExitCode != 0)
+      Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd "
+             "oom/timeout/crash: %zd/%zd/%zd time: %zds\n", NumRuns,
              Cov.size(), Features.size(), Files.size(),
-             Stats.average_exec_per_sec);
+             Stats.average_exec_per_sec,
+             NumOOMs, NumTimeouts, NumCrashes, secondsSinceProcessStartUp());
   }
 };
 
@@ -187,14 +202,14 @@ void WorkerThread(std::atomic<bool> *Sto
 void FuzzWithFork(Random &Rand, const FuzzingOptions &Options,
                   const Vector<std::string> &Args,
                   const Vector<std::string> &CorpusDirs, int NumJobs) {
-  Printf("INFO: -fork=%d: doing fuzzing in a separate process in order to "
-         "be more resistant to crashes, timeouts, and OOMs\n", NumJobs);
+  Printf("INFO: -fork=%d: fuzzing in separate process(s)\n", NumJobs);
 
   GlobalEnv Env;
   Env.Args = Args;
   Env.CorpusDirs = CorpusDirs;
   Env.Rand = &Rand;
   Env.Verbosity = Options.Verbosity;
+  Env.ProcessStartTime = std::chrono::system_clock::now();
 
   Vector<SizedFile> SeedFiles;
   for (auto &Dir : CorpusDirs)
@@ -215,8 +230,8 @@ void FuzzWithFork(Random &Rand, const Fu
                       {}, &Env.Cov,
                       CFPath, false);
   RemoveFile(CFPath);
-  Printf("INFO: -fork=%d: %zd seeds, starting to fuzz; scratch: %s\n",
-         NumJobs, Env.Files.size(), Env.TempDir.c_str());
+  Printf("INFO: -fork=%d: %zd seed inputs, starting to fuzz in %s\n", NumJobs,
+         Env.Files.size(), Env.TempDir.c_str());
 
   int ExitCode = 0;
 
@@ -230,9 +245,11 @@ void FuzzWithFork(Random &Rand, const Fu
     FuzzQ.Push(Env.CreateNewJob(JobId++));
   }
 
-  while (!Stop) {
+  while (true) {
     auto Job = MergeQ.Pop();
     if (!Job) {
+      if (Stop)
+        break;
       SleepSeconds(1);
       continue;
     }
@@ -242,20 +259,42 @@ void FuzzWithFork(Random &Rand, const Fu
 
     // Continue if our crash is one of the ignorred ones.
     if (Options.IgnoreTimeouts && ExitCode == Options.TimeoutExitCode)
-      ;
+      Env.NumTimeouts++;
     else if (Options.IgnoreOOMs && ExitCode == Options.OOMExitCode)
-      ;
+      Env.NumOOMs++;
     else if (ExitCode == Options.InterruptExitCode)
       Stop = true;
     else if (ExitCode != 0) {
-      // And exit if we don't ignore this crash.
-      Printf("INFO: log from the inner process:\n%s",
-                   FileToString(Job->LogPath).c_str());
-      Stop = true;
+      Env.NumCrashes++;
+      if (Options.IgnoreCrashes) {
+        std::ifstream In(Job->LogPath);
+        std::string Line;
+        while (std::getline(In, Line, '\n'))
+          if (Line.find("ERROR:") != Line.npos)
+            Printf("%s\n", Line.c_str());
+      } else {
+        // And exit if we don't ignore this crash.
+        Printf("INFO: log from the inner process:\n%s",
+               FileToString(Job->LogPath).c_str());
+        Stop = true;
+      }
     }
     RemoveFile(Job->LogPath);
     delete Job;
-    FuzzQ.Push(Env.CreateNewJob(JobId++));
+
+    // Stop if we are over the time budget.
+    // This is not precise, since other threads are still running
+    // and we will wait while joining them.
+    // We also don't stop instantly: other jobs need to finish.
+    if (Options.MaxTotalTimeSec > 0 && !Stop &&
+        Env.secondsSinceProcessStartUp() >= (size_t)Options.MaxTotalTimeSec) {
+      Printf("INFO: fuzzed for %zd seconds, wrapping up soon\n",
+             Env.secondsSinceProcessStartUp());
+      Stop = true;
+    }
+
+    if (!Stop)
+      FuzzQ.Push(Env.CreateNewJob(JobId++));
   }
   Stop = true;
 
@@ -265,7 +304,8 @@ void FuzzWithFork(Random &Rand, const Fu
   RmDirRecursive(Env.TempDir);
 
   // Use the exit code from the last child process.
-  Printf("Fork: exiting: %d\n", ExitCode);
+  Printf("INFO: exiting: %d time: %zds\n", ExitCode,
+         Env.secondsSinceProcessStartUp());
   exit(ExitCode);
 }
 

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIO.cpp Fri Feb 15 13:51:15 2019
@@ -136,7 +136,7 @@ void VPrintf(bool Verbose, const char *F
 }
 
 void RmDirRecursive(const std::string &Dir) {
-  IterateDirRecurisve(
+  IterateDirRecursive(
       Dir, [](const std::string &Path) {},
       [](const std::string &Path) { RmDir(Path); },
       [](const std::string &Path) { RemoveFile(Path); });

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIO.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIO.h?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIO.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIO.h Fri Feb 15 13:51:15 2019
@@ -65,7 +65,7 @@ void RmDirRecursive(const std::string &D
 // Iterate files and dirs inside Dir, recursively.
 // Call DirPreCallback/DirPostCallback on dirs before/after
 // calling FileCallback on files.
-void IterateDirRecurisve(const std::string &Dir,
+void IterateDirRecursive(const std::string &Dir,
                          void (*DirPreCallback)(const std::string &Dir),
                          void (*DirPostCallback)(const std::string &Dir),
                          void (*FileCallback)(const std::string &Dir));

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIOPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIOPosix.cpp?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIOPosix.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIOPosix.cpp Fri Feb 15 13:51:15 2019
@@ -79,7 +79,7 @@ void ListFilesInDirRecursive(const std::
 }
 
 
-void IterateDirRecurisve(const std::string &Dir,
+void IterateDirRecursive(const std::string &Dir,
                          void (*DirPreCallback)(const std::string &Dir),
                          void (*DirPostCallback)(const std::string &Dir),
                          void (*FileCallback)(const std::string &Dir)) {
@@ -94,7 +94,7 @@ void IterateDirRecurisve(const std::stri
     else if ((E->d_type == DT_DIR ||
              (E->d_type == DT_UNKNOWN && IsDirectory(Path))) &&
              *E->d_name != '.')
-      IterateDirRecurisve(Path, DirPreCallback, DirPostCallback, FileCallback);
+      IterateDirRecursive(Path, DirPreCallback, DirPostCallback, FileCallback);
   }
   closedir(D);
   DirPostCallback(Dir);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerIOWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerIOWindows.cpp?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerIOWindows.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerIOWindows.cpp Fri Feb 15 13:51:15 2019
@@ -141,7 +141,7 @@ void ListFilesInDirRecursive(const std::
 }
 
 
-void IterateDirRecurisve(const std::string &Dir,
+void IterateDirRecursive(const std::string &Dir,
                          void (*DirPreCallback)(const std::string &Dir),
                          void (*DirPostCallback)(const std::string &Dir),
                          void (*FileCallback)(const std::string &Dir)) {

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h Fri Feb 15 13:51:15 2019
@@ -23,8 +23,9 @@ struct FuzzingOptions {
   int OOMExitCode = 71;
   int InterruptExitCode = 72;
   int ErrorExitCode = 77;
-  bool IgnoreTimeouts = 1;
-  bool IgnoreOOMs = 1;
+  bool IgnoreTimeouts = true;
+  bool IgnoreOOMs = true;
+  bool IgnoreCrashes = false;
   int MaxTotalTimeSec = 0;
   int RssLimitMb = 0;
   int MallocLimitMb = 0;

Modified: compiler-rt/trunk/test/fuzzer/fork.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/fork.test?rev=354175&r1=354174&r2=354175&view=diff
==============================================================================
--- compiler-rt/trunk/test/fuzzer/fork.test (original)
+++ compiler-rt/trunk/test/fuzzer/fork.test Fri Feb 15 13:51:15 2019
@@ -14,3 +14,7 @@ RUN: not %run %t-OutOfMemoryTest -fork=1
 CRASH: SEGV on unknown address 0x000000000000
 RUN: %cpp_compiler %S/ShallowOOMDeepCrash.cpp -o %t-ShallowOOMDeepCrash
 RUN: not %run %t-ShallowOOMDeepCrash -fork=1 -rss_limit_mb=128 2>&1 | FileCheck %s --check-prefix=CRASH
+
+MAX_TOTAL_TIME: INFO: fuzzed for {{.*}} seconds, wrapping up soon
+MAX_TOTAL_TIME: INFO: exiting: {{.*}} time:
+RUN: not %run %t-ShallowOOMDeepCrash -fork=1 -rss_limit_mb=128 -ignore_crashes=1 -max_total_time=5 2>&1 | FileCheck %s --check-prefix=MAX_TOTAL_TIME




More information about the llvm-commits mailing list