diff options
author | Kostya Serebryany <kcc@google.com> | 2015-11-04 23:22:25 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2015-11-04 23:22:25 +0000 |
commit | e692621a9dc6eff696939a552fe7aa1fed4300ad (patch) | |
tree | 923baa6ac86011e7e8689574dd0d12eeb67d75d8 /llvm/lib/Fuzzer/FuzzerLoop.cpp | |
parent | 58a7e659d94d14fe6e78012d474691964f31a29a (diff) | |
download | bcm5719-llvm-e692621a9dc6eff696939a552fe7aa1fed4300ad.tar.gz bcm5719-llvm-e692621a9dc6eff696939a552fe7aa1fed4300ad.zip |
[libFuzzer] when choosing the next unit to mutate, give some preference to the most recent units (they are more likely to be interesting)
llvm-svn: 252097
Diffstat (limited to 'llvm/lib/Fuzzer/FuzzerLoop.cpp')
-rw-r--r-- | llvm/lib/Fuzzer/FuzzerLoop.cpp | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/llvm/lib/Fuzzer/FuzzerLoop.cpp b/llvm/lib/Fuzzer/FuzzerLoop.cpp index 4f07961e066..64c567d83f7 100644 --- a/llvm/lib/Fuzzer/FuzzerLoop.cpp +++ b/llvm/lib/Fuzzer/FuzzerLoop.cpp @@ -346,39 +346,58 @@ void Fuzzer::MutateAndTestOne(Unit *U) { } } +// Returns an index of random unit from the corpus to mutate. +// Hypothesis: units added to the corpus last are more likely to be interesting. +// This function gives more wieght to the more recent units. +size_t Fuzzer::ChooseUnitToMutate() { + size_t N = Corpus.size(); + size_t Total = (N + 1) * N / 2; + size_t R = USF.GetRand()(Total); + size_t IdxBeg = 0, IdxEnd = N; + // Binary search. + while (IdxEnd - IdxBeg >= 2) { + size_t Idx = IdxBeg + (IdxEnd - IdxBeg) / 2; + if (R > (Idx + 1) * Idx / 2) + IdxBeg = Idx; + else + IdxEnd = Idx; + } + assert(IdxBeg < N); + return IdxBeg; +} + void Fuzzer::Loop() { for (auto &U: Options.Dictionary) USF.GetMD().AddWordToDictionary(U.data(), U.size()); while (true) { - for (size_t J1 = 0; J1 < Corpus.size(); J1++) { - SyncCorpus(); - RereadOutputCorpus(); - if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) - return; - if (Options.MaxTotalTimeSec > 0 && - secondsSinceProcessStartUp() > - static_cast<size_t>(Options.MaxTotalTimeSec)) - return; - CurrentUnit = Corpus[J1]; - // Optionally, cross with another unit. - if (Options.DoCrossOver && USF.GetRand().RandBool()) { - size_t J2 = USF.GetRand()(Corpus.size()); - if (!Corpus[J1].empty() && !Corpus[J2].empty()) { - assert(!Corpus[J2].empty()); - CurrentUnit.resize(Options.MaxLen); - size_t NewSize = USF.CrossOver( - Corpus[J1].data(), Corpus[J1].size(), Corpus[J2].data(), - Corpus[J2].size(), CurrentUnit.data(), CurrentUnit.size()); - assert(NewSize > 0 && "CrossOver returned empty unit"); - assert(NewSize <= (size_t)Options.MaxLen && - "CrossOver returned overisized unit"); - CurrentUnit.resize(NewSize); - } + size_t J1 = ChooseUnitToMutate();; + SyncCorpus(); + RereadOutputCorpus(); + if (TotalNumberOfRuns >= Options.MaxNumberOfRuns) + return; + if (Options.MaxTotalTimeSec > 0 && + secondsSinceProcessStartUp() > + static_cast<size_t>(Options.MaxTotalTimeSec)) + return; + CurrentUnit = Corpus[J1]; + // Optionally, cross with another unit. + if (Options.DoCrossOver && USF.GetRand().RandBool()) { + size_t J2 = ChooseUnitToMutate(); + if (!Corpus[J1].empty() && !Corpus[J2].empty()) { + assert(!Corpus[J2].empty()); + CurrentUnit.resize(Options.MaxLen); + size_t NewSize = USF.CrossOver( + Corpus[J1].data(), Corpus[J1].size(), Corpus[J2].data(), + Corpus[J2].size(), CurrentUnit.data(), CurrentUnit.size()); + assert(NewSize > 0 && "CrossOver returned empty unit"); + assert(NewSize <= (size_t)Options.MaxLen && + "CrossOver returned overisized unit"); + CurrentUnit.resize(NewSize); } - // Perform several mutations and runs. - MutateAndTestOne(&CurrentUnit); } + // Perform several mutations and runs. + MutateAndTestOne(&CurrentUnit); } } |