]> granicus.if.org Git - llvm/commitdiff
[libFuzzer] fix merging with trace-pc-guard
authorKostya Serebryany <kcc@google.com>
Fri, 23 Sep 2016 01:58:51 +0000 (01:58 +0000)
committerKostya Serebryany <kcc@google.com>
Fri, 23 Sep 2016 01:58:51 +0000 (01:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282224 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerCorpus.h
lib/Fuzzer/FuzzerDriver.cpp
lib/Fuzzer/FuzzerInternal.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerTracePC.h
lib/Fuzzer/test/FuzzerUnittest.cpp
lib/Fuzzer/test/merge.test
lib/Fuzzer/test/trace-pc/CMakeLists.txt

index d1a3efebe2d3ea9854c65583608dbdf3de763044..b9a066552733d316134f39525548bc1e384d94ce 100644 (file)
@@ -26,9 +26,6 @@ struct InputInfo {
   // Stats.
   uintptr_t NumExecutedMutations = 0;
   uintptr_t NumSuccessfullMutations = 0;
-
-  // A set of features (PCIDs, etc) that were first found with this unit.
-  std::vector<uintptr_t> Features;
 };
 
 class InputCorpus {
@@ -39,14 +36,13 @@ class InputCorpus {
   size_t size() const { return Inputs.size(); }
   bool empty() const { return Inputs.empty(); }
   const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; }
-  void AddToCorpus(const Unit &U, uintptr_t *Features, size_t NumFeatures) {
+  void AddToCorpus(const Unit &U) {
     uint8_t Hash[kSHA1NumBytes];
     ComputeSHA1(U.data(), U.size(), Hash);
     if (!Hashes.insert(Sha1ToString(Hash)).second) return;
     Inputs.push_back(InputInfo());
     InputInfo &II = Inputs.back();
     II.U = U;
-    II.Features.insert(II.Features.begin(), Features, Features + NumFeatures);
     memcpy(II.Sha1, Hash, kSHA1NumBytes);
     UpdateCorpusDistribution();
   }
@@ -72,10 +68,9 @@ class InputCorpus {
   void PrintStats() {
     for (size_t i = 0; i < Inputs.size(); i++) {
       const auto &II = Inputs[i];
-      Printf("  [%zd %s]\tsz: %zd\truns: %zd\tsucc: %zd\tfea: %zd\n", i,
+      Printf("  [%zd %s]\tsz: %zd\truns: %zd\tsucc: %zd\n", i,
              Sha1ToString(II.Sha1).c_str(), II.U.size(),
-             II.NumExecutedMutations, II.NumSuccessfullMutations,
-             II.Features.size());
+             II.NumExecutedMutations, II.NumSuccessfullMutations);
     }
   }
 
index f077d902d123646705230748361e29ced877faae..b826b9f0729631ea39c0ba21c678452fa35b6c3c 100644 (file)
@@ -342,7 +342,7 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
   Unit U = FileToVector(InputFilePath);
   assert(U.size() > 2);
   Printf("INFO: Starting MinimizeCrashInputInternalStep: %zd\n", U.size());
-  Corpus->AddToCorpus(U, nullptr, 0);
+  Corpus->AddToCorpus(U);
   F->SetMaxInputLen(U.size());
   F->SetMaxMutationLen(U.size() - 1);
   F->Loop();
index 7574e22347ffecd65ca99776ae3a7c7334333acf..23cdc6a84cc227545e8ae087b979b3a624e3307e 100644 (file)
@@ -110,7 +110,7 @@ private:
   bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
   void WriteToOutputCorpus(const Unit &U);
   void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
-  void PrintStats(const char *Where, const char *End = "\n");
+  void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
   void PrintStatusForNewUnit(const Unit &U);
   void ShuffleCorpus(UnitVector *V);
   void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
index 0ca03c5fea9314d53b9d494b33a23bd720f53819..c376d10dd516e5f5116542c9f1104c32a05451e4 100644 (file)
@@ -163,6 +163,7 @@ Fuzzer::Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
   assert(!F);
   F = this;
   TPC.ResetTotalPCCoverage();
+  TPC.Reset();
   ResetCoverage();
   IsMyThread = true;
   if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
@@ -309,7 +310,7 @@ void Fuzzer::RssLimitCallback() {
   _Exit(Options.ErrorExitCode); // Stop right now.
 }
 
-void Fuzzer::PrintStats(const char *Where, const char *End) {
+void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
   size_t ExecPerSec = execPerSec();
   if (Options.OutputCSV) {
     static bool csvHeaderPrinted = false;
@@ -337,7 +338,11 @@ void Fuzzer::PrintStats(const char *Where, const char *End) {
     Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge());
   if (MaxCoverage.CallerCalleeCoverage)
     Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
-  Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
+  if (size_t N = Corpus.size())
+    Printf(" units: %zd", N);
+  if (Units)
+    Printf(" units: %zd", Units);
+  Printf(" exec/s: %zd", ExecPerSec);
   Printf("%s", End);
 }
 
@@ -381,9 +386,7 @@ void Fuzzer::RereadOutputCorpus(size_t MaxSize) {
       X.resize(MaxSize);
     if (!Corpus.HasUnit(X)) {
       if (RunOne(X)) {
-        uintptr_t *NewPCIDs;
-        size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
-        Corpus.AddToCorpus(X, NewPCIDs, NumNewPCIDs);
+        Corpus.AddToCorpus(X);
         PrintStats("RELOAD");
       }
     }
@@ -406,9 +409,7 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) {
   for (const auto &U : *InitialCorpus) {
     bool NewCoverage = RunOne(U);
     if (!Options.PruneCorpus || NewCoverage) {
-      uintptr_t *NewPCIDs;
-      size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
-      Corpus.AddToCorpus(U, NewPCIDs, NumNewPCIDs);
+      Corpus.AddToCorpus(U);
       if (Options.Verbosity >= 2)
         Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());
     }
@@ -545,9 +546,7 @@ void Fuzzer::PrintNewPCs() {
 
 void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
   II->NumSuccessfullMutations++;
-  uintptr_t *NewPCIDs;
-  size_t NumNewPCIDs = TPC.GetNewPCIDs(&NewPCIDs);
-  Corpus.AddToCorpus(U, NewPCIDs, NumNewPCIDs);
+  Corpus.AddToCorpus(U);
   MD.RecordSuccessfulMutationSequence();
   PrintStatusForNewUnit(U);
   WriteToOutputCorpus(U);
@@ -566,6 +565,7 @@ UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
   size_t OldSize = Res.size();
   for (int Iter = 0; Iter < 10; Iter++) {
     ShuffleCorpus(&Res);
+    TPC.Reset();
     ResetCoverage();
 
     for (auto &U : Initial)
@@ -578,7 +578,7 @@ UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
 
     char Stat[7] = "MIN   ";
     Stat[3] = '0' + Iter;
-    PrintStats(Stat);
+    PrintStats(Stat, "\n", Tmp.size());
 
     size_t NewSize = Tmp.size();
     assert(NewSize <= OldSize);
@@ -691,7 +691,6 @@ void Fuzzer::MutateAndTestOne() {
 void Fuzzer::ResetCoverage() {
   ResetEdgeCoverage();
   MaxCoverage.Reset();
-  TPC.Reset();
   PrepareCounters(&MaxCoverage);
 }
 
index 19f67082930ad069639ca3a0a83e12eddb5f75b2..2139af300194ed09653d0cb546f6a5c929502c51 100644 (file)
@@ -46,6 +46,7 @@ class TracePC {
   void Reset() {
     NumNewPCIDs = 0;
     CounterMap.Reset();
+    ValueProfileMap.Reset();
     ResetGuards();
   }
 
index f2ac0e5f458acd6acb22fc5d8c9c287b1d47deba..fdde1d3fbb94318f5a70549e65f041bbbb9e53e0 100644 (file)
@@ -583,7 +583,7 @@ TEST(Corpus, Distribution) {
   size_t N = 10;
   size_t TriesPerUnit = 1<<20;
   for (size_t i = 0; i < N; i++)
-    C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, nullptr, 0);
+    C.AddToCorpus(Unit{ static_cast<uint8_t>(i) });
 
   std::vector<size_t> Hist(N);
   for (size_t i = 0; i < N * TriesPerUnit; i++) {
index b3dcc799457551f1d9239bbca5a42847a53364fb..0ef1b6f3069b29d4507a30d99a67ea13cb8adef4 100644 (file)
@@ -7,7 +7,8 @@ RUN: echo .U.... > %tmp/T1/2
 RUN: echo ..Z... > %tmp/T1/3
 
 # T1 has 3 elements, T2 is empty.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
+RUN: LLVMFuzzer-FullCoverageSetTest-TracePC -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
 CHECK1: === Minimizing the initial corpus of 3 units
 CHECK1: === Merge: written 0 units
 
@@ -19,13 +20,14 @@ RUN: echo .U.... > %tmp/T2/b
 RUN: echo ..Z... > %tmp/T2/c
 
 # T1 has 3 elements, T2 has 6 elements, only 3 are new.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
+RUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK2
 CHECK2: === Minimizing the initial corpus of 3 units
 CHECK2: === Merging extra 6 units
 CHECK2: === Merge: written 3 units
 
 # Now, T1 has 6 units and T2 has no new interesting units.
-RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-FullCoverageSetTest         -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
+RUN: LLVMFuzzer-FullCoverageSetTest-TracePC -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK3
 CHECK3: === Minimizing the initial corpus of 6 units
 CHECK3: === Merge: written 0 units
 
index ea160ccc502cc053932761e5d8a4076bfddc6d96..3def7271424e0baa584d1025bda7cb08979917a6 100644 (file)
@@ -9,6 +9,7 @@ set(TracePCTests
   CallerCalleeTest
   NullDerefTest
   MinimizeCorpusTest
+  FullCoverageSetTest
   )
 
 foreach(Test ${TracePCTests})