Index: compiler-rt/lib/fuzzer/FuzzerCorpus.h =================================================================== --- compiler-rt/lib/fuzzer/FuzzerCorpus.h +++ compiler-rt/lib/fuzzer/FuzzerCorpus.h @@ -238,12 +238,6 @@ return false; } - bool IsFeatureNew(size_t Idx, uint32_t NewSize, bool Shrink) { - assert(NewSize); - uint32_t OldSize = GetFeature(Idx % kFeatureSetSize); - return OldSize == 0 || (Shrink && OldSize > NewSize); - } - size_t NumFeatures() const { return NumAddedFeatures; } size_t NumFeatureUpdates() const { return NumUpdatedFeatures; } Index: compiler-rt/lib/fuzzer/FuzzerDriver.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -617,10 +617,6 @@ Options.PrintFinalStats = Flags.print_final_stats; Options.PrintCorpusStats = Flags.print_corpus_stats; Options.PrintCoverage = Flags.print_coverage; - Options.PrintUnstableStats = Flags.print_unstable_stats; - if (Flags.handle_unstable == TracePC::MinUnstable || - Flags.handle_unstable == TracePC::ZeroUnstable) - Options.HandleUnstable = Flags.handle_unstable; Options.DumpCoverage = Flags.dump_coverage; if (Flags.exit_on_src_pos) Options.ExitOnSrcPos = Flags.exit_on_src_pos; Index: compiler-rt/lib/fuzzer/FuzzerFlags.def =================================================================== --- compiler-rt/lib/fuzzer/FuzzerFlags.def +++ compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -110,15 +110,6 @@ FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated." " If 1, dump coverage information as a" " .sancov file at exit.") -FUZZER_FLAG_INT(handle_unstable, 0, "Experimental." - " Executes every input 3 times in total if a unique feature" - " is found during the first execution." - " If 1, we only use the minimum hit count from the 3 runs" - " to determine whether an input is interesting." - " If 2, we disregard edges that are found unstable for" - " feature collection.") -FUZZER_FLAG_INT(print_unstable_stats, 0, "Experimental." - " If 1, print unstable statistics at exit.") FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.") FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.") FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.") Index: compiler-rt/lib/fuzzer/FuzzerInternal.h =================================================================== --- compiler-rt/lib/fuzzer/FuzzerInternal.h +++ compiler-rt/lib/fuzzer/FuzzerInternal.h @@ -67,7 +67,6 @@ static void StaticGracefulExitCallback(); void ExecuteCallback(const uint8_t *Data, size_t Size); - void CheckForUnstableCounters(const uint8_t *Data, size_t Size); bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false, InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr); Index: compiler-rt/lib/fuzzer/FuzzerLoop.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -355,8 +355,6 @@ void Fuzzer::PrintFinalStats() { if (Options.PrintCoverage) TPC.PrintCoverage(); - if (Options.PrintUnstableStats) - TPC.PrintUnstableStats(); if (Options.DumpCoverage) TPC.DumpCoverage(); if (Options.PrintCorpusStats) @@ -449,29 +447,6 @@ } } -void Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size) { - auto CBSetupAndRun = [&]() { - ScopedEnableMsanInterceptorChecks S; - UnitStartTime = system_clock::now(); - TPC.ResetMaps(); - RunningUserCallback = true; - CB(Data, Size); - RunningUserCallback = false; - UnitStopTime = system_clock::now(); - }; - - // Copy original run counters into our unstable counters - TPC.InitializeUnstableCounters(); - - // First Rerun - CBSetupAndRun(); - if (TPC.UpdateUnstableCounters(Options.HandleUnstable)) { - // Second Rerun - CBSetupAndRun(); - TPC.UpdateAndApplyUnstableCounters(Options.HandleUnstable); - } -} - bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile, InputInfo *II, bool *FoundUniqFeatures) { if (!Size) @@ -482,17 +457,6 @@ UniqFeatureSetTmp.clear(); size_t FoundUniqFeaturesOfII = 0; size_t NumUpdatesBefore = Corpus.NumFeatureUpdates(); - bool NewFeaturesUnstable = false; - - if (Options.HandleUnstable || Options.PrintUnstableStats) { - TPC.CollectFeatures([&](size_t Feature) { - if (Corpus.IsFeatureNew(Feature, Size, Options.Shrink)) - NewFeaturesUnstable = true; - }); - if (NewFeaturesUnstable) - CheckForUnstableCounters(Data, Size); - } - TPC.CollectFeatures([&](size_t Feature) { if (Corpus.AddFeature(Feature, Size, Options.Shrink)) UniqFeatureSetTmp.push_back(Feature); @@ -501,12 +465,10 @@ II->UniqFeatureSet.end(), Feature)) FoundUniqFeaturesOfII++; }); - if (FoundUniqFeatures) *FoundUniqFeatures = FoundUniqFeaturesOfII; PrintPulseAndReportSlowInput(Data, Size); size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore; - if (NumNewFeatures) { TPC.UpdateObservedPCs(); Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile, Index: compiler-rt/lib/fuzzer/FuzzerOptions.h =================================================================== --- compiler-rt/lib/fuzzer/FuzzerOptions.h +++ compiler-rt/lib/fuzzer/FuzzerOptions.h @@ -54,8 +54,6 @@ bool PrintFinalStats = false; bool PrintCorpusStats = false; bool PrintCoverage = false; - bool PrintUnstableStats = false; - int HandleUnstable = 0; bool DumpCoverage = false; bool DetectLeaks = true; int PurgeAllocatorIntervalSec = 1; Index: compiler-rt/lib/fuzzer/FuzzerTracePC.h =================================================================== --- compiler-rt/lib/fuzzer/FuzzerTracePC.h +++ compiler-rt/lib/fuzzer/FuzzerTracePC.h @@ -74,11 +74,6 @@ // How many bits of PC are used from __sanitizer_cov_trace_pc. static const size_t kTracePcBits = 18; - enum HandleUnstableOptions { - MinUnstable = 1, - ZeroUnstable = 2, - }; - void HandleInit(uint32_t *Start, uint32_t *Stop); void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop); void HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop); @@ -109,7 +104,6 @@ void PrintCoverage(); void DumpCoverage(); - void PrintUnstableStats(); template void IterateCoveredFunctions(CallBack CB); @@ -142,18 +136,7 @@ void SetFocusFunction(const std::string &FuncName); bool ObservedFocusFunction(); - void InitializeUnstableCounters(); - bool UpdateUnstableCounters(int UnstableMode); - void UpdateAndApplyUnstableCounters(int UnstableMode); - private: - struct UnstableEdge { - uint8_t Counter; - bool IsUnstable; - }; - - UnstableEdge UnstableCounters[kNumPCs]; - bool UseCounters = false; uint32_t UseValueProfileMask = false; bool DoPrintNewPCs = false; @@ -185,9 +168,6 @@ Set ObservedPCs; std::unordered_map ObservedFuncs; // PC => Counter. - template - void IterateInline8bitCounters(Callback CB) const; - std::pair FocusFunction = {-1, -1}; // Module and PC IDs. ValueBitMap ValueProfileMap; Index: compiler-rt/lib/fuzzer/FuzzerTracePC.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerTracePC.cpp +++ compiler-rt/lib/fuzzer/FuzzerTracePC.cpp @@ -58,59 +58,6 @@ return Res; } -template -void TracePC::IterateInline8bitCounters(CallBack CB) const { - if (NumInline8bitCounters && NumInline8bitCounters == NumPCsInPCTables) { - size_t CounterIdx = 0; - for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) { - uint8_t *Beg = ModuleCounters[i].Start; - size_t Size = ModuleCounters[i].Stop - Beg; - assert(Size == (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start)); - for (size_t j = 0; j < Size; j++, CounterIdx++) - CB(i, j, CounterIdx); - } - } -} - -// Initializes unstable counters by copying Inline8bitCounters to unstable -// counters. -void TracePC::InitializeUnstableCounters() { - IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { - UnstableCounters[UnstableIdx].Counter = ModuleCounters[i].Start[j]; - }); -} - -// Compares the current counters with counters from previous runs -// and records differences as unstable edges. -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; - else if (UnstableMode == MinUnstable) - UnstableCounters[UnstableIdx].Counter = std::min( - ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter); - } - }); - return Updated; -} - -// Updates and applies unstable counters to ModuleCounters in single iteration -void TracePC::UpdateAndApplyUnstableCounters(int UnstableMode) { - IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { - 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); - } - }); -} void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) { if (Start == Stop) return; @@ -245,10 +192,15 @@ if (NumPCsInPCTables) { if (NumInline8bitCounters == NumPCsInPCTables) { - IterateInline8bitCounters([&](int i, int j, int CounterIdx) { - if (ModuleCounters[i].Start[j]) - Observe(ModulePCTable[i].Start[j]); - }); + for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) { + uint8_t *Beg = ModuleCounters[i].Start; + size_t Size = ModuleCounters[i].Stop - Beg; + assert(Size == + (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start)); + for (size_t j = 0; j < Size; j++) + if (Beg[j]) + Observe(ModulePCTable[i].Start[j]); + } } else if (NumGuards == NumPCsInPCTables) { size_t GuardIdx = 1; for (size_t i = 0; i < NumModules; i++) { @@ -380,27 +332,6 @@ } } -void TracePC::PrintUnstableStats() { - size_t count = 0; - Printf("UNSTABLE_FUNCTIONS:\n"); - IterateInline8bitCounters([&](int i, int j, int UnstableIdx) { - const PCTableEntry &TE = ModulePCTable[i].Start[j]; - if (UnstableCounters[UnstableIdx].IsUnstable) { - count++; - if (ObservedFuncs.count(TE.PC)) { - auto VisualizePC = GetNextInstructionPc(TE.PC); - std::string FunctionStr = DescribePC("%F", VisualizePC); - if (FunctionStr.find("in ") == 0) - FunctionStr = FunctionStr.substr(3); - Printf("%s\n", FunctionStr.c_str()); - } - } - }); - - Printf("stat::stability_rate: %.2f\n", - 100 - static_cast(count * 100) / NumInline8bitCounters); -} - // Value profile. // We keep track of various values that affect control flow. // These values are inserted into a bit-set-based hash map. Index: compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp =================================================================== --- compiler-rt/test/fuzzer/PrintUnstableStatsTest.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include - -int x = 0; -bool skip0 = false; -bool skip1 = false; -bool skip2 = false; - -__attribute__((noinline)) void det0() { x++; } -__attribute__((noinline)) void det1() { x++; } -__attribute__((noinline)) void det2() { x++; } -__attribute__((noinline)) void det3() { x++; } -__attribute__((noinline)) void det4() { x++; } - -__attribute__((noinline)) void ini0() { x++; } -__attribute__((noinline)) void ini1() { x++; } -__attribute__((noinline)) void ini2() { x++; } - -__attribute__((noinline)) void t0(int a) { x += a; } -__attribute__((noinline)) void t1() { x++; } -__attribute__((noinline)) void t2(int a, int b) { x += a + b; } -__attribute__((noinline)) void t3() { x++; } -__attribute__((noinline)) void t4(int a, int b, int c) { x += a + b +c; } - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size == 1 && Data[0] == 'A' && !skip0) { - skip0 = true; - ini0(); - } - if (Size == 1 && Data[0] == 'B' && !skip1) { - skip1 = true; - ini1(); - } - if (Size == 1 && Data[0] == 'C' && !skip2) { - skip2 = true; - ini2(); - } - - det0(); - det1(); - int a = rand(); - det2(); - - switch (a % 5) { - case 0: - t0(a); - break; - case 1: - t1(); - break; - case 2: - t2(a, a); - break; - case 3: - t3(); - break; - case 4: - t4(a, a, a); - break; - default: - assert(false); - } - - det3(); - det4(); - return 0; -} Index: compiler-rt/test/fuzzer/handle-unstable.test =================================================================== --- compiler-rt/test/fuzzer/handle-unstable.test +++ /dev/null @@ -1,43 +0,0 @@ -# Tests -handle_unstable -# FIXME: Disabled on Windows until symbolization works properly. -UNSUPPORTED: windows - -RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-HandleUnstableTest - -; Normal -RUN: %run %t-HandleUnstableTest -print_coverage=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=NORMAL -NORMAL-DAG: det0() -NORMAL-DAG: det1() -NORMAL-DAG: det2() -NORMAL-DAG: det3() -NORMAL-DAG: det4() -NORMAL-DAG: ini0() -NORMAL-DAG: ini1() -NORMAL-DAG: ini2() -NORMAL-DAG: t0(int) -NORMAL-DAG: t1() -NORMAL-DAG: t2(int, int) -NORMAL-DAG: t3() -NORMAL-DAG: t4(int, int, int) - -; MinUnstable -RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=MIN -MIN-NOT: ini0() -MIN-NOT: ini1() -MIN-NOT: ini2() -MIN: det0() -MIN: det1() -MIN: det2() -MIN: det3() -MIN: det4() - -; ZeroUnstable -RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=2 -runs=1 2>&1 | FileCheck %s --check-prefix=ZERO -ZERO-NOT: ini0() -ZERO-NOT: ini1() -ZERO-NOT: ini2() -ZERO: det0() -ZERO: det1() -ZERO: det2() -ZERO: det3() -ZERO: det4() Index: compiler-rt/test/fuzzer/print_unstable_stats.test =================================================================== --- compiler-rt/test/fuzzer/print_unstable_stats.test +++ /dev/null @@ -1,24 +0,0 @@ -# Tests -print_unstable_stats -# Disabled on Windows because of differences symbolizing and flakiness. -UNSUPPORTED: aarch64, windows - -RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-PrintUnstableStatsTest - -RUN: %run %t-PrintUnstableStatsTest -print_unstable_stats=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=LONG -# We do not observe ini functions since we take the minimum hit counts, and minimum hit counts for ini is 0. -LONG: UNSTABLE_FUNCTIONS: -LONG-NOT: det0() -LONG-NOT: det1() -LONG-NOT: det2() -LONG-NOT: det3() -LONG-NOT: det4() -LONG-NOT: ini0() -LONG-NOT: ini1() -LONG-NOT: ini2() -LONG-DAG: t0(int) -LONG-DAG: t1() -LONG-DAG: t2(int, int) -LONG-DAG: t3() -LONG-DAG: t4(int, int, int) - -LONG-DAG: stat::stability_rate: 27.59