[libFuzzer] print successfull mutations sequences
authorKostya Serebryany <kcc@google.com>
Sat, 19 Dec 2015 01:09:49 +0000 (01:09 +0000)
committerKostya Serebryany <kcc@google.com>
Sat, 19 Dec 2015 01:09:49 +0000 (01:09 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256071 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerInterface.h
lib/Fuzzer/FuzzerLoop.cpp
lib/Fuzzer/FuzzerMutate.cpp

index c409c06..329e3a9 100644 (file)
@@ -70,6 +70,10 @@ class MutationDispatcher {
  public:
   MutationDispatcher(FuzzerRandomBase &Rand);
   ~MutationDispatcher();
+  /// Indicate that we are about to start a new sequence of mutations.
+  void StartMutationSequence();
+  /// Print the current sequence of mutations.
+  void PrintMutationSequence();
   /// Mutates data by shuffling bytes.
   size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
   /// Mutates data by erasing a byte.
@@ -138,6 +142,8 @@ class UserSuppliedFuzzer {
   UserSuppliedFuzzer(FuzzerRandomBase *Rand);
   /// Executes the target function on 'Size' bytes of 'Data'.
   virtual int TargetFunction(const uint8_t *Data, size_t Size) = 0;
+  virtual void StartMutationSequence() { MD.StartMutationSequence(); }
+  virtual void PrintMutationSequence() { MD.PrintMutationSequence(); }
   /// Mutates 'Size' bytes of data in 'Data' inplace into up to 'MaxSize' bytes,
   /// returns the new size of the data, which should be positive.
   virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
index 889c30c..b1ce294 100644 (file)
@@ -320,12 +320,8 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U) {
     return;
   PrintStats("NEW   ", "");
   if (Options.Verbosity) {
-    Printf(" L: %zd", U.size());
-    if (U.size() < 30) {
-      Printf(" ");
-      PrintUnitInASCII(U, "\t");
-      Print(U);
-    }
+    Printf(" L: %zd ", U.size());
+    USF.PrintMutationSequence();
     Printf("\n");
   }
 }
@@ -483,6 +479,7 @@ void Fuzzer::Loop() {
         secondsSinceProcessStartUp() >
         static_cast<size_t>(Options.MaxTotalTimeSec))
       break;
+    USF.StartMutationSequence();
     CurrentUnit = Corpus[J1];
     // Optionally, cross with another unit.
     if (Options.DoCrossOver && USF.GetRand().RandBool()) {
index 74ae0cb..471ae6c 100644 (file)
 
 namespace fuzzer {
 
-typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
-                                              size_t Max);
+struct Mutator {
+  size_t (MutationDispatcher::*Fn)(uint8_t *Data, size_t Size, size_t Max);
+  const char *Name;
+};
 
 struct MutationDispatcher::Impl {
   std::vector<Unit> Dictionary;
   std::vector<Mutator> Mutators;
+  std::vector<Mutator> CurrentMutatorSequence;
+
+  void Add(Mutator M) { Mutators.push_back(M); }
   Impl() {
-    Mutators.push_back(&MutationDispatcher::Mutate_EraseByte);
-    Mutators.push_back(&MutationDispatcher::Mutate_InsertByte);
-    Mutators.push_back(&MutationDispatcher::Mutate_ChangeByte);
-    Mutators.push_back(&MutationDispatcher::Mutate_ChangeBit);
-    Mutators.push_back(&MutationDispatcher::Mutate_ShuffleBytes);
-    Mutators.push_back(&MutationDispatcher::Mutate_ChangeASCIIInteger);
+    Add({&MutationDispatcher::Mutate_EraseByte, "EraseByte"});
+    Add({&MutationDispatcher::Mutate_InsertByte, "InsertByte"});
+    Add({&MutationDispatcher::Mutate_ChangeByte, "ChangeByte"});
+    Add({&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"});
+    Add({&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"});
+    Add({&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"});
   }
   void AddWordToDictionary(const uint8_t *Word, size_t Size) {
     if (Dictionary.empty()) {
-      Mutators.push_back(&MutationDispatcher::Mutate_AddWordFromDictionary);
+      Add({&MutationDispatcher::Mutate_AddWordFromDictionary, "AddFromDict"});
     }
     Dictionary.push_back(Unit(Word, Word + Size));
   }
 };
 
-
 static char FlipRandomBit(char X, FuzzerRandomBase &Rand) {
   int Bit = Rand(8);
   char Mask = 1 << Bit;
@@ -150,6 +154,16 @@ size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
   return Size;
 }
 
+void MutationDispatcher::StartMutationSequence() {
+  MDImpl->CurrentMutatorSequence.clear();
+}
+
+void MutationDispatcher::PrintMutationSequence() {
+  Printf("MS: %zd ", MDImpl->CurrentMutatorSequence.size());
+  for (auto M : MDImpl->CurrentMutatorSequence)
+    Printf("%s-", M.Name);
+}
+
 // Mutates Data in place, returns new size.
 size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
   assert(MaxSize > 0);
@@ -165,9 +179,12 @@ size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
   // Try several times before returning un-mutated data.
   for (int Iter = 0; Iter < 10; Iter++) {
     size_t MutatorIdx = Rand(MDImpl->Mutators.size());
-    size_t NewSize =
-        (this->*(MDImpl->Mutators[MutatorIdx]))(Data, Size, MaxSize);
-    if (NewSize) return NewSize;
+    auto M = MDImpl->Mutators[MutatorIdx];
+    size_t NewSize = (this->*(M.Fn))(Data, Size, MaxSize);
+    if (NewSize) {
+      MDImpl->CurrentMutatorSequence.push_back(M);
+      return NewSize;
+    }
   }
   return Size;
 }