[fuzzer] add -runs=N to limit the number of runs per session. Also, make sure we...
authorKostya Serebryany <kcc@google.com>
Wed, 4 Feb 2015 22:20:09 +0000 (22:20 +0000)
committerKostya Serebryany <kcc@google.com>
Wed, 4 Feb 2015 22:20:09 +0000 (22:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228214 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerFlags.def
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerMain.cpp

index 0895fa7..f4a4bb9 100644 (file)
 FUZZER_FLAG(int, verbosity, 1, "Verbosity level.")
 FUZZER_FLAG(int, seed, 0, "Random seed. If 0, seed is generated.")
 FUZZER_FLAG(int, iterations, -1,
-            "Number of iterations of the fuzzer (-1 for infinite runs).")
+            "Number of iterations of the fuzzer internal loop"
+            " (-1 for infinite iterations).")
+FUZZER_FLAG(int, runs, -1,
+            "Number of individual test runs (-1 for infinite runs).")
 FUZZER_FLAG(int, max_len, 64, "Maximal length of the test input.")
 FUZZER_FLAG(int, cross_over, 1, "If 1, cross over inputs.")
 FUZZER_FLAG(int, mutate_depth, 5,
index fbf2630..acf07ee 100644 (file)
@@ -9,6 +9,7 @@
 // Define the main class fuzzer::Fuzzer and most functions.
 //===----------------------------------------------------------------------===//
 #include <cassert>
+#include <climits>
 #include <chrono>
 #include <cstddef>
 #include <cstdlib>
@@ -46,6 +47,7 @@ class Fuzzer {
     int  MutateDepth = 5;
     bool ExitOnFirst = false;
     bool UseFullCoverageSet  = false;
+    size_t MaxNumberOfRuns = ULONG_MAX;
     std::string OutputCorpus;
   };
   Fuzzer(FuzzingOptions Options) : Options(Options) {
index 0428589..d825148 100644 (file)
@@ -147,6 +147,8 @@ void Fuzzer::SaveCorpus() {
 size_t Fuzzer::MutateAndTestOne(Unit *U) {
   size_t NewUnits = 0;
   for (int i = 0; i < Options.MutateDepth; i++) {
+    if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
+      return NewUnits;
     Mutate(U, Options.MaxLen);
     size_t NewCoverage = RunOne(*U);
     if (NewCoverage) {
@@ -177,19 +179,20 @@ size_t Fuzzer::MutateAndTestOne(Unit *U) {
 size_t Fuzzer::Loop(size_t NumIterations) {
   size_t NewUnits = 0;
   for (size_t i = 1; i <= NumIterations; i++) {
-    if (Options.DoCrossOver) {
-      for (size_t J1 = 0; J1 < Corpus.size(); J1++) {
+    for (size_t J1 = 0; J1 < Corpus.size(); J1++) {
+      if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
+        return NewUnits;
+      // First, simply mutate the unit w/o doing crosses.
+      CurrentUnit = Corpus[J1];
+      NewUnits += MutateAndTestOne(&CurrentUnit);
+      // Now, cross with others.
+      if (Options.DoCrossOver) {
         for (size_t J2 = 0; J2 < Corpus.size(); J2++) {
           CurrentUnit.clear();
           CrossOver(Corpus[J1], Corpus[J2], &CurrentUnit, Options.MaxLen);
           NewUnits += MutateAndTestOne(&CurrentUnit);
         }
       }
-    } else {  // No CrossOver
-      for (size_t J = 0; J < Corpus.size(); J++) {
-        CurrentUnit = Corpus[J];
-        NewUnits += MutateAndTestOne(&CurrentUnit);
-      }
     }
   }
   return NewUnits;
index 0a852ed..35e50f0 100644 (file)
@@ -11,7 +11,6 @@
 
 #include "FuzzerInternal.h"
 
-#include <climits>
 #include <cstring>
 #include <unistd.h>
 #include <iostream>
@@ -164,6 +163,8 @@ int main(int argc, char **argv) {
   Options.MutateDepth = Flags.mutate_depth;
   Options.ExitOnFirst = Flags.exit_on_first;
   Options.UseFullCoverageSet = Flags.use_full_coverage_set;
+  if (Flags.runs >= 0)
+    Options.MaxNumberOfRuns = Flags.runs;
   if (!inputs.empty())
     Options.OutputCorpus = inputs[0];
   Fuzzer F(Options);