[llvm] r228170 - [fuzzer] make multi-process execution more verbose; fix mutation to actually respect mutation depth and to never produce empty units

David Blaikie dblaikie at gmail.com
Wed Feb 4 12:48:12 PST 2015


On Wed, Feb 4, 2015 at 12:44 PM, Sean Silva <chisophugis at gmail.com> wrote:

> -    bool MutateDepth = 10;
> +    int  MutateDepth = 5;
>
> Ouch, I feel like we should maybe have a warning for this?
>

Agreed - we do have -Wliteral-conversion which catches some cases like
this, but I don't think it catches cases where the destination is bool,
unfortunately. I think I tried to improve this years ago & it was more work
than I had time for, at the time.

- David


>
> -- Sean Silva
>
> On Wed, Feb 4, 2015 at 11:10 AM, Kostya Serebryany <kcc at google.com> wrote:
>
>> Author: kcc
>> Date: Wed Feb  4 13:10:20 2015
>> New Revision: 228170
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=228170&view=rev
>> Log:
>> [fuzzer] make multi-process execution more verbose; fix mutation to
>> actually respect mutation depth and to never produce empty units
>>
>> Modified:
>>     llvm/trunk/lib/Fuzzer/FuzzerFlags.def
>>     llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
>>     llvm/trunk/lib/Fuzzer/FuzzerInternal.h
>>     llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
>>     llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
>>     llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerFlags.def
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Wed Feb  4 13:10:20 2015
>> @@ -16,7 +16,7 @@ FUZZER_FLAG(int, iterations, -1,
>>              "Number of iterations of the fuzzer (-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, 10,
>> +FUZZER_FLAG(int, mutate_depth, 5,
>>              "Apply this number of consecutive mutations to each input.")
>>  FUZZER_FLAG(int, exit_on_first, 0,
>>              "If 1, exit after the first new interesting input is found.")
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerIO.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerIO.cpp (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerIO.cpp Wed Feb  4 13:10:20 2015
>> @@ -9,6 +9,8 @@
>>  // IO functions.
>>
>>  //===----------------------------------------------------------------------===//
>>  #include "FuzzerInternal.h"
>> +#include <iostream>
>> +#include <iterator>
>>  #include <fstream>
>>  #include <dirent.h>
>>  namespace fuzzer {
>> @@ -31,6 +33,12 @@ Unit FileToVector(const std::string &Pat
>>                std::istreambuf_iterator<char>());
>>  }
>>
>> +void CopyFileToErr(const std::string &Path) {
>> +  std::ifstream T(Path);
>> +  std::copy(std::istreambuf_iterator<char>(T),
>> std::istreambuf_iterator<char>(),
>> +            std::ostream_iterator<char>(std::cerr, ""));
>> +}
>> +
>>  void WriteToFile(const Unit &U, const std::string &Path) {
>>    std::ofstream OF(Path);
>>    OF.write((const char*)U.data(), U.size());
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Wed Feb  4 13:10:20 2015
>> @@ -23,6 +23,7 @@ using namespace std::chrono;
>>  Unit ReadFile(const char *Path);
>>  void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V);
>>  void WriteToFile(const Unit &U, const std::string &Path);
>> +void CopyFileToErr(const std::string &Path);
>>  // Returns "Dir/FileName" or equivalent for the current OS.
>>  std::string DirPlusFile(const std::string &DirPath,
>>                          const std::string &FileName);
>> @@ -42,7 +43,7 @@ class Fuzzer {
>>      int Verbosity = 1;
>>      int MaxLen = 0;
>>      bool DoCrossOver = true;
>> -    bool MutateDepth = 10;
>> +    int  MutateDepth = 5;
>>      bool ExitOnFirst = false;
>>      bool UseFullCoverageSet  = false;
>>      std::string OutputCorpus;
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Wed Feb  4 13:10:20 2015
>> @@ -146,9 +146,8 @@ void Fuzzer::SaveCorpus() {
>>
>>  size_t Fuzzer::MutateAndTestOne(Unit *U) {
>>    size_t NewUnits = 0;
>> -  for (size_t i = 0; i < Options.MutateDepth; i++) {
>> +  for (int i = 0; i < Options.MutateDepth; i++) {
>>      Mutate(U, Options.MaxLen);
>> -    if (U->empty()) continue;
>>      size_t NewCoverage = RunOne(*U);
>>      if (NewCoverage) {
>>        Corpus.push_back(*U);
>> @@ -158,6 +157,7 @@ size_t Fuzzer::MutateAndTestOne(Unit *U)
>>                    << "\tNEW: " << NewCoverage
>>                    << " L: " << U->size()
>>                    << " S: " << Corpus.size()
>> +                  << " I: " << i
>>                    << "\t";
>>          if (U->size() < 30) {
>>            PrintASCII(*U);
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerMain.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerMain.cpp (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerMain.cpp Wed Feb  4 13:10:20 2015
>> @@ -17,6 +17,7 @@
>>  #include <iostream>
>>  #include <thread>
>>  #include <atomic>
>> +#include <mutex>
>>
>>  // ASAN options:
>>  //   * don't dump the coverage to disk.
>> @@ -105,20 +106,30 @@ static void ParseFlags(int argc, char **
>>  }
>>
>>  static void WorkerThread(const std::string &Cmd, std::atomic<int>
>> *Counter,
>> -                         int NumJobs) {
>> +                        int NumJobs, std::atomic<bool> *HasErrors) {
>> +  static std::mutex CerrMutex;
>>    while (true) {
>>      int C = (*Counter)++;
>> -    if (C >= NumJobs) return;
>> -    std::string ToRun = Cmd + " > fuzz-" + std::to_string(C) + ".log
>> 2>&1\n";
>> +    if (C >= NumJobs) break;
>> +    std::string Log = "fuzz-" + std::to_string(C) + ".log";
>> +    std::string ToRun = Cmd + " > " + Log + " 2>&1\n";
>>      if (Flags.verbosity)
>>        std::cerr << ToRun;
>> -    system(ToRun.c_str());
>> +    int ExitCode = system(ToRun.c_str());
>> +    if (ExitCode != 0)
>> +      *HasErrors = true;
>> +    std::lock_guard<std::mutex> Lock(CerrMutex);
>> +    std::cerr << "================== Job " << C
>> +              << " exited with exit code " << ExitCode
>> +              << " =================\n";
>> +    fuzzer::CopyFileToErr(Log);
>>    }
>>  }
>>
>>  static int RunInMultipleProcesses(int argc, char **argv, int NumWorkers,
>>                                    int NumJobs) {
>>    std::atomic<int> Counter(0);
>> +  std::atomic<bool> HasErrors(false);
>>    std::string Cmd;
>>    for (int i = 0; i < argc; i++) {
>>      if (FlagValue(argv[i], "jobs") || FlagValue(argv[i], "workers"))
>> continue;
>> @@ -127,10 +138,10 @@ static int RunInMultipleProcesses(int ar
>>    }
>>    std::vector<std::thread> V;
>>    for (int i = 0; i < NumWorkers; i++)
>> -    V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs));
>> +    V.push_back(std::thread(WorkerThread, Cmd, &Counter, NumJobs,
>> &HasErrors));
>>    for (auto &T : V)
>>      T.join();
>> -  return 0;
>> +  return HasErrors ? 1 : 0;
>>  }
>>
>>  int main(int argc, char **argv) {
>>
>> Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=228170&r1=228169&r2=228170&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
>> +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Wed Feb  4 13:10:20 2015
>> @@ -31,18 +31,25 @@ static char RandCh() {
>>    return Special[rand() % (sizeof(Special) - 1)];
>>  }
>>
>> +// Mutate U in place.
>>  void Mutate(Unit *U, size_t MaxLen) {
>>    assert(MaxLen > 0);
>>    assert(U->size() <= MaxLen);
>> +  if (U->empty()) {
>> +    for (size_t i = 0; i < MaxLen; i++)
>> +      U->push_back(RandCh());
>> +    return;
>> +  }
>> +  assert(!U->empty());
>>    switch (rand() % 3) {
>>    case 0:
>> -    if (U->size())
>> +    if (U->size() > 1) {
>>        U->erase(U->begin() + rand() % U->size());
>> -    break;
>> +      break;
>> +    }
>> +    // Fallthrough
>>    case 1:
>> -    if (U->empty()) {
>> -      U->push_back(RandCh());
>> -    } else if (U->size() < MaxLen) {
>> +    if (U->size() < MaxLen) {
>>        U->insert(U->begin() + rand() % U->size(), RandCh());
>>      } else { // At MaxLen.
>>        uint8_t Ch = RandCh();
>> @@ -51,12 +58,13 @@ void Mutate(Unit *U, size_t MaxLen) {
>>      }
>>      break;
>>    default:
>> -    if (!U->empty()) {
>> -      size_t idx = rand() % U->size();
>> -      (*U)[idx] = FlipRandomBit((*U)[idx]);
>> +    {
>> +      size_t Idx = rand() % U->size();
>> +      (*U)[Idx] = FlipRandomBit((*U)[Idx]);
>>      }
>>      break;
>>    }
>> +  assert(!U->empty());
>>  }
>>
>>  }  // namespace fuzzer
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150204/745908cf/attachment.html>


More information about the llvm-commits mailing list