Index: lib/fuzzer/FuzzerDriver.cpp =================================================================== --- lib/fuzzer/FuzzerDriver.cpp +++ lib/fuzzer/FuzzerDriver.cpp @@ -619,7 +619,8 @@ Options.PrintCorpusStats = Flags.print_corpus_stats; Options.PrintCoverage = Flags.print_coverage; Options.PrintUnstableStats = Flags.print_unstable_stats; - if (Flags.handle_unstable == TracePC::MinUnstable) + if (Flags.handle_unstable == TracePC::MinUnstable && + Flags.handle_unstable == TracePC::PoisonUnstable) Options.HandleUnstable = Flags.handle_unstable; Options.DumpCoverage = Flags.dump_coverage; if (Flags.exit_on_src_pos) Index: lib/fuzzer/FuzzerInternal.h =================================================================== --- lib/fuzzer/FuzzerInternal.h +++ lib/fuzzer/FuzzerInternal.h @@ -67,8 +67,8 @@ static void StaticGracefulExitCallback(); void ExecuteCallback(const uint8_t *Data, size_t Size); - void CheckForUnstableCounters(const uint8_t *Data, size_t Size, - int UnstableMode); + int CheckForUnstableCounters(const uint8_t *Data, size_t Size, + int UnstableMode); bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr); Index: lib/fuzzer/FuzzerLoop.cpp =================================================================== --- lib/fuzzer/FuzzerLoop.cpp +++ lib/fuzzer/FuzzerLoop.cpp @@ -449,8 +449,8 @@ } } -void Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size, - int UnstableMode) { +int Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size, + int UnstableMode) { auto CBSetupAndRun = [&]() { ScopedEnableMsanInterceptorChecks S; UnitStartTime = system_clock::now(); @@ -461,20 +461,24 @@ UnitStopTime = system_clock::now(); }; + int NumNewUnstableEdges = 0; + // Copy original run counters into our unstable counters TPC.InitializeUnstableCounters(); // First Rerun CBSetupAndRun(); - TPC.UpdateUnstableCounters(UnstableMode); + NumNewUnstableEdges += TPC.UpdateUnstableCounters(UnstableMode); // Second Rerun CBSetupAndRun(); - TPC.UpdateUnstableCounters(UnstableMode); + NumNewUnstableEdges += TPC.UpdateUnstableCounters(UnstableMode); // Move minimum hit counts back to ModuleInline8bitCounters if (UnstableMode == TPC.MinUnstable) TPC.ApplyUnstableCounters(); + + return NumNewUnstableEdges; } bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, @@ -488,6 +492,7 @@ size_t FoundUniqFeaturesOfII = 0; size_t NumUpdatesBefore = Corpus.NumFeatureUpdates(); int NumNewFeaturesForUnstable = 0; + int NumNewUnstableEdges = 0; if (Options.HandleUnstable || Options.PrintUnstableStats) { TPC.CollectFeatures([&](size_t Feature) { @@ -495,7 +500,8 @@ NumNewFeaturesForUnstable++; }); if (NumNewFeaturesForUnstable) - CheckForUnstableCounters(Data, Size, Options.HandleUnstable); + NumNewUnstableEdges = + CheckForUnstableCounters(Data, Size, Options.HandleUnstable); } TPC.CollectFeatures([&](size_t Feature) { @@ -512,6 +518,9 @@ PrintPulseAndReportSlowInput(Data, Size); size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore; + if (Options.HandleUnstable == TPC.PoisonUnstable) + NumNewFeatures -= NumNewUnstableEdges; + if (NumNewFeatures) { TPC.UpdateObservedPCs(); Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile, Index: lib/fuzzer/FuzzerTracePC.h =================================================================== --- lib/fuzzer/FuzzerTracePC.h +++ lib/fuzzer/FuzzerTracePC.h @@ -75,6 +75,7 @@ enum HandleUnstableOptions { MinUnstable = 1, + PoisonUnstable = 2, }; void HandleInit(uint32_t *Start, uint32_t *Stop); @@ -141,7 +142,7 @@ bool ObservedFocusFunction(); void InitializeUnstableCounters(); - void UpdateUnstableCounters(int UnstableMode); + int UpdateUnstableCounters(int UnstableMode); void ApplyUnstableCounters(); private: Index: lib/fuzzer/FuzzerTracePC.cpp =================================================================== --- lib/fuzzer/FuzzerTracePC.cpp +++ lib/fuzzer/FuzzerTracePC.cpp @@ -81,14 +81,20 @@ // Compares the current counters with counters from previous runs // and records differences as unstable edges. -void TracePC::UpdateUnstableCounters(int UnstableMode) { +int TracePC::UpdateUnstableCounters(int UnstableMode) { + int NumNewUnstableEdges = 0; IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { - if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) + if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) { + // Check if it is a new unstable edge. + if (!UnstableCounters[UnstableIdx].IsUnstable) + NumNewUnstableEdges++; UnstableCounters[UnstableIdx].IsUnstable = true; + } if (UnstableMode == MinUnstable && ModuleCounters[i].Start[j] < UnstableCounters[UnstableIdx].Counter) UnstableCounters[UnstableIdx].Counter = ModuleCounters[i].Start[j]; }); + return NumNewUnstableEdges; } // Moves the minimum hit counts to ModuleCounters.