[compiler-rt] r315407 - [libFuzzer] experimental flag to tweak the corpus distribution. Seems to improve the situation dramatically on the png benchmark and make things worse on a number of micro-puzzles. Needs more A/B testing

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 10 18:44:27 PDT 2017


Author: kcc
Date: Tue Oct 10 18:44:26 2017
New Revision: 315407

URL: http://llvm.org/viewvc/llvm-project?rev=315407&view=rev
Log:
[libFuzzer] experimental flag to tweak the corpus distribution. Seems to improve the situation dramatically on the png benchmark and make things worse on a number of micro-puzzles. Needs more A/B testing 

Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerCorpus.h
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
    compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerCorpus.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerCorpus.h?rev=315407&r1=315406&r2=315407&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerCorpus.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerCorpus.h Tue Oct 10 18:44:26 2017
@@ -36,6 +36,7 @@ struct InputInfo {
   bool MayDeleteFile = false;
   bool Reduced = false;
   Vector<uint32_t> UniqFeatureSet;
+  float FeatureFrequencyScore = 1.0;
 };
 
 class InputCorpus {
@@ -44,6 +45,7 @@ class InputCorpus {
   InputCorpus(const std::string &OutputCorpus) : OutputCorpus(OutputCorpus) {
     memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
     memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
+    memset(FeatureFrequency, 0, sizeof(FeatureFrequency));
   }
   ~InputCorpus() {
     for (auto II : Inputs)
@@ -134,6 +136,7 @@ class InputCorpus {
     Hashes.insert(Sha1ToString(II->Sha1));
     II->U = U;
     II->Reduced = true;
+    UpdateCorpusDistribution();
   }
 
   bool HasUnit(const Unit &U) { return Hashes.count(Hash(U)); }
@@ -145,8 +148,6 @@ class InputCorpus {
   };
 
   // Returns an index of random unit from the corpus to mutate.
-  // Hypothesis: units added to the corpus last are more likely to be
-  // interesting. This function gives more weight to the more recent units.
   size_t ChooseUnitIdxToMutate(Random &Rand) {
     size_t Idx = static_cast<size_t>(CorpusDistribution(Rand));
     assert(Idx < Inputs.size());
@@ -212,15 +213,22 @@ class InputCorpus {
     return false;
   }
 
+  void UpdateFeatureFrequency(size_t Idx) {
+    FeatureFrequency[Idx % kFeatureSetSize]++;
+  }
+  float GetFeatureFrequency(size_t Idx) const {
+    return FeatureFrequency[Idx % kFeatureSetSize];
+  }
+  void UpdateFeatureFrequencyScore(InputInfo *II) {
+    II->FeatureFrequencyScore = 0.00000001;
+    for (auto Idx : II->UniqFeatureSet)
+      II->FeatureFrequencyScore +=
+          1. / (GetFeatureFrequency(Idx) * GetFeatureFrequency(Idx) + 1.);
+  }
+
   size_t NumFeatures() const { return NumAddedFeatures; }
   size_t NumFeatureUpdates() const { return NumUpdatedFeatures; }
 
-  void ResetFeatureSet() {
-    assert(Inputs.empty());
-    memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature));
-    memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature));
-  }
-
 private:
 
   static const bool FeatureDebug = false;
@@ -243,6 +251,10 @@ private:
 
   // Updates the probability distribution for the units in the corpus.
   // Must be called whenever the corpus or unit weights are changed.
+  //
+  // Hypothesis: units added to the corpus last are more interesting.
+  //
+  // Hypothesis: inputs with infrequent features are more interesting.
   void UpdateCorpusDistribution() {
     size_t N = Inputs.size();
     assert(N);
@@ -250,7 +262,8 @@ private:
     Weights.resize(N);
     std::iota(Intervals.begin(), Intervals.end(), 0);
     for (size_t i = 0; i < N; i++)
-      Weights[i] = Inputs[i]->NumFeatures * (i + 1);
+      Weights[i] =
+          Inputs[i]->NumFeatures * (i + 1) * Inputs[i]->FeatureFrequencyScore;
     CorpusDistribution = std::piecewise_constant_distribution<double>(
         Intervals.begin(), Intervals.end(), Weights.begin());
   }
@@ -266,6 +279,7 @@ private:
   size_t NumUpdatedFeatures = 0;
   uint32_t InputSizesPerFeature[kFeatureSetSize];
   uint32_t SmallestElementPerFeature[kFeatureSetSize];
+  float FeatureFrequency[kFeatureSetSize];
 
   std::string OutputCorpus;
 };

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=315407&r1=315406&r2=315407&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Tue Oct 10 18:44:26 2017
@@ -605,6 +605,7 @@ int FuzzerDriver(int *argc, char ***argv
   Options.PrintCoverage = Flags.print_coverage;
   Options.DumpCoverage = Flags.dump_coverage;
   Options.UseClangCoverage = Flags.use_clang_coverage;
+  Options.UseFeatureFrequency = Flags.use_feature_frequency;
   if (Flags.exit_on_src_pos)
     Options.ExitOnSrcPos = Flags.exit_on_src_pos;
   if (Flags.exit_on_item)

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=315407&r1=315406&r2=315407&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Tue Oct 10 18:44:26 2017
@@ -132,6 +132,7 @@ FUZZER_FLAG_STRING(run_equivalence_serve
 FUZZER_FLAG_STRING(use_equivalence_server, "Experimental")
 FUZZER_FLAG_INT(analyze_dict, 0, "Experimental")
 FUZZER_FLAG_INT(use_clang_coverage, 0, "Experimental")
+FUZZER_FLAG_INT(use_feature_frequency, 0, "Experimental")
 
 FUZZER_DEPRECATED_FLAG(exit_on_first)
 FUZZER_DEPRECATED_FLAG(save_minimized_corpus)

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=315407&r1=315406&r2=315407&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Tue Oct 10 18:44:26 2017
@@ -396,6 +396,7 @@ bool Fuzzer::RunOne(const uint8_t *Data,
   size_t FoundUniqFeaturesOfII = 0;
   size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
   TPC.CollectFeatures([&](size_t Feature) {
+    Corpus.UpdateFeatureFrequency(Feature);
     if (Corpus.AddFeature(Feature, Size, Options.Shrink))
       UniqFeatureSetTmp.push_back(Feature);
     if (Options.ReduceInputs && II)
@@ -565,6 +566,8 @@ void Fuzzer::MutateAndTestOne() {
   MD.StartMutationSequence();
 
   auto &II = Corpus.ChooseUnitToMutate(MD.GetRand());
+  if (Options.UseFeatureFrequency)
+    Corpus.UpdateFeatureFrequencyScore(&II);
   const auto &U = II.U;
   memcpy(BaseSha1, II.Sha1, sizeof(BaseSha1));
   assert(CurrentUnitData);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h?rev=315407&r1=315406&r2=315407&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerOptions.h Tue Oct 10 18:44:26 2017
@@ -54,6 +54,7 @@ struct FuzzingOptions {
   bool DumpCoverage = false;
   bool UseClangCoverage = false;
   bool DetectLeaks = true;
+  int UseFeatureFrequency = false;
   int  TraceMalloc = 0;
   bool HandleAbrt = false;
   bool HandleBus = false;




More information about the llvm-commits mailing list