[libFuzzer] Mutation tracking and logging implemented.
Summary:
Code now exists to track number of mutations that are used in fuzzing in total
and ones that produce new coverage. The stats are currently being dumped to the
command line.
Patch by Kodé Williams (@kodewilliams).
Reviewers: metzman, Dor1s, morehouse, kcc
Reviewed By: Dor1s, morehouse, kcc
Subscribers: delcypher, kubamracek, kcc, morehouse, llvm-commits, #sanitizers, mgorny
Differential Revision: https://reviews.llvm.org/D48054
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@337324 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/FuzzerMutate.cpp b/FuzzerMutate.cpp
index 6f6ce07..e89e1a4 100644
--- a/FuzzerMutate.cpp
+++ b/FuzzerMutate.cpp
@@ -30,34 +30,36 @@
DefaultMutators.insert(
DefaultMutators.begin(),
{
- {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes"},
- {&MutationDispatcher::Mutate_InsertByte, "InsertByte"},
+ {&MutationDispatcher::Mutate_EraseBytes, "EraseBytes", 0, 0},
+ {&MutationDispatcher::Mutate_InsertByte, "InsertByte", 0, 0},
{&MutationDispatcher::Mutate_InsertRepeatedBytes,
- "InsertRepeatedBytes"},
- {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"},
- {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
- {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
- {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
- {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"},
- {&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
- {&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
+ "InsertRepeatedBytes", 0, 0},
+ {&MutationDispatcher::Mutate_ChangeByte, "ChangeByte", 0, 0},
+ {&MutationDispatcher::Mutate_ChangeBit, "ChangeBit", 0, 0},
+ {&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes", 0, 0},
+ {&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt", 0,
+ 0},
+ {&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt", 0,
+ 0},
+ {&MutationDispatcher::Mutate_CopyPart, "CopyPart", 0, 0},
+ {&MutationDispatcher::Mutate_CrossOver, "CrossOver", 0, 0},
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
- "ManualDict"},
+ "ManualDict", 0, 0},
{&MutationDispatcher::Mutate_AddWordFromPersistentAutoDictionary,
- "PersAutoDict"},
+ "PersAutoDict", 0, 0},
});
if(Options.UseCmp)
DefaultMutators.push_back(
- {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP"});
+ {&MutationDispatcher::Mutate_AddWordFromTORC, "CMP", 0, 0});
if (EF->LLVMFuzzerCustomMutator)
- Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
+ Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom", 0, 0});
else
Mutators = DefaultMutators;
if (EF->LLVMFuzzerCustomCrossOver)
Mutators.push_back(
- {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
+ {&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver", 0, 0});
}
static char RandCh(Random &Rand) {
@@ -464,6 +466,7 @@
if (!PersistentAutoDictionary.ContainsWord(DE->GetW()))
PersistentAutoDictionary.push_back({DE->GetW(), 1});
}
+ RecordUsefulMutations();
}
void MutationDispatcher::PrintRecommendedDictionary() {
@@ -484,8 +487,7 @@
void MutationDispatcher::PrintMutationSequence() {
Printf("MS: %zd ", CurrentMutatorSequence.size());
- for (auto M : CurrentMutatorSequence)
- Printf("%s-", M.Name);
+ for (auto M : CurrentMutatorSequence) Printf("%s-", M->Name);
if (!CurrentDictionaryEntrySequence.empty()) {
Printf(" DE: ");
for (auto DE : CurrentDictionaryEntrySequence) {
@@ -513,12 +515,13 @@
// in which case they will return 0.
// Try several times before returning un-mutated data.
for (int Iter = 0; Iter < 100; Iter++) {
- auto M = Mutators[Rand(Mutators.size())];
- size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
+ auto M = &Mutators[Rand(Mutators.size())];
+ size_t NewSize = (this->*(M->Fn))(Data, Size, MaxSize);
if (NewSize && NewSize <= MaxSize) {
if (Options.OnlyASCII)
ToASCII(Data, NewSize);
CurrentMutatorSequence.push_back(M);
+ M->TotalCount++;
return NewSize;
}
}
@@ -531,4 +534,21 @@
{W, std::numeric_limits<size_t>::max()});
}
+void MutationDispatcher::RecordUsefulMutations() {
+ for (auto M : CurrentMutatorSequence) M->UsefulCount++;
+}
+
+void MutationDispatcher::PrintMutationStats() {
+ Printf("\nstat::mutation_usefulness: ");
+ for (size_t i = 0; i < Mutators.size(); i++) {
+ double UsefulPercentage =
+ Mutators[i].TotalCount
+ ? (100.0 * Mutators[i].UsefulCount) / Mutators[i].TotalCount
+ : 0;
+ Printf("%.3f", UsefulPercentage);
+ if (i < Mutators.size() - 1) Printf(",");
+ }
+ Printf("\n");
+}
+
} // namespace fuzzer