OSDN Git Service

[libFuzzer] clear the corpus elements if they are evicted (i.e. smaller elements...
authorKostya Serebryany <kcc@google.com>
Wed, 5 Oct 2016 00:25:17 +0000 (00:25 +0000)
committerKostya Serebryany <kcc@google.com>
Wed, 5 Oct 2016 00:25:17 +0000 (00:25 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283279 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerCorpus.h
lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerLoop.cpp

index 3b76471..ea4f0c7 100644 (file)
@@ -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;
index 8f7820d..d0de517 100644 (file)
@@ -511,7 +511,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
   }
 
   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");
   }
index 57dbb9f..35d68bc 100644 (file)
@@ -309,10 +309,20 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
     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(UnitVector *InitialCorpus) {
   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);