From 763d4bc96b9c8dd4fb5d2c378f26966106a67a56 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Fri, 23 Sep 2016 01:58:51 +0000 Subject: [PATCH] [libFuzzer] fix merging with trace-pc-guard llvm-svn: 282224 --- lib/Fuzzer/FuzzerCorpus.h | 11 +++-------- lib/Fuzzer/FuzzerDriver.cpp | 2 +- lib/Fuzzer/FuzzerInternal.h | 2 +- lib/Fuzzer/FuzzerLoop.cpp | 25 ++++++++++++------------- lib/Fuzzer/FuzzerTracePC.h | 1 + lib/Fuzzer/test/FuzzerUnittest.cpp | 2 +- lib/Fuzzer/test/merge.test | 8 +++++--- lib/Fuzzer/test/trace-pc/CMakeLists.txt | 1 + 8 files changed, 25 insertions(+), 27 deletions(-) diff --git a/lib/Fuzzer/FuzzerCorpus.h b/lib/Fuzzer/FuzzerCorpus.h index d1a3efebe2d..b9a06655273 100644 --- a/lib/Fuzzer/FuzzerCorpus.h +++ b/lib/Fuzzer/FuzzerCorpus.h @@ -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 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); } } diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index f077d902d12..b826b9f0729 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -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(); diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 7574e22347f..23cdc6a84cc 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -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, diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 0ca03c5fea9..c376d10dd51 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -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); } diff --git a/lib/Fuzzer/FuzzerTracePC.h b/lib/Fuzzer/FuzzerTracePC.h index 19f67082930..2139af30019 100644 --- a/lib/Fuzzer/FuzzerTracePC.h +++ b/lib/Fuzzer/FuzzerTracePC.h @@ -46,6 +46,7 @@ class TracePC { void Reset() { NumNewPCIDs = 0; CounterMap.Reset(); + ValueProfileMap.Reset(); ResetGuards(); } diff --git a/lib/Fuzzer/test/FuzzerUnittest.cpp b/lib/Fuzzer/test/FuzzerUnittest.cpp index f2ac0e5f458..fdde1d3fbb9 100644 --- a/lib/Fuzzer/test/FuzzerUnittest.cpp +++ b/lib/Fuzzer/test/FuzzerUnittest.cpp @@ -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(i) }, nullptr, 0); + C.AddToCorpus(Unit{ static_cast(i) }); std::vector Hist(N); for (size_t i = 0; i < N * TriesPerUnit; i++) { diff --git a/lib/Fuzzer/test/merge.test b/lib/Fuzzer/test/merge.test index b3dcc799457..0ef1b6f3069 100644 --- a/lib/Fuzzer/test/merge.test +++ b/lib/Fuzzer/test/merge.test @@ -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 diff --git a/lib/Fuzzer/test/trace-pc/CMakeLists.txt b/lib/Fuzzer/test/trace-pc/CMakeLists.txt index ea160ccc502..3def7271424 100644 --- a/lib/Fuzzer/test/trace-pc/CMakeLists.txt +++ b/lib/Fuzzer/test/trace-pc/CMakeLists.txt @@ -9,6 +9,7 @@ set(TracePCTests CallerCalleeTest NullDerefTest MinimizeCorpusTest + FullCoverageSetTest ) foreach(Test ${TracePCTests})