return II;
}
+ InputInfo &ChooseUnitToCrossOverWith(Random &Rand, bool UniformDist) {
+ if (!UniformDist) {
+ return ChooseUnitToMutate(Rand);
+ }
+ InputInfo &II = *Inputs[Rand(Inputs.size())];
+ assert(!II.U.empty());
+ return II;
+ }
+
// Returns an index of random unit from the corpus to mutate.
size_t ChooseUnitIdxToMutate(Random &Rand) {
UpdateCorpusDistribution(Rand);
Options.IgnoreCrashes = Flags.ignore_crashes;
Options.MaxTotalTimeSec = Flags.max_total_time;
Options.DoCrossOver = Flags.cross_over;
+ Options.CrossOverUniformDist = Flags.cross_over_uniform_dist;
Options.MutateDepth = Flags.mutate_depth;
Options.ReduceDepth = Flags.reduce_depth;
Options.UseCounters = Flags.use_counters;
"seed inputs will never be reduced. This option can be useful when seeds are"
"not properly formed for the fuzz target but still have useful snippets.")
FUZZER_FLAG_INT(cross_over, 1, "If 1, cross over inputs.")
+FUZZER_FLAG_INT(cross_over_uniform_dist, 0, "Experimental. If 1, use a "
+ "uniform probability distribution when choosing inputs to cross over with. "
+ "Some of the inputs in the corpus may never get chosen for mutation "
+ "depending on the input mutation scheduling policy. With this flag, all "
+ "inputs, regardless of the input mutation scheduling policy, can be chosen "
+ "as an input to cross over with. This can be particularly useful with "
+ "|keep_seed==1|; all the initial seed inputs, even though they do not "
+ "increase coverage because they are not properly formed, will still be "
+ "chosen as an input to cross over with.")
+
FUZZER_FLAG_INT(mutate_depth, 5,
"Apply this number of consecutive mutations to each input.")
FUZZER_FLAG_INT(reduce_depth, 0, "Experimental/internal. "
MD.StartMutationSequence();
auto &II = Corpus.ChooseUnitToMutate(MD.GetRand());
- if (Options.DoCrossOver)
- MD.SetCrossOverWith(&Corpus.ChooseUnitToMutate(MD.GetRand()).U);
+ if (Options.DoCrossOver) {
+ auto &CrossOverII = Corpus.ChooseUnitToCrossOverWith(
+ MD.GetRand(), Options.CrossOverUniformDist);
+ MD.SetCrossOverWith(&CrossOverII.U);
+ }
const auto &U = II.U;
memcpy(BaseSha1, II.Sha1, sizeof(BaseSha1));
assert(CurrentUnitData);
int RssLimitMb = 0;
int MallocLimitMb = 0;
bool DoCrossOver = true;
+ bool CrossOverUniformDist = false;
int MutateDepth = 5;
bool ReduceDepth = false;
bool UseCounters = false;
--- /dev/null
+REQUIRES: linux, x86_64
+RUN: %cpp_compiler %S/KeepSeedTest.cpp -o %t-CrossOverUniformDistTest
+
+RUN: rm -rf %t-corpus
+RUN: mkdir %t-corpus
+RUN: echo -n "@SELECT" > %t-corpus/A
+RUN: echo -n "@FROM WHERE" > %t-corpus/B
+
+RUN: not %run %t-CrossOverUniformDistTest -keep_seed=1 -cross_over_uniform_dist=1 -seed=1 -runs=2000000 %t-corpus 2>&1 | FileCheck %s
+CHECK: BINGO
+
+RUN: rm -rf %t-corpus
+RUN: mkdir %t-corpus
+RUN: echo -n "@SELECT" > %t-corpus/A
+RUN: echo -n "@FROM WHERE" > %t-corpus/B
+RUN: %run %t-CrossOverUniformDistTest -keep_seed=1 -seed=1 -runs=2000000 %t-corpus 2>&1