Index: lib/fuzzer/FuzzerLoop.cpp =================================================================== --- lib/fuzzer/FuzzerLoop.cpp +++ lib/fuzzer/FuzzerLoop.cpp @@ -466,16 +466,11 @@ // First Rerun CBSetupAndRun(); - TPC.UpdateUnstableCounters(Options.HandleUnstable); - - // Second Rerun - CBSetupAndRun(); - TPC.UpdateUnstableCounters(Options.HandleUnstable); - - // Move minimum hit counts back to ModuleInline8bitCounters - if (Options.HandleUnstable == TracePC::MinUnstable || - Options.HandleUnstable == TracePC::ZeroUnstable) - TPC.ApplyUnstableCounters(); + if (TPC.UpdateUnstableCounters(Options.HandleUnstable)) { + // Second Rerun + CBSetupAndRun(); + TPC.UpdateAndApplyUnstableCounters(Options.HandleUnstable); + } } bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, Index: lib/fuzzer/FuzzerTracePC.h =================================================================== --- lib/fuzzer/FuzzerTracePC.h +++ lib/fuzzer/FuzzerTracePC.h @@ -143,8 +143,8 @@ bool ObservedFocusFunction(); void InitializeUnstableCounters(); - void UpdateUnstableCounters(int UnstableMode); - void ApplyUnstableCounters(); + bool UpdateUnstableCounters(int UnstableMode); + void UpdateAndApplyUnstableCounters(int UnstableMode); private: struct UnstableEdge { Index: lib/fuzzer/FuzzerTracePC.cpp =================================================================== --- lib/fuzzer/FuzzerTracePC.cpp +++ lib/fuzzer/FuzzerTracePC.cpp @@ -81,9 +81,11 @@ // Compares the current counters with counters from previous runs // and records differences as unstable edges. -void TracePC::UpdateUnstableCounters(int UnstableMode) { +bool TracePC::UpdateUnstableCounters(int UnstableMode) { + bool Updated = false; IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) { + Updated = true; UnstableCounters[UnstableIdx].IsUnstable = true; if (UnstableMode == ZeroUnstable) UnstableCounters[UnstableIdx].Counter = 0; @@ -92,12 +94,20 @@ ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter); } }); + return Updated; } -// Moves the minimum hit counts to ModuleCounters. -void TracePC::ApplyUnstableCounters() { +// Updates and applies unstable counters to ModuleCounters in single iteration +void TracePC::UpdateAndApplyUnstableCounters(int UnstableMode) { IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { - ModuleCounters[i].Start[j] = UnstableCounters[UnstableIdx].Counter; + if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) { + UnstableCounters[UnstableIdx].IsUnstable = true; + if (UnstableMode == ZeroUnstable) + ModuleCounters[i].Start[j] = 0; + else if (UnstableMode == MinUnstable) + ModuleCounters[i].Start[j] = std::min( + ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter); + } }); }