From 46c638cfc877176752dbf94e016d6ea0fc8afe76 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Wed, 4 Feb 2015 22:20:09 +0000 Subject: [PATCH] [fuzzer] add -runs=N to limit the number of runs per session. Also, make sure we do some mutations w/o cross over. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228214 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Fuzzer/FuzzerFlags.def | 5 ++++- lib/Fuzzer/FuzzerInternal.h | 2 ++ lib/Fuzzer/FuzzerLoop.cpp | 17 ++++++++++------- lib/Fuzzer/FuzzerMain.cpp | 3 ++- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 0895fa7bac0..f4a4bb96441 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -13,7 +13,10 @@ FUZZER_FLAG(int, verbosity, 1, "Verbosity level.") FUZZER_FLAG(int, seed, 0, "Random seed. If 0, seed is generated.") FUZZER_FLAG(int, iterations, -1, - "Number of iterations of the fuzzer (-1 for infinite runs).") + "Number of iterations of the fuzzer internal loop" + " (-1 for infinite iterations).") +FUZZER_FLAG(int, runs, -1, + "Number of individual test runs (-1 for infinite runs).") FUZZER_FLAG(int, max_len, 64, "Maximal length of the test input.") FUZZER_FLAG(int, cross_over, 1, "If 1, cross over inputs.") FUZZER_FLAG(int, mutate_depth, 5, diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index fbf26309f23..acf07ee6166 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -9,6 +9,7 @@ // Define the main class fuzzer::Fuzzer and most functions. //===----------------------------------------------------------------------===// #include +#include #include #include #include @@ -46,6 +47,7 @@ class Fuzzer { int MutateDepth = 5; bool ExitOnFirst = false; bool UseFullCoverageSet = false; + size_t MaxNumberOfRuns = ULONG_MAX; std::string OutputCorpus; }; Fuzzer(FuzzingOptions Options) : Options(Options) { diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 04285895181..d825148c758 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -147,6 +147,8 @@ void Fuzzer::SaveCorpus() { size_t Fuzzer::MutateAndTestOne(Unit *U) { size_t NewUnits = 0; for (int i = 0; i < Options.MutateDepth; i++) { + if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) + return NewUnits; Mutate(U, Options.MaxLen); size_t NewCoverage = RunOne(*U); if (NewCoverage) { @@ -177,19 +179,20 @@ size_t Fuzzer::MutateAndTestOne(Unit *U) { size_t Fuzzer::Loop(size_t NumIterations) { size_t NewUnits = 0; for (size_t i = 1; i <= NumIterations; i++) { - if (Options.DoCrossOver) { - for (size_t J1 = 0; J1 < Corpus.size(); J1++) { + for (size_t J1 = 0; J1 < Corpus.size(); J1++) { + if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) + return NewUnits; + // First, simply mutate the unit w/o doing crosses. + CurrentUnit = Corpus[J1]; + NewUnits += MutateAndTestOne(&CurrentUnit); + // Now, cross with others. + if (Options.DoCrossOver) { for (size_t J2 = 0; J2 < Corpus.size(); J2++) { CurrentUnit.clear(); CrossOver(Corpus[J1], Corpus[J2], &CurrentUnit, Options.MaxLen); NewUnits += MutateAndTestOne(&CurrentUnit); } } - } else { // No CrossOver - for (size_t J = 0; J < Corpus.size(); J++) { - CurrentUnit = Corpus[J]; - NewUnits += MutateAndTestOne(&CurrentUnit); - } } } return NewUnits; diff --git a/lib/Fuzzer/FuzzerMain.cpp b/lib/Fuzzer/FuzzerMain.cpp index 0a852ed4257..35e50f0ee31 100644 --- a/lib/Fuzzer/FuzzerMain.cpp +++ b/lib/Fuzzer/FuzzerMain.cpp @@ -11,7 +11,6 @@ #include "FuzzerInternal.h" -#include #include #include #include @@ -164,6 +163,8 @@ int main(int argc, char **argv) { Options.MutateDepth = Flags.mutate_depth; Options.ExitOnFirst = Flags.exit_on_first; Options.UseFullCoverageSet = Flags.use_full_coverage_set; + if (Flags.runs >= 0) + Options.MaxNumberOfRuns = Flags.runs; if (!inputs.empty()) Options.OutputCorpus = inputs[0]; Fuzzer F(Options); -- 2.34.1