[llvm] r283279 - [libFuzzer] clear the corpus elements if they are evicted (i.e. smaller elements with proper coverage are found). Make sure we never try to mutate empty element. Print the corpus size in bytes in the status lines

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 4 17:25:17 PDT 2016


Author: kcc
Date: Tue Oct  4 19:25:17 2016
New Revision: 283279

URL: http://llvm.org/viewvc/llvm-project?rev=283279&view=rev
Log:
[libFuzzer] clear the corpus elements if they are evicted (i.e. smaller elements with proper coverage are found). Make sure we never try to mutate empty element. Print the corpus size in bytes in the status lines

Modified:
    llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
    llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
    llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp

Modified: llvm/trunk/lib/Fuzzer/FuzzerCorpus.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCorpus.h?rev=283279&r1=283278&r2=283279&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerCorpus.h (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerCorpus.h Tue Oct  4 19:25:17 2016
@@ -39,9 +39,22 @@ class InputCorpus {
     memset(FeatureSet, 0, sizeof(FeatureSet));
   }
   size_t size() const { return Inputs.size(); }
+  size_t SizeInBytes() const {
+    size_t Res = 0;
+    for (auto &II : Inputs)
+      Res += II.U.size();
+    return Res;
+  }
+  size_t NumActiveUnits() const {
+    size_t Res = 0;
+    for (auto &II : Inputs)
+      Res += !II.U.empty();
+    return Res;
+  }
   bool empty() const { return Inputs.empty(); }
   const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; }
   void AddToCorpus(const Unit &U) {
+    assert(!U.empty());
     uint8_t Hash[kSHA1NumBytes];
     ComputeSHA1(U.data(), U.size(), Hash);
     if (!Hashes.insert(Sha1ToString(Hash)).second) return;
@@ -60,7 +73,9 @@ class InputCorpus {
   bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
   bool HasUnit(const std::string &H) { return Hashes.count(H); }
   InputInfo &ChooseUnitToMutate(Random &Rand) {
-    return Inputs[ChooseUnitIdxToMutate(Rand)];
+    InputInfo &II = Inputs[ChooseUnitIdxToMutate(Rand)];
+    assert(!II.U.empty());
+    return II;
   };
 
   // Returns an index of random unit from the corpus to mutate.
@@ -132,8 +147,11 @@ private:
           auto &OlderII = Inputs[Fe.SmallestElementIdx];
           assert(OlderII.NumFeatures > 0);
           OlderII.NumFeatures--;
-          if (!OlderII.NumFeatures && FeatureDebug)
-            Printf("EVICTED %zd\n", Fe.SmallestElementIdx);
+          if (!OlderII.NumFeatures) {
+            OlderII.U.clear();  // Will be never used again.
+            if (FeatureDebug)
+              Printf("EVICTED %zd\n", Fe.SmallestElementIdx);
+          }
         }
         Fe.SmallestElementIdx = CurrentElementIdx;
         Fe.SmallestElementSize = Size;

Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=283279&r1=283278&r2=283279&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Tue Oct  4 19:25:17 2016
@@ -511,7 +511,7 @@ int FuzzerDriver(int *argc, char ***argv
   }
 
   if (InitialCorpus.empty()) {
-    InitialCorpus.push_back(Unit());
+    InitialCorpus.push_back(Unit({0}));
     if (Options.Verbosity)
       Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
   }

Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=283279&r1=283278&r2=283279&view=diff
==============================================================================
--- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
+++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Oct  4 19:25:17 2016
@@ -309,10 +309,20 @@ void Fuzzer::PrintStats(const char *Wher
     Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge());
   if (MaxCoverage.CallerCalleeCoverage)
     Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
-  if (size_t N = Corpus.size())
-    Printf(" units: %zd", N);
+  if (size_t N = Corpus.size()) {
+    Printf(" corpus: %zd", Corpus.NumActiveUnits());
+    if (size_t N = Corpus.SizeInBytes()) {
+      if (N < (1<<14))
+        Printf("/%zdb", N);
+      else if (N < (1 << 24))
+        Printf("/%zdKb", N >> 10);
+      else
+        Printf("/%zdMb", N >> 20);
+    }
+  }
   if (Units)
     Printf(" units: %zd", Units);
+
   Printf(" exec/s: %zd", ExecPerSec);
   Printf("%s", End);
 }
@@ -403,6 +413,10 @@ void Fuzzer::ShuffleAndMinimize(UnitVect
   if (Options.ShuffleAtStartUp)
     ShuffleCorpus(InitialCorpus);
 
+  // Test the callback with empty input and never try it again.
+  uint8_t dummy;
+  ExecuteCallback(&dummy, 0);
+
   for (const auto &U : *InitialCorpus) {
     if (RunOne(U)) {
       Corpus.AddToCorpus(U);




More information about the llvm-commits mailing list