From: Kostya Serebryany Date: Wed, 5 Oct 2016 22:56:21 +0000 (+0000) Subject: [libFuzzer] refactoring to make -shrink=1 work for value profile, added a test. X-Git-Tag: android-x86-7.1-r4~26187 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=cc6cbfdebc417cf8869b855f759b7996203f4688;p=android-x86%2Fexternal-llvm.git [libFuzzer] refactoring to make -shrink=1 work for value profile, added a test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283409 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Fuzzer/FuzzerCorpus.h b/lib/Fuzzer/FuzzerCorpus.h index ea4f0c706c7..a46f1dccb45 100644 --- a/lib/Fuzzer/FuzzerCorpus.h +++ b/lib/Fuzzer/FuzzerCorpus.h @@ -34,9 +34,11 @@ struct InputInfo { class InputCorpus { public: + static const size_t kFeatureSetSize = 1 << 16; InputCorpus() { Inputs.reserve(1 << 14); // Avoid too many resizes. - memset(FeatureSet, 0, sizeof(FeatureSet)); + memset(InputSizesPerFeature, 0, sizeof(InputSizesPerFeature)); + memset(SmallestElementPerFeature, 0, sizeof(SmallestElementPerFeature)); } size_t size() const { return Inputs.size(); } size_t SizeInBytes() const { @@ -53,17 +55,20 @@ class InputCorpus { } bool empty() const { return Inputs.empty(); } const Unit &operator[] (size_t Idx) const { return Inputs[Idx].U; } - void AddToCorpus(const Unit &U) { + void AddToCorpus(const Unit &U, size_t NumFeatures) { assert(!U.empty()); uint8_t Hash[kSHA1NumBytes]; + if (FeatureDebug) + Printf("ADD_TO_CORPUS %zd NF %zd\n", Inputs.size(), NumFeatures); ComputeSHA1(U.data(), U.size(), Hash); - if (!Hashes.insert(Sha1ToString(Hash)).second) return; + Hashes.insert(Sha1ToString(Hash)); Inputs.push_back(InputInfo()); InputInfo &II = Inputs.back(); II.U = U; + II.NumFeatures = NumFeatures; memcpy(II.Sha1, Hash, kSHA1NumBytes); - UpdateFeatureSet(Inputs.size() - 1); UpdateCorpusDistribution(); + ValidateFeatureSet(); } typedef const std::vector::const_iterator ConstIter; @@ -97,12 +102,9 @@ class InputCorpus { } void PrintFeatureSet() { - Printf("Features [id: idx sz] "); for (size_t i = 0; i < kFeatureSetSize; i++) { - auto &Fe = FeatureSet[i]; - if (!Fe.Count) continue; - Printf("[%zd: %zd %zd] ", i, Fe.SmallestElementIdx, - Fe.SmallestElementSize); + if(size_t Sz = GetFeature(i)) + Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz); } Printf("\n\t"); for (size_t i = 0; i < Inputs.size(); i++) @@ -111,57 +113,59 @@ class InputCorpus { Printf("\n"); } + bool AddFeature(size_t Idx, uint32_t NewSize, bool Shrink) { + assert(NewSize); + Idx = Idx % kFeatureSetSize; + uint32_t OldSize = GetFeature(Idx); + if (OldSize == 0 || (Shrink && OldSize > NewSize)) { + if (OldSize > 0) { + InputInfo &II = Inputs[SmallestElementPerFeature[Idx]]; + assert(II.NumFeatures > 0); + II.NumFeatures--; + if (II.NumFeatures == 0) { + II.U.clear(); + if (FeatureDebug) + Printf("EVICTED %zd\n", SmallestElementPerFeature[Idx]); + } + } + if (FeatureDebug) + Printf("ADD FEATURE %zd sz %d\n", Idx, NewSize); + SmallestElementPerFeature[Idx] = Inputs.size(); + InputSizesPerFeature[Idx] = NewSize; + CountingFeatures = true; + return true; + } + return false; + } + + size_t NumFeatures() const { + size_t Res = 0; + for (size_t i = 0; i < kFeatureSetSize; i++) + Res += GetFeature(i) != 0; + return Res; + } + private: static const bool FeatureDebug = false; - static const size_t kFeatureSetSize = TracePC::kFeatureSetSize; + + size_t GetFeature(size_t Idx) const { return InputSizesPerFeature[Idx]; } void ValidateFeatureSet() { - for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) { - Feature &Fe = FeatureSet[Idx]; - if(Fe.Count && Fe.SmallestElementSize) - Inputs[Fe.SmallestElementIdx].Tmp++; - } + if (!CountingFeatures) return; + if (FeatureDebug) + PrintFeatureSet(); + for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) + if (GetFeature(Idx)) + Inputs[SmallestElementPerFeature[Idx]].Tmp++; for (auto &II: Inputs) { + if (II.Tmp != II.NumFeatures) + Printf("ZZZ %zd %zd\n", II.Tmp, II.NumFeatures); assert(II.Tmp == II.NumFeatures); II.Tmp = 0; } } - void UpdateFeatureSet(size_t CurrentElementIdx) { - auto &II = Inputs[CurrentElementIdx]; - size_t Size = II.U.size(); - if (!Size) - return; - bool Updated = false; - for (size_t Idx = 0; Idx < kFeatureSetSize; Idx++) { - if (!TPC.HasFeature(Idx)) - continue; - Feature &Fe = FeatureSet[Idx]; - Fe.Count++; - if (!Fe.SmallestElementSize || - Fe.SmallestElementSize > Size) { - II.NumFeatures++; - CountingFeatures = true; - if (Fe.SmallestElementSize > Size) { - auto &OlderII = Inputs[Fe.SmallestElementIdx]; - assert(OlderII.NumFeatures > 0); - OlderII.NumFeatures--; - 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; - Updated = true; - } - } - if (Updated && FeatureDebug) PrintFeatureSet(); - ValidateFeatureSet(); - } - // Updates the probability distribution for the units in the corpus. // Must be called whenever the corpus or unit weights are changed. void UpdateCorpusDistribution() { @@ -185,13 +189,9 @@ private: std::unordered_set Hashes; std::vector Inputs; - struct Feature { - size_t Count; - size_t SmallestElementIdx; - size_t SmallestElementSize; - }; bool CountingFeatures = false; - Feature FeatureSet[kFeatureSetSize]; + uint32_t InputSizesPerFeature[kFeatureSetSize]; + uint32_t SmallestElementPerFeature[kFeatureSetSize]; }; } // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index d0de517920d..fd88d50cfa8 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); + Corpus->AddToCorpus(U, 0); F->SetMaxInputLen(U.size()); F->SetMaxMutationLen(U.size() - 1); F->Loop(); diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index 29e810b0f6d..9ea5c96fe4b 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -42,17 +42,13 @@ public: CounterBitmapBits = 0; CounterBitmap.clear(); VPMap.Reset(); - TPCMap.Reset(); } - std::string DebugString() const; - size_t BlockCoverage; size_t CallerCalleeCoverage; // Precalculated number of bits in CounterBitmap. size_t CounterBitmapBits; std::vector CounterBitmap; - ValueBitMap TPCMap; ValueBitMap VPMap; }; @@ -80,7 +76,7 @@ public: static void StaticInterruptCallback(); void ExecuteCallback(const uint8_t *Data, size_t Size); - bool RunOne(const uint8_t *Data, size_t Size); + size_t RunOne(const uint8_t *Data, size_t Size); // Merge Corpora[1:] into Corpora[0]. void Merge(const std::vector &Corpora); @@ -106,7 +102,7 @@ private: void ReportNewCoverage(InputInfo *II, const Unit &U); void PrintNewPCs(); void PrintOneNewPC(uintptr_t PC); - bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); } + size_t 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", size_t Units = 0); diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 35d68bce694..6c1f376d8ef 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -299,18 +299,18 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) { Printf("#%zd\t%s", TotalNumberOfRuns, Where); if (MaxCoverage.BlockCoverage) Printf(" cov: %zd", MaxCoverage.BlockCoverage); + if (size_t N = MaxCoverage.VPMap.GetNumBitsSinceLastMerge()) + Printf(" vp: %zd", N); if (size_t N = TPC.GetTotalPCCoverage()) Printf(" cov: %zd", N); - if (MaxCoverage.VPMap.GetNumBitsSinceLastMerge()) - Printf(" vp: %zd", MaxCoverage.VPMap.GetNumBitsSinceLastMerge()); if (auto TB = MaxCoverage.CounterBitmapBits) Printf(" bits: %zd", TB); - if (auto TB = MaxCoverage.TPCMap.GetNumBitsSinceLastMerge()) - Printf(" bits: %zd", MaxCoverage.TPCMap.GetNumBitsSinceLastMerge()); + if (size_t N = Corpus.NumFeatures()) + Printf( " ft: %zd", N); if (MaxCoverage.CallerCalleeCoverage) Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage); if (size_t N = Corpus.size()) { - Printf(" corpus: %zd", Corpus.NumActiveUnits()); + Printf(" corp: %zd", Corpus.NumActiveUnits()); if (size_t N = Corpus.SizeInBytes()) { if (N < (1<<14)) Printf("/%zdb", N); @@ -392,8 +392,8 @@ void Fuzzer::RereadOutputCorpus(size_t MaxSize) { if (U.size() > MaxSize) U.resize(MaxSize); if (!Corpus.HasUnit(U)) { - if (RunOne(U)) { - Corpus.AddToCorpus(U); + if (size_t NumFeatures = RunOne(U)) { + Corpus.AddToCorpus(U, NumFeatures); PrintStats("RELOAD"); } } @@ -418,8 +418,8 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) { ExecuteCallback(&dummy, 0); for (const auto &U : *InitialCorpus) { - if (RunOne(U)) { - Corpus.AddToCorpus(U); + if (size_t NumFeatures = RunOne(U)) { + Corpus.AddToCorpus(U, NumFeatures); if (Options.Verbosity >= 2) Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size()); } @@ -434,27 +434,23 @@ void Fuzzer::ShuffleAndMinimize(UnitVector *InitialCorpus) { } } -bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) { +size_t Fuzzer::RunOne(const uint8_t *Data, size_t Size) { + if (!Size) return 0; TotalNumberOfRuns++; ExecuteCallback(Data, Size); - bool Res = false; - if (TPC.FinalizeTrace(Size)) - if (Options.Shrink) - Res = true; - - if (!Res) { - if (TPC.UpdateCounterMap(&MaxCoverage.TPCMap)) - Res = true; + size_t Res = 0; + if (size_t NumFeatures = TPC.FinalizeTrace(&Corpus, Size, Options.Shrink)) + Res = NumFeatures; + if (!TPC.UsingTracePcGuard()) { if (TPC.UpdateValueProfileMap(&MaxCoverage.VPMap)) - Res = true; + Res = 1; + if (!Res && RecordMaxCoverage(&MaxCoverage)) + Res = 1; } - if (RecordMaxCoverage(&MaxCoverage)) - Res = true; - CheckExitOnSrcPos(); auto TimeOfUnit = duration_cast(UnitStopTime - UnitStartTime).count(); @@ -500,16 +496,6 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) { delete[] DataCopy; } -std::string Fuzzer::Coverage::DebugString() const { - std::string Result = - std::string("Coverage{") + "BlockCoverage=" + - std::to_string(BlockCoverage) + " CallerCalleeCoverage=" + - std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" + - std::to_string(CounterBitmapBits) + " VPMapBits " + - std::to_string(VPMap.GetNumBitsSinceLastMerge()) + "}"; - return Result; -} - void Fuzzer::WriteToOutputCorpus(const Unit &U) { if (Options.OnlyASCII) assert(IsASCII(U)); @@ -694,8 +680,9 @@ void Fuzzer::MutateAndTestOne() { if (i == 0) StartTraceRecording(); II.NumExecutedMutations++; - if (RunOne(CurrentUnitData, Size)) { - Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}); + if (size_t NumFeatures = RunOne(CurrentUnitData, Size)) { + Corpus.AddToCorpus({CurrentUnitData, CurrentUnitData + Size}, + NumFeatures); ReportNewCoverage(&II, {CurrentUnitData, CurrentUnitData + Size}); CheckExitOnItem(); } diff --git a/lib/Fuzzer/FuzzerTracePC.cpp b/lib/Fuzzer/FuzzerTracePC.cpp index c752002ab0f..aa5bd9b6087 100644 --- a/lib/Fuzzer/FuzzerTracePC.cpp +++ b/lib/Fuzzer/FuzzerTracePC.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "FuzzerCorpus.h" #include "FuzzerDefs.h" #include "FuzzerTracePC.h" #include "FuzzerValueBitMap.h" @@ -68,45 +69,46 @@ void TracePC::ResetGuards() { assert(N == NumGuards); } -bool TracePC::FinalizeTrace(size_t InputSize) { - bool Res = false; - if (TotalPCCoverage) { - const size_t Step = 8; - assert(reinterpret_cast(Counters) % Step == 0); - size_t N = Min(kNumCounters, NumGuards + 1); - N = (N + Step - 1) & ~(Step - 1); // Round up. - for (size_t Idx = 0; Idx < N; Idx += Step) { - uint64_t Bundle = *reinterpret_cast(&Counters[Idx]); - if (!Bundle) continue; - for (size_t i = Idx; i < Idx + Step; i++) { - uint8_t Counter = (Bundle >> (i * 8)) & 0xff; - if (!Counter) continue; - Counters[i] = 0; - unsigned Bit = 0; - /**/ if (Counter >= 128) Bit = 7; - else if (Counter >= 32) Bit = 6; - else if (Counter >= 16) Bit = 5; - else if (Counter >= 8) Bit = 4; - else if (Counter >= 4) Bit = 3; - else if (Counter >= 3) Bit = 2; - else if (Counter >= 2) Bit = 1; - size_t Feature = i * 8 + Bit; - CounterMap.AddValue(Feature); - uint32_t *SizePtr = &InputSizesPerFeature[Feature % kFeatureSetSize]; - if (!*SizePtr || *SizePtr > InputSize) { - *SizePtr = InputSize; - Res = true; - } - } +size_t TracePC::FinalizeTrace(InputCorpus *C, size_t InputSize, bool Shrink) { + if (!UsingTracePcGuard()) return 0; + size_t Res = 0; + const size_t Step = 8; + assert(reinterpret_cast(Counters) % Step == 0); + size_t N = Min(kNumCounters, NumGuards + 1); + N = (N + Step - 1) & ~(Step - 1); // Round up. + for (size_t Idx = 0; Idx < N; Idx += Step) { + uint64_t Bundle = *reinterpret_cast(&Counters[Idx]); + if (!Bundle) continue; + for (size_t i = Idx; i < Idx + Step; i++) { + uint8_t Counter = (Bundle >> (i * 8)) & 0xff; + if (!Counter) continue; + Counters[i] = 0; + unsigned Bit = 0; + /**/ if (Counter >= 128) Bit = 7; + else if (Counter >= 32) Bit = 6; + else if (Counter >= 16) Bit = 5; + else if (Counter >= 8) Bit = 4; + else if (Counter >= 4) Bit = 3; + else if (Counter >= 3) Bit = 2; + else if (Counter >= 2) Bit = 1; + size_t Feature = (i * 8 + Bit); + if (C->AddFeature(Feature, InputSize, Shrink)) + Res++; } } + if (UseValueProfile) + ValueProfileMap.ForEach([&](size_t Idx) { + if (C->AddFeature(NumGuards + Idx, InputSize, Shrink)) + Res++; + }); return Res; } void TracePC::HandleCallerCallee(uintptr_t Caller, uintptr_t Callee) { const uintptr_t kBits = 12; const uintptr_t kMask = (1 << kBits) - 1; - CounterMap.AddValue((Caller & kMask) | ((Callee & kMask) << kBits)); + uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits); + HandleValueProfile(Idx); } void TracePC::PrintCoverage() { @@ -163,11 +165,9 @@ void TracePC::AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2, ATTRIBUTE_TARGET_POPCNT static void AddValueForCmp(void *PCptr, uint64_t Arg1, uint64_t Arg2) { - if (Arg1 == Arg2) - return; uintptr_t PC = reinterpret_cast(PCptr); - uint64_t ArgDistance = __builtin_popcountl(Arg1 ^ Arg2) - 1; // [0,63] - uintptr_t Idx = (PC & 4095) | (ArgDistance << 12); + uint64_t ArgDistance = __builtin_popcountl(Arg1 ^ Arg2) + 1; // [1,65] + uintptr_t Idx = ((PC & 4095) + 1) * ArgDistance; TPC.HandleValueProfile(Idx); } diff --git a/lib/Fuzzer/FuzzerTracePC.h b/lib/Fuzzer/FuzzerTracePC.h index a96a2c087e2..49f7faa6a1a 100644 --- a/lib/Fuzzer/FuzzerTracePC.h +++ b/lib/Fuzzer/FuzzerTracePC.h @@ -29,13 +29,11 @@ class TracePC { void ResetTotalPCCoverage() { TotalPCCoverage = 0; } void SetUseCounters(bool UC) { UseCounters = UC; } void SetUseValueProfile(bool VP) { UseValueProfile = VP; } - bool UpdateCounterMap(ValueBitMap *MaxCounterMap) { - return MaxCounterMap->MergeFrom(CounterMap); - } + size_t FinalizeTrace(InputCorpus *C, size_t InputSize, bool Shrink); bool UpdateValueProfileMap(ValueBitMap *MaxValueProfileMap) { return UseValueProfile && MaxValueProfileMap->MergeFrom(ValueProfileMap); - } - bool FinalizeTrace(size_t InputSize); + } + size_t GetNewPCIDs(uintptr_t **NewPCIDsPtr) { *NewPCIDsPtr = NewPCIDs; @@ -46,7 +44,6 @@ class TracePC { void ResetMaps() { NumNewPCIDs = 0; - CounterMap.Reset(); ValueProfileMap.Reset(); memset(Counters, 0, sizeof(Counters)); } @@ -60,13 +57,13 @@ class TracePC { void PrintCoverage(); - bool HasFeature(size_t Idx) { return CounterMap.Get(Idx); } - void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2, size_t n); void AddValueForStrcmp(void *caller_pc, const char *s1, const char *s2, size_t n); + bool UsingTracePcGuard() const {return NumModules; } + private: bool UseCounters = false; bool UseValueProfile = false; @@ -93,9 +90,7 @@ private: static const size_t kNumPCs = 1 << 20; uintptr_t PCs[kNumPCs]; - ValueBitMap CounterMap; ValueBitMap ValueProfileMap; - uint32_t InputSizesPerFeature[kFeatureSetSize]; }; extern TracePC TPC; diff --git a/lib/Fuzzer/FuzzerValueBitMap.h b/lib/Fuzzer/FuzzerValueBitMap.h index 97f4c5e51b9..0692acd13ee 100644 --- a/lib/Fuzzer/FuzzerValueBitMap.h +++ b/lib/Fuzzer/FuzzerValueBitMap.h @@ -68,6 +68,15 @@ struct ValueBitMap { return OldNumBits < NumBits; } + template + void ForEach(Callback CB) { + for (size_t i = 0; i < kMapSizeInWords; i++) + if (uintptr_t M = Map[i]) + for (size_t j = 0; j < sizeof(M) * 8; j++) + if (M & ((uintptr_t)1 << j)) + CB(i * sizeof(M) * 8 + j); + } + private: size_t NumBits = 0; uintptr_t Map[kMapSizeInWords] __attribute__((aligned(512))); diff --git a/lib/Fuzzer/test/FuzzerUnittest.cpp b/lib/Fuzzer/test/FuzzerUnittest.cpp index fdde1d3fbb9..ed37055fe45 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) }); + C.AddToCorpus(Unit{ static_cast(i) }, 0); std::vector Hist(N); for (size_t i = 0; i < N * TriesPerUnit; i++) { diff --git a/lib/Fuzzer/test/ShrinkControlFlowTest.cpp b/lib/Fuzzer/test/ShrinkControlFlowTest.cpp index 2fa17f156e2..0fd7c5e9a1f 100644 --- a/lib/Fuzzer/test/ShrinkControlFlowTest.cpp +++ b/lib/Fuzzer/test/ShrinkControlFlowTest.cpp @@ -21,7 +21,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { int Z = Ids[(unsigned char)'Z']; if (F >= 0 && U > F && Z > U) { Sink++; - // fprintf(stderr, "IDS: %d %d %d\n", F, U, Z); + //fprintf(stderr, "IDS: %d %d %d\n", F, U, Z); } return 0; } diff --git a/lib/Fuzzer/test/ShrinkValueProfileTest.cpp b/lib/Fuzzer/test/ShrinkValueProfileTest.cpp index 9ff5b19c7b6..026b8ce2659 100644 --- a/lib/Fuzzer/test/ShrinkValueProfileTest.cpp +++ b/lib/Fuzzer/test/ShrinkValueProfileTest.cpp @@ -12,10 +12,11 @@ static volatile uint32_t Sink; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { if (Size < sizeof(uint32_t)) return 0; - uint32_t X; + uint32_t X, Y; size_t Offset = Size < 8 ? 0 : Size / 2; memcpy(&X, Data + Offset, sizeof(uint32_t)); - Sink = X == 0xAABBCCDD; + memcpy(&Y, "FUZZ", sizeof(uint32_t)); + Sink = X == Y; return 0; } diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test index 98139c09d6f..fe408596f5f 100644 --- a/lib/Fuzzer/test/fuzzer.test +++ b/lib/Fuzzer/test/fuzzer.test @@ -27,13 +27,13 @@ NULL_DEREF_ON_EMPTY: stat::number_of_executed_units: RUN: not LLVMFuzzer-CounterTest -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS RUN: not LLVMFuzzer-CounterTest-TracePC -use_counters=1 -max_len=6 -seed=1 -timeout=15 2>&1 | FileCheck %s --check-prefix=COUNTERS -COUNTERS: INITED {{.*}} bits: -COUNTERS: NEW {{.*}} bits: {{[1-9]*}} -COUNTERS: NEW {{.*}} bits: {{[1-9]*}} +COUNTERS: INITED {{.*}} {{bits:|ft:}} +COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}} +COUNTERS: NEW {{.*}} {{bits:|ft:}} {{[1-9]*}} COUNTERS: BINGO -RUN: not LLVMFuzzer-CallerCalleeTest -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s -RUN: not LLVMFuzzer-CallerCalleeTest-TracePC -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-CallerCalleeTest -use_value_profile=1 -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s +RUN: not LLVMFuzzer-CallerCalleeTest-TracePC -use_value_profile=1 -cross_over=0 -max_len=6 -seed=1 -max_total_time=15 2>&1 | FileCheck %s # This one is flaky, may actually find the goal even w/o use_indir_calls. # LLVMFuzzer-CallerCalleeTest -use_indir_calls=0 -cross_over=0 -max_len=6 -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000 diff --git a/lib/Fuzzer/test/shrink.test b/lib/Fuzzer/test/shrink.test new file mode 100644 index 00000000000..68206f0901b --- /dev/null +++ b/lib/Fuzzer/test/shrink.test @@ -0,0 +1,7 @@ +RUN: LLVMFuzzer-ShrinkControlFlowTest-TracePC -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=1 2>&1 | FileCheck %s --check-prefix=SHRINK1 +RUN: LLVMFuzzer-ShrinkControlFlowTest-TracePC -seed=1 -exit_on_item=0eb8e4ed029b774d80f2b66408203801cb982a60 -runs=1000000 -shrink=0 2>&1 | FileCheck %s --check-prefix=SHRINK0 +RUN: LLVMFuzzer-ShrinkValueProfileTest-TracePC -seed=1 -exit_on_item=aea2e3923af219a8956f626558ef32f30a914ebc -runs=100000 -shrink=1 -use_value_profile=1 2>&1 | FileCheck %s --check-prefix=SHRINK1_VP + +SHRINK0: Done 1000000 runs in +SHRINK1: INFO: found item with checksum '0eb8e4ed029b774d80f2b66408203801cb982a60', exiting. +SHRINK1_VP: INFO: found item with checksum 'aea2e3923af219a8956f626558ef32f30a914ebc', exiting