<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 29, 2015 at 8:06 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron@aaronballman.com" target="_blank">aaron@aaronballman.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Thu, Jan 29, 2015 at 11:01 AM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>> wrote:<br>
> Can this be *disabled* on windows instead of reverting?<br>
<br>
</span>Sorry for the troubles, but I was unaware this wasn't supposed to work<br>
on Windows, especially since it was not mentioned in the commit<br>
message, and it was being used by clang-format.<br>
<span class=""><br>
> This code at this stage is not supposed to work on windows and this is what<br>
> EXCLUDE_FROM_ALL was for.<br>
<br>
</span>It appears that was a nonfunctional solution, and there were several<br>
people on IRC with the same inability to move forward. Since this<br>
caused bots to go red as well, reverting to green is the usual<br>
approach. Again, I'm sorry if I've caused problems, but this appears<br>
to have been broken for two days and I was mostly interested in<br>
getting everyone back to a working state.<br>
<div class="HOEnZb"><div class="h5"><br></div></div></blockquote><div><br></div><div>I was available by e-mail. </div><div>Do you know how to disable this build on windows?</div><div>May I ask you to commit the code back in a windows-disabled state?</div><div>I do not have access to windows and can not verify fixes there.  </div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
~Aaron<br>
<br>
><br>
> On Thu, Jan 29, 2015 at 8:00 AM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>> wrote:<br>
>><br>
>> Could this have been resolved w/o reverting?<br>
>><br>
>><br>
>> On Thu, Jan 29, 2015 at 7:53 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
>> wrote:<br>
>>><br>
>>> Sorry for any troubles this causes, but I have reverted in 227452 and<br>
>>> 227453 as this was causing issues for too many folks. Also, there<br>
>>> appear to be other build issues you will want to address before<br>
>>> recommit:<br>
>>> <a href="http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc17-DA/builds/1467/steps/build_llvm_all/logs/stdio" target="_blank">http://bb.pgr.jp/builders/msbuild-llvmclang-x64-msc17-DA/builds/1467/steps/build_llvm_all/logs/stdio</a><br>
>>><br>
>>> ~Aaron<br>
>>><br>
>>> On Thu, Jan 29, 2015 at 10:28 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>><br>
>>> wrote:<br>
>>> > Actually, this is completely broken on Windows and should be reverted<br>
>>> > until it is fixed up. Comments below.<br>
>>> ><br>
>>> > On Thu, Jan 29, 2015 at 10:11 AM, Aaron Ballman<br>
>>> > <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br>
>>> >> This commit puts the fuzzer targets on the top-level for MSVC<br>
>>> >> solutions when they should be in a separate folder instead. Picture<br>
>>> >> attached is worth 1000 words. ;-)<br>
>>> >><br>
>>> >> ~Aaron<br>
>>> >><br>
>>> >> On Tue, Jan 27, 2015 at 5:08 PM, Kostya Serebryany <<a href="mailto:kcc@google.com">kcc@google.com</a>><br>
>>> >> wrote:<br>
>>> >>> Author: kcc<br>
>>> >>> Date: Tue Jan 27 16:08:41 2015<br>
>>> >>> New Revision: 227252<br>
>>> >>><br>
>>> >>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=227252&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=227252&view=rev</a><br>
>>> >>> Log:<br>
>>> >>> Add a Fuzzer library<br>
>>> >>><br>
>>> >>> Summary:<br>
>>> >>> A simple genetic in-process coverage-guided fuzz testing library.<br>
>>> >>><br>
>>> >>> I've used this fuzzer to test clang-format<br>
>>> >>> (it found 12+ bugs, thanks djasper@ for the fixes!)<br>
>>> >>> and it may also help us test other parts of LLVM.<br>
>>> >>> So why not keep it in the LLVM repository?<br>
>>> >>><br>
>>> >>> I plan to add the cmake build rules later (in a separate patch, if<br>
>>> >>> that's ok)<br>
>>> >>> and also add a clang-format-fuzzer target.<br>
>>> >>><br>
>>> >>> See README.txt for details.<br>
>>> >>><br>
>>> >>> Test Plan: Tests will follow separately.<br>
>>> >>><br>
>>> >>> Reviewers: djasper, chandlerc, rnk<br>
>>> >>><br>
>>> >>> Reviewed By: rnk<br>
>>> >>><br>
>>> >>> Subscribers: majnemer, ygribov, dblaikie, llvm-commits<br>
>>> >>><br>
>>> >>> Differential Revision: <a href="http://reviews.llvm.org/D7184" target="_blank">http://reviews.llvm.org/D7184</a><br>
>>> >>><br>
>>> >>> Added:<br>
>>> >>>     llvm/trunk/lib/Fuzzer/<br>
>>> >>>     llvm/trunk/lib/Fuzzer/CMakeLists.txt<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerFlags.def<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerIO.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerInternal.h<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerMain.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/README.txt<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/ExactTest.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp<br>
>>> >>>     llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp<br>
>>> >>> Modified:<br>
>>> >>>     llvm/trunk/lib/CMakeLists.txt<br>
>>> >>><br>
>>> >>> Modified: llvm/trunk/lib/CMakeLists.txt<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CMakeLists.txt?rev=227252&r1=227251&r2=227252&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CMakeLists.txt?rev=227252&r1=227251&r2=227252&view=diff</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/CMakeLists.txt (original)<br>
>>> >>> +++ llvm/trunk/lib/CMakeLists.txt Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -17,3 +17,4 @@ add_subdirectory(Target)<br>
>>> >>>  add_subdirectory(AsmParser)<br>
>>> >>>  add_subdirectory(LineEditor)<br>
>>> >>>  add_subdirectory(ProfileData)<br>
>>> >>> +add_subdirectory(Fuzzer)<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/CMakeLists.txt<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/CMakeLists.txt (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/CMakeLists.txt Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,9 @@<br>
>>> >>> +add_library(LLVMFuzzer STATIC<br>
>>> >>> +  EXCLUDE_FROM_ALL  # Do not build if you are not building fuzzers.<br>
>>> >>> +  FuzzerCrossOver.cpp<br>
>>> >>> +  FuzzerIO.cpp<br>
>>> >>> +  FuzzerLoop.cpp<br>
>>> >>> +  FuzzerMain.cpp<br>
>>> >>> +  FuzzerMutate.cpp<br>
>>> >>> +  FuzzerUtil.cpp<br>
>>> >>> +  )<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp Tue Jan 27 16:08:41<br>
>>> >>> 2015<br>
>>> >>> @@ -0,0 +1,46 @@<br>
>>> >>> +//===- FuzzerCrossOver.cpp - Cross over two test inputs<br>
>>> >>> -------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Cross over test inputs.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +<br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +<br>
>>> >>> +// Cross A and B, store the result (ap to MaxLen bytes) in U.<br>
>>> >>> +void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t MaxLen)<br>
>>> >>> {<br>
>>> >>> +  size_t Size = rand() % MaxLen + 1;<br>
>>> >>> +  U->clear();<br>
>>> >>> +  const Unit *V = &A;<br>
>>> >>> +  size_t PosA = 0;<br>
>>> >>> +  size_t PosB = 0;<br>
>>> >>> +  size_t *Pos = &PosA;<br>
>>> >>> +  while (U->size() < Size && (PosA < A.size() || PosB < B.size())) {<br>
>>> >>> +    // Merge a part of V into U.<br>
>>> >>> +    size_t SizeLeftU = Size - U->size();<br>
>>> >>> +    if (*Pos < V->size()) {<br>
>>> >>> +      size_t SizeLeftV = V->size() - *Pos;<br>
>>> >>> +      size_t MaxExtraSize = std::min(SizeLeftU, SizeLeftV);<br>
>>> >>> +      size_t ExtraSize = rand() % MaxExtraSize + 1;<br>
>>> >>> +      U->insert(U->end(), V->begin() + *Pos, V->begin() + *Pos +<br>
>>> >>> ExtraSize);<br>
>>> >>> +      (*Pos) += ExtraSize;<br>
>>> >>> +    }<br>
>>> >>> +<br>
>>> >>> +    // Use the other Unit on the next iteration.<br>
>>> >>> +    if (Pos == &PosA) {<br>
>>> >>> +      Pos = &PosB;<br>
>>> >>> +      V = &B;<br>
>>> >>> +    } else {<br>
>>> >>> +      Pos = &PosA;<br>
>>> >>> +      V = &A;<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +}  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerFlags.def<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerFlags.def?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerFlags.def (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerFlags.def Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,24 @@<br>
>>> >>> +//===- FuzzerFlags.def - Run-time flags -------------------------*-<br>
>>> >>> C++ -* ===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Flags. FUZZER_FLAG macro should be defined at the point of<br>
>>> >>> inclusion.<br>
>>> >>> +// We are not using any flag parsing library for better portability<br>
>>> >>> and<br>
>>> >>> +// independence.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +FUZZER_FLAG(int, verbosity, 1, "Verbosity level.")<br>
>>> >>> +FUZZER_FLAG(int, seed, 0, "Random seed. If 0, seed is generated.")<br>
>>> >>> +FUZZER_FLAG(int, iterations, -1,<br>
>>> >>> +            "Number of iterations of the fuzzer (-1 for infinite<br>
>>> >>> runs).")<br>
>>> >>> +FUZZER_FLAG(int, max_len, 64, "Maximal length of the test input.")<br>
>>> >>> +FUZZER_FLAG(int, cross_over, 1, "If 1, cross over inputs.")<br>
>>> >>> +FUZZER_FLAG(int, mutate_depth, 10,<br>
>>> >>> +            "Apply this number of consecutive mutations to each<br>
>>> >>> input.")<br>
>>> >>> +FUZZER_FLAG(int, exit_on_first, 0,<br>
>>> >>> +            "If 1, exit after the first new interesting input is<br>
>>> >>> found.")<br>
>>> >>> +FUZZER_FLAG(int, timeout, -1, "Timeout in seconds (if positive).")<br>
>>> >>> +FUZZER_FLAG(int, help, 0, "Print help.")<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerIO.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerIO.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerIO.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerIO.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,44 @@<br>
>>> >>> +//===- FuzzerIO.cpp - IO utils.<br>
>>> >>> -------------------------------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// IO functions.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +#include <fstream><br>
>>> >>> +#include <dirent.h><br>
>>> ><br>
>>> > dirent.h does not exist on Windows with MSVC.<br>
>>> ><br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +<br>
>>> >>> +std::vector<std::string> ListFilesInDir(const std::string &Dir) {<br>
>>> >>> +  std::vector<std::string> V;<br>
>>> >>> +  DIR *D = opendir(Dir.c_str());<br>
>>> >>> +  if (!D) return V;<br>
>>> >>> +  while (auto E = readdir(D)) {<br>
>>> >>> +    if (E->d_type == DT_REG || E->d_type == DT_LNK)<br>
>>> >>> +      V.push_back(E->d_name);<br>
>>> >>> +  }<br>
>>> >>> +  closedir(D);<br>
>>> >>> +  return V;<br>
>>> ><br>
>>> > We have filesystem APIs to do this, don't we?<br>
>>> ><br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +Unit FileToVector(const std::string &Path) {<br>
>>> >>> +  std::ifstream T(Path);<br>
>>> >>> +  return Unit((std::istreambuf_iterator<char>(T)),<br>
>>> >>> +              std::istreambuf_iterator<char>());<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void WriteToFile(const Unit &U, const std::string &Path) {<br>
>>> >>> +  std::ofstream OF(Path);<br>
>>> >>> +  OF.write((const char*)U.data(), U.size());<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V)<br>
>>> >>> {<br>
>>> >>> +  for (auto &X : ListFilesInDir(Path))<br>
>>> >>> +    V->push_back(FileToVector(std::string(Path) + "/" + X));<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +}  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerInternal.h<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,77 @@<br>
>>> >>> +//===- FuzzerInternal.h - Internal header for the Fuzzer --------*-<br>
>>> >>> C++ -* ===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Define the main class fuzzer::Fuzzer and most functions.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +#include <cassert><br>
>>> >>> +#include <chrono><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <string><br>
>>> >>> +#include <vector><br>
>>> >>> +<br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +typedef std::vector<uint8_t> Unit;<br>
>>> >>> +using namespace std::chrono;<br>
>>> >>> +<br>
>>> >>> +Unit ReadFile(const char *Path);<br>
>>> >>> +std::vector<std::string> ListFilesInDir(const std::string &Dir);<br>
>>> >>> +void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V);<br>
>>> >>> +void WriteToFile(const Unit &U, const std::string &Path);<br>
>>> >>> +<br>
>>> >>> +void Mutate(Unit *U, size_t MaxLen);<br>
>>> >>> +<br>
>>> >>> +void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t<br>
>>> >>> MaxLen);<br>
>>> >>> +<br>
>>> >>> +void Print(const Unit &U, const char *PrintAfter = "");<br>
>>> >>> +void PrintASCII(const Unit &U, const char *PrintAfter = "");<br>
>>> >>> +std::string Hash(const Unit &U);<br>
>>> >>> +void SetTimer(int Seconds);<br>
>>> >>> +<br>
>>> >>> +class Fuzzer {<br>
>>> >>> + public:<br>
>>> >>> +  struct FuzzingOptions {<br>
>>> >>> +    int Verbosity = 1;<br>
>>> >>> +    int MaxLen = 0;<br>
>>> >>> +    bool DoCrossOver = true;<br>
>>> >>> +    bool MutateDepth = 10;<br>
>>> >>> +    bool ExitOnFirst = false;<br>
>>> >>> +    std::string OutputCorpus;<br>
>>> >>> +  };<br>
>>> >>> +  Fuzzer(FuzzingOptions Options) : Options(Options) {<br>
>>> >>> +    SetDeathCallback();<br>
>>> >>> +  }<br>
>>> >>> +  void AddToCorpus(const Unit &U) { Corpus.push_back(U); }<br>
>>> >>> +  size_t Loop(size_t NumIterations);<br>
>>> >>> +  void ShuffleAndMinimize();<br>
>>> >>> +  size_t CorpusSize() const { return Corpus.size(); }<br>
>>> >>> +  void ReadDir(const std::string &Path) {<br>
>>> >>> +    ReadDirToVectorOfUnits(Path.c_str(), &Corpus);<br>
>>> >>> +  }<br>
>>> >>> +<br>
>>> >>> +  static void AlarmCallback();<br>
>>> >>> +<br>
>>> >>> + private:<br>
>>> >>> +  size_t MutateAndTestOne(Unit *U);<br>
>>> >>> +  size_t RunOne(const Unit &U);<br>
>>> >>> +  void WriteToOutputCorpus(const Unit &U);<br>
>>> >>> +  static void WriteToCrash(const Unit &U, const char *Prefix);<br>
>>> >>> +<br>
>>> >>> +  void SetDeathCallback();<br>
>>> >>> +  static void DeathCallback();<br>
>>> >>> +  static Unit CurrentUnit;<br>
>>> >>> +<br>
>>> >>> +  size_t TotalNumberOfRuns = 0;<br>
>>> >>> +<br>
>>> >>> +  std::vector<Unit> Corpus;<br>
>>> >>> +  FuzzingOptions Options;<br>
>>> >>> +  system_clock::time_point ProcessStartTime = system_clock::now();<br>
>>> >>> +  static system_clock::time_point UnitStartTime;<br>
>>> >>> +};<br>
>>> >>> +<br>
>>> >>> +};  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,161 @@<br>
>>> >>> +//===- FuzzerLoop.cpp - Fuzzer's main loop<br>
>>> >>> --------------------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Fuzzer's main loop.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +#include <sanitizer/asan_interface.h><br>
>>> ><br>
>>> > Please do not assume everyone has asan checked out. Also, this is<br>
>>> > using a system include path on Windows instead of a project include<br>
>>> > path.<br>
>>> ><br>
>>> >>> +#include <algorithm><br>
>>> >>> +#include <string><br>
>>> >>> +#include <iostream><br>
>>> >>> +#include <stdlib.h><br>
>>> ><br>
>>> > Why are we including a C header instead of cstdlib?<br>
>>> ><br>
>>> >>> +<br>
>>> >>> +// This function should be defined by the user.<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size);<br>
>>> >>> +<br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +<br>
>>> >>> +// static<br>
>>> >>> +Unit Fuzzer::CurrentUnit;<br>
>>> >>> +system_clock::time_point Fuzzer::UnitStartTime;<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::SetDeathCallback() {<br>
>>> >>> +  __sanitizer_set_death_callback(DeathCallback);<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::DeathCallback() {<br>
>>> >>> +  std::cerr << "DEATH: " <<  std::endl;<br>
>>> >>> +  Print(CurrentUnit, "\n");<br>
>>> >>> +  PrintASCII(CurrentUnit, "\n");<br>
>>> >>> +  WriteToCrash(CurrentUnit, "crash-");<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::AlarmCallback() {<br>
>>> >>> +  size_t Seconds =<br>
>>> >>> +      duration_cast<seconds>(system_clock::now() -<br>
>>> >>> UnitStartTime).count();<br>
>>> >>> +  std::cerr << "ALARM: working on the last Unit for " << Seconds <<<br>
>>> >>> " seconds"<br>
>>> >>> +            << std::endl;<br>
>>> >>> +  if (Seconds > 60) {<br>
>>> >>> +    Print(CurrentUnit, "\n");<br>
>>> >>> +    PrintASCII(CurrentUnit, "\n");<br>
>>> >>> +    WriteToCrash(CurrentUnit, "timeout-");<br>
>>> >>> +  }<br>
>>> >>> +  abort();<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::ShuffleAndMinimize() {<br>
>>> >>> +  if (Options.Verbosity)<br>
>>> >>> +    std::cerr << "Shuffle: " << Corpus.size() << "\n";<br>
>>> >>> +  std::vector<Unit> NewCorpus;<br>
>>> >>> +  random_shuffle(Corpus.begin(), Corpus.end());<br>
>>> >>> +  size_t MaxCov = 0;<br>
>>> >>> +  Unit &U = CurrentUnit;<br>
>>> >>> +  for (const auto &C : Corpus) {<br>
>>> >>> +    for (size_t First = 0; First < 1; First++) {<br>
>>> >>> +      U.clear();<br>
>>> >>> +      size_t Last = std::min(First + Options.MaxLen, C.size());<br>
>>> >>> +      U.insert(U.begin(), C.begin() + First, C.begin() + Last);<br>
>>> >>> +      size_t NewCoverage = RunOne(U);<br>
>>> >>> +      if (NewCoverage) {<br>
>>> >>> +        MaxCov = NewCoverage;<br>
>>> >>> +        NewCorpus.push_back(U);<br>
>>> >>> +        if (Options.Verbosity >= 2)<br>
>>> >>> +          std::cerr << "NEW0: " << NewCoverage << "\n";<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +  Corpus = NewCorpus;<br>
>>> >>> +  if (Options.Verbosity)<br>
>>> >>> +    std::cerr << "Shuffle done: " << Corpus.size() << " IC: " <<<br>
>>> >>> MaxCov << "\n";<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +size_t Fuzzer::RunOne(const Unit &U) {<br>
>>> >>> +  UnitStartTime = system_clock::now();<br>
>>> >>> +  TotalNumberOfRuns++;<br>
>>> >>> +  size_t OldCoverage = __sanitizer_get_total_unique_coverage();<br>
>>> >>> +  TestOneInput(U.data(), U.size());<br>
>>> >>> +  size_t NewCoverage = __sanitizer_get_total_unique_coverage();<br>
>>> >>> +  if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&<br>
>>> >>> Options.Verbosity) {<br>
>>> >>> +    size_t Seconds =<br>
>>> >>> +        duration_cast<seconds>(system_clock::now() -<br>
>>> >>> ProcessStartTime).count();<br>
>>> >>> +    std::cerr<br>
>>> >>> +        << "#" << TotalNumberOfRuns<br>
>>> >>> +        << "\tcov: " << NewCoverage<br>
>>> >>> +        << "\texec/s: " << (Seconds ? TotalNumberOfRuns / Seconds :<br>
>>> >>> 0) << "\n";<br>
>>> >>> +  }<br>
>>> >>> +  if (NewCoverage > OldCoverage)<br>
>>> >>> +    return NewCoverage;<br>
>>> >>> +  return 0;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::WriteToOutputCorpus(const Unit &U) {<br>
>>> >>> +  if (Options.OutputCorpus.empty()) return;<br>
>>> >>> +  std::string Path = Options.OutputCorpus + "/" + Hash(U);<br>
>>> >>> +  WriteToFile(U, Path);<br>
>>> >>> +  if (Options.Verbosity >= 2)<br>
>>> >>> +    std::cerr << "Written to " << Path << std::endl;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Fuzzer::WriteToCrash(const Unit &U, const char *Prefix) {<br>
>>> >>> +  std::string Path = Prefix + Hash(U);<br>
>>> >>> +  WriteToFile(U, Path);<br>
>>> >>> +  std::cerr << "CRASHED; file written to " << Path << std::endl;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +size_t Fuzzer::MutateAndTestOne(Unit *U) {<br>
>>> >>> +  size_t NewUnits = 0;<br>
>>> >>> +  for (size_t i = 0; i < Options.MutateDepth; i++) {<br>
>>> >>> +    Mutate(U, Options.MaxLen);<br>
>>> >>> +    if (U->empty()) continue;<br>
>>> >>> +    size_t NewCoverage = RunOne(*U);<br>
>>> >>> +    if (NewCoverage) {<br>
>>> >>> +      Corpus.push_back(*U);<br>
>>> >>> +      NewUnits++;<br>
>>> >>> +      if (Options.Verbosity) {<br>
>>> >>> +        std::cerr << "#" << TotalNumberOfRuns<br>
>>> >>> +                  << "\tNEW: " << NewCoverage<br>
>>> >>> +                  << " L: " << U->size()<br>
>>> >>> +                  << "\t";<br>
>>> >>> +        if (U->size() < 30) {<br>
>>> >>> +          PrintASCII(*U);<br>
>>> >>> +          std::cerr << "\t";<br>
>>> >>> +          Print(*U);<br>
>>> >>> +        }<br>
>>> >>> +        std::cerr << "\n";<br>
>>> >>> +      }<br>
>>> >>> +      WriteToOutputCorpus(*U);<br>
>>> >>> +      if (Options.ExitOnFirst)<br>
>>> >>> +        exit(0);<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +  return NewUnits;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +size_t Fuzzer::Loop(size_t NumIterations) {<br>
>>> >>> +  size_t NewUnits = 0;<br>
>>> >>> +  for (size_t i = 1; i <= NumIterations; i++) {<br>
>>> >>> +    if (Options.DoCrossOver) {<br>
>>> >>> +      for (size_t J1 = 0; J1 < Corpus.size(); J1++) {<br>
>>> >>> +        for (size_t J2 = 0; J2 < Corpus.size(); J2++) {<br>
>>> >>> +          CurrentUnit.clear();<br>
>>> >>> +          CrossOver(Corpus[J1], Corpus[J2], &CurrentUnit,<br>
>>> >>> Options.MaxLen);<br>
>>> >>> +          NewUnits += MutateAndTestOne(&CurrentUnit);<br>
>>> >>> +        }<br>
>>> >>> +      }<br>
>>> >>> +    } else {  // No CrossOver<br>
>>> >>> +      for (size_t J = 0; J < Corpus.size(); J++) {<br>
>>> >>> +        CurrentUnit = Corpus[J];<br>
>>> >>> +        NewUnits += MutateAndTestOne(&CurrentUnit);<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +  return NewUnits;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +}  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerMain.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMain.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerMain.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerMain.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,143 @@<br>
>>> >>> +//===- FuzzerMain.cpp - main() function and flags<br>
>>> >>> -------------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// main() and flags.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +<br>
>>> >>> +#include <climits><br>
>>> >>> +#include <cstring><br>
>>> >>> +#include <unistd.h><br>
>>> ><br>
>>> > unistd.h does not exist on Windows with MSVC.<br>
>>> ><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +// ASAN options:<br>
>>> >>> +//   * don't dump the coverage to disk.<br>
>>> >>> +extern "C" const char* __asan_default_options() { return<br>
>>> >>> "coverage_pcs=0"; }<br>
>>> >>> +<br>
>>> >>> +// Program arguments.<br>
>>> >>> +struct FlagDescription {<br>
>>> >>> +  const char *Name;<br>
>>> >>> +  const char *Description;<br>
>>> >>> +  int   Default;<br>
>>> >>> +  int   *Flag;<br>
>>> >>> +};<br>
>>> >>> +<br>
>>> >>> +struct {<br>
>>> >>> +#define FUZZER_FLAG(Type, Name, Default, Description) Type Name;<br>
>>> >>> +#include "FuzzerFlags.def"<br>
>>> >>> +#undef FUZZER_FLAG<br>
>>> >>> +} Flags;<br>
>>> >>> +<br>
>>> >>> +static FlagDescription FlagDescriptions [] {<br>
>>> >>> +#define FUZZER_FLAG(Type, Name, Default, Description) {#Name,<br>
>>> >>> Description, Default, &Flags.Name},<br>
>>> >>> +#include "FuzzerFlags.def"<br>
>>> >>> +#undef FUZZER_FLAG<br>
>>> >>> +};<br>
>>> >>> +<br>
>>> >>> +static const size_t kNumFlags =<br>
>>> >>> +    sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]);<br>
>>> >>> +<br>
>>> >>> +static std::vector<std::string> inputs;<br>
>>> >>> +static const char *ProgName;<br>
>>> >>> +<br>
>>> >>> +static void PrintHelp() {<br>
>>> >>> +  std::cerr << "Usage: " << ProgName<br>
>>> >>> +            << " [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...]<br>
>>> >>> ]\n";<br>
>>> >>> +  std::cerr << "\nFlags: (strictly in form -flag=value)\n";<br>
>>> >>> +  size_t MaxFlagLen = 0;<br>
>>> >>> +  for (size_t F = 0; F < kNumFlags; F++)<br>
>>> >>> +    MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name),<br>
>>> >>> MaxFlagLen);<br>
>>> >>> +<br>
>>> >>> +  for (size_t F = 0; F < kNumFlags; F++) {<br>
>>> >>> +    const auto &D = FlagDescriptions[F];<br>
>>> >>> +    std::cerr << "  " << D.Name;<br>
>>> >>> +    for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++)<br>
>>> >>> +      std::cerr << " ";<br>
>>> >>> +    std::cerr << "\t";<br>
>>> >>> +    std::cerr << D.Default << "\t" << D.Description << "\n";<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +static const char *FlagValue(const char *Param, const char *Name) {<br>
>>> >>> +  size_t Len = strlen(Name);<br>
>>> >>> +  if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 &&<br>
>>> >>> +      Param[Len + 1] == '=')<br>
>>> >>> +      return &Param[Len + 2];<br>
>>> >>> +  return nullptr;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +static bool ParseOneFlag(const char *Param) {<br>
>>> >>> +  if (Param[0] != '-') return false;<br>
>>> >>> +  for (size_t F = 0; F < kNumFlags; F++) {<br>
>>> >>> +    const char *Name = FlagDescriptions[F].Name;<br>
>>> >>> +    const char *Str = FlagValue(Param, Name);<br>
>>> >>> +    if (Str)  {<br>
>>> >>> +      int Val = std::stol(Str);<br>
>>> >>> +      *FlagDescriptions[F].Flag = Val;<br>
>>> >>> +      if (Flags.verbosity >= 2)<br>
>>> >>> +        std::cerr << "Flag: " << Name << " " << Val << "\n";<br>
>>> >>> +      return true;<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +  PrintHelp();<br>
>>> >>> +  exit(1);<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +// We don't use any library to minimize dependencies.<br>
>>> >>> +static void ParseFlags(int argc, char **argv) {<br>
>>> >>> +  for (size_t F = 0; F < kNumFlags; F++)<br>
>>> >>> +    *FlagDescriptions[F].Flag = FlagDescriptions[F].Default;<br>
>>> >>> +  for (int A = 1; A < argc; A++) {<br>
>>> >>> +    if (ParseOneFlag(argv[A])) continue;<br>
>>> >>> +    inputs.push_back(argv[A]);<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +int main(int argc, char **argv) {<br>
>>> >>> +  using namespace fuzzer;<br>
>>> >>> +<br>
>>> >>> +  ProgName = argv[0];<br>
>>> >>> +  ParseFlags(argc, argv);<br>
>>> >>> +  if (Flags.help) {<br>
>>> >>> +    PrintHelp();<br>
>>> >>> +    return 0;<br>
>>> >>> +  }<br>
>>> >>> +  Fuzzer::FuzzingOptions Options;<br>
>>> >>> +  Options.Verbosity = Flags.verbosity;<br>
>>> >>> +  Options.MaxLen = Flags.max_len;<br>
>>> >>> +  Options.DoCrossOver = Flags.cross_over;<br>
>>> >>> +  Options.MutateDepth = Flags.mutate_depth;<br>
>>> >>> +  Options.ExitOnFirst = Flags.exit_on_first;<br>
>>> >>> +  if (!inputs.empty())<br>
>>> >>> +    Options.OutputCorpus = inputs[0];<br>
>>> >>> +  Fuzzer F(Options);<br>
>>> >>> +<br>
>>> >>> +  unsigned seed = Flags.seed;<br>
>>> >>> +  // Initialize seed.<br>
>>> >>> +  if (seed == 0)<br>
>>> >>> +    seed = time(0) * 10000 + getpid();<br>
>>> >>> +  if (Flags.verbosity)<br>
>>> >>> +    std::cerr << "Seed: " << seed << "\n";<br>
>>> >>> +  srand(seed);<br>
>>> >>> +<br>
>>> >>> +  // Timer<br>
>>> >>> +  if (Flags.timeout > 0)<br>
>>> >>> +    SetTimer(Flags.timeout);<br>
>>> >>> +<br>
>>> >>> +  for (auto &inp : inputs)<br>
>>> >>> +    F.ReadDir(inp);<br>
>>> >>> +<br>
>>> >>> +  if (F.CorpusSize() == 0)<br>
>>> >>> +    F.AddToCorpus(Unit());  // Can't fuzz empty corpus, so add an<br>
>>> >>> empty input.<br>
>>> >>> +  F.ShuffleAndMinimize();<br>
>>> >>> +  F.Loop(Flags.iterations < 0 ? INT_MAX : Flags.iterations);<br>
>>> >>> +  if (Flags.verbosity)<br>
>>> >>> +    std::cerr << "Done\n";<br>
>>> >>> +  return 1;<br>
>>> >>> +}<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,62 @@<br>
>>> >>> +//===- FuzzerMutate.cpp - Mutate a test input<br>
>>> >>> -----------------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Mutate a test input.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +<br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +<br>
>>> >>> +static char FlipRandomBit(char X) {<br>
>>> >>> +  int Bit = rand() % 8;<br>
>>> >>> +  char Mask = 1 << Bit;<br>
>>> >>> +  char R;<br>
>>> >>> +  if (X & (1 << Bit))<br>
>>> >>> +    R = X & ~Mask;<br>
>>> >>> +  else<br>
>>> >>> +    R = X | Mask;<br>
>>> >>> +  assert(R != X);<br>
>>> >>> +  return R;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +static char RandCh() {<br>
>>> >>> +  if (rand() % 2) return rand();<br>
>>> >>> +  const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~.";<br>
>>> >>> +  return Special[rand() % (sizeof(Special) - 1)];<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void Mutate(Unit *U, size_t MaxLen) {<br>
>>> >>> +  assert(MaxLen > 0);<br>
>>> >>> +  assert(U->size() <= MaxLen);<br>
>>> >>> +  switch (rand() % 3) {<br>
>>> >>> +  case 0:<br>
>>> >>> +    if (U->size())<br>
>>> >>> +      U->erase(U->begin() + rand() % U->size());<br>
>>> >>> +    break;<br>
>>> >>> +  case 1:<br>
>>> >>> +    if (U->empty()) {<br>
>>> >>> +      U->push_back(RandCh());<br>
>>> >>> +    } else if (U->size() < MaxLen) {<br>
>>> >>> +      U->insert(U->begin() + rand() % U->size(), RandCh());<br>
>>> >>> +    } else { // At MaxLen.<br>
>>> >>> +      uint8_t Ch = RandCh();<br>
>>> >>> +      size_t Idx = rand() % U->size();<br>
>>> >>> +      (*U)[Idx] = Ch;<br>
>>> >>> +    }<br>
>>> >>> +    break;<br>
>>> >>> +  default:<br>
>>> >>> +    if (!U->empty()) {<br>
>>> >>> +      size_t idx = rand() % U->size();<br>
>>> >>> +      (*U)[idx] = FlipRandomBit((*U)[idx]);<br>
>>> >>> +    }<br>
>>> >>> +    break;<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +}  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/FuzzerUtil.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,61 @@<br>
>>> >>> +//===- FuzzerUtil.cpp - Misc utils<br>
>>> >>> ----------------------------------------===//<br>
>>> >>> +//<br>
>>> >>> +//                     The LLVM Compiler Infrastructure<br>
>>> >>> +//<br>
>>> >>> +// This file is distributed under the University of Illinois Open<br>
>>> >>> Source<br>
>>> >>> +// License. See LICENSE.TXT for details.<br>
>>> >>> +//<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +// Misc utils.<br>
>>> >>><br>
>>> >>> +//===----------------------------------------------------------------------===//<br>
>>> >>> +<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +#include <iostream><br>
>>> >>> +#include <sys/time.h><br>
>>> ><br>
>>> > sys/time.h does not exist on Windows with MSVC.<br>
>>> ><br>
>>> >>> +#include <cassert><br>
>>> >>> +#include <cstring><br>
>>> >>> +#include <signal.h><br>
>>> >>> +<br>
>>> >>> +namespace fuzzer {<br>
>>> >>> +<br>
>>> >>> +void Print(const Unit &v, const char *PrintAfter) {<br>
>>> >>> +  std::cerr << v.size() << ": ";<br>
>>> >>> +  for (auto x : v)<br>
>>> >>> +    std::cerr << (unsigned) x << " ";<br>
>>> >>> +  std::cerr << PrintAfter;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void PrintASCII(const Unit &U, const char *PrintAfter) {<br>
>>> >>> +  for (auto X : U)<br>
>>> >>> +    std::cerr << (char)((isascii(X) && X >= ' ') ? X : '?');<br>
>>> >>> +  std::cerr << PrintAfter;<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +std::string Hash(const Unit &in) {<br>
>>> >>> +  size_t h1 = 0, h2 = 0;<br>
>>> >>> +  for (auto x : in) {<br>
>>> >>> +    h1 += x;<br>
>>> >>> +    h1 *= 5;<br>
>>> >>> +    h2 += x;<br>
>>> >>> +    h2 *= 7;<br>
>>> >>> +  }<br>
>>> >>> +  return std::to_string(h1) + std::to_string(h2);<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +static void AlarmHandler(int, siginfo_t *, void *) {<br>
>>> >>> +  Fuzzer::AlarmCallback();<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +void SetTimer(int Seconds) {<br>
>>> >>> +  struct itimerval T {{Seconds, 0}, {Seconds, 0}};<br>
>>> >>> +  std::cerr << "SetTimer " << Seconds << "\n";<br>
>>> >>> +  int Res = setitimer(ITIMER_REAL, &T, nullptr);<br>
>>> >>> +  assert(Res == 0);<br>
>>> >>> +  struct sigaction sigact;<br>
>>> >>> +  memset(&sigact, 0, sizeof(sigact));<br>
>>> >>> +  sigact.sa_sigaction = AlarmHandler;<br>
>>> >>> +  Res = sigaction(SIGALRM, &sigact, 0);<br>
>>> >>> +  assert(Res == 0);<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>> +}  // namespace fuzzer<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/README.txt<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/README.txt (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/README.txt Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,56 @@<br>
>>> >>> +===============================<br>
>>> >>> +Fuzzer -- a library for coverage-guided fuzz testing.<br>
>>> >>> +===============================<br>
>>> >>> +<br>
>>> >>> +This library is intended primarily for in-process coverage-guided<br>
>>> >>> fuzz testing<br>
>>> >>> +(fuzzing) of other libraries. The typical workflow looks like this:<br>
>>> >>> +<br>
>>> >>> +  * Build the Fuzzer library as a static archive (or just a set of<br>
>>> >>> .o files).<br>
>>> >>> +    Note that the Fuzzer contains the main() function.<br>
>>> >>> +    Preferably do *not* use sanitizers while building the Fuzzer.<br>
>>> >>> +  * Build the library you are going to test with<br>
>>> >>> -fsanitize-coverage=[234]<br>
>>> >>> +    and one of the sanitizers. We recommend to build the library in<br>
>>> >>> several<br>
>>> >>> +    different modes (e.g. asan, msan, lsan, ubsan, etc) and even<br>
>>> >>> using different<br>
>>> >>> +    optimizations options (e.g. -O0, -O1, -O2) to diversify testing.<br>
>>> >>> +  * Build a test driver using the same options as the library.<br>
>>> >>> +    The test driver is a C/C++ file containing interesting calls to<br>
>>> >>> the library<br>
>>> >>> +    inside a single function:<br>
>>> >>> +    extern "C" void TestOneInput(const uint8_t *Data, size_t Size);<br>
>>> >>> +  * Link the Fuzzer, the library and the driver together into an<br>
>>> >>> executable<br>
>>> >>> +    using the same sanitizer options as for the library.<br>
>>> >>> +  * Collect the initial corpus of inputs for the<br>
>>> >>> +    fuzzer (a directory with test inputs, one file per input).<br>
>>> >>> +    The better your inputs are the faster you will find something<br>
>>> >>> interesting.<br>
>>> >>> +    Also try to keep your inputs small, otherwise the Fuzzer will<br>
>>> >>> run too slow.<br>
>>> >>> +  * Run the fuzzer with the test corpus. As new interesting test<br>
>>> >>> cases are<br>
>>> >>> +    discovered they will be added to the corpus. If a bug is<br>
>>> >>> discovered by<br>
>>> >>> +    the sanitizer (asan, etc) it will be reported as usual and the<br>
>>> >>> reproducer<br>
>>> >>> +    will be written to disk.<br>
>>> >>> +    Each Fuzzer process is single-threaded (unless the library<br>
>>> >>> starts its own<br>
>>> >>> +    threads). You can run the Fuzzer on the same corpus in multiple<br>
>>> >>> processes.<br>
>>> >>> +    in parallel. For run-time options run the Fuzzer binary with<br>
>>> >>> '-help=1'.<br>
>>> >>> +<br>
>>> >>> +<br>
>>> >>> +The Fuzzer is similar in concept to AFL<br>
>>> >>> (<a href="http://lcamtuf.coredump.cx/afl/" target="_blank">http://lcamtuf.coredump.cx/afl/</a>),<br>
>>> >>> +but uses in-process Fuzzing, which is more fragile, more<br>
>>> >>> restrictive, but<br>
>>> >>> +potentially much faster as it has no overhead for process start-up.<br>
>>> >>> +It uses LLVM's "Sanitizer Coverage" instrumentation to get<br>
>>> >>> in-process<br>
>>> >>> +coverage-feedback<br>
>>> >>> <a href="https://code.google.com/p/address-sanitizer/wiki/AsanCoverage" target="_blank">https://code.google.com/p/address-sanitizer/wiki/AsanCoverage</a><br>
>>> >>> +<br>
>>> >>> +The code resides in the LLVM repository and is (or will be) used by<br>
>>> >>> various<br>
>>> >>> +parts of LLVM, but the Fuzzer itself does not (and should not)<br>
>>> >>> depend on any<br>
>>> >>> +part of LLVM and can be used for other projects. Ideally, the<br>
>>> >>> Fuzzer's code<br>
>>> >>> +should not have any external dependencies. Right now it uses STL,<br>
>>> >>> which may need<br>
>>> >>> +to be fixed later.<br>
>>> >>> +<br>
>>> >>> +Examples of usage in LLVM:<br>
>>> >>> +  * clang-format-fuzzer. The inputs are random pieces of C++-like<br>
>>> >>> text.<br>
>>> >>> +  * TODO: add more<br>
>>> >>> +<br>
>>> >>> +Toy example (see SimpleTest.cpp):<br>
>>> >>> +a simple function that does something interesting if it receives<br>
>>> >>> bytes "Hi!".<br>
>>> >>> +  # Build the Fuzzer with asan:<br>
>>> >>> +  % clang++ -std=c++11 -fsanitize=address -fsanitize-coverage=3 -O1<br>
>>> >>> -g \<br>
>>> >>> +     Fuzzer*.cpp test/SimpleTest.cpp<br>
>>> >>> +  # Run the fuzzer with no corpus (assuming on empty input)<br>
>>> >>> +  % ./a.out<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/ExactTest.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/ExactTest.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/ExactTest.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/ExactTest.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/ExactTest.cpp Tue Jan 27 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,21 @@<br>
>>> >>> +// Simple test for a fuzzer. The fuzzer must find the string<br>
>>> >>> "FUZZER".<br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +static volatile int Sink;<br>
>>> >>> +<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size) {<br>
>>> >>> +  int bits = 0;<br>
>>> >>> +  if (Size > 0 && Data[0] == 'F') bits |= 1;<br>
>>> >>> +  if (Size > 1 && Data[1] == 'U') bits |= 2;<br>
>>> >>> +  if (Size > 2 && Data[2] == 'Z') bits |= 4;<br>
>>> >>> +  if (Size > 3 && Data[3] == 'Z') bits |= 8;<br>
>>> >>> +  if (Size > 4 && Data[4] == 'E') bits |= 16;<br>
>>> >>> +  if (Size > 5 && Data[5] == 'R') bits |= 32;<br>
>>> >>> +  if (bits == 63) {<br>
>>> >>> +    std::cerr <<  "BINGO!\n";<br>
>>> >>> +    abort();<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/InfiniteTest.cpp Tue Jan 27 16:08:41<br>
>>> >>> 2015<br>
>>> >>> @@ -0,0 +1,19 @@<br>
>>> >>> +// Simple test for a fuzzer. The fuzzer must find the string "Hi!".<br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +static volatile int Sink;<br>
>>> >>> +<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size) {<br>
>>> >>> +  if (Size > 0 && Data[0] == 'H') {<br>
>>> >>> +    Sink = 1;<br>
>>> >>> +    if (Size > 1 && Data[1] == 'i') {<br>
>>> >>> +      Sink = 2;<br>
>>> >>> +      if (Size > 2 && Data[2] == '!') {<br>
>>> >>> +        Size = 2;<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/NullDerefTest.cpp Tue Jan 27 16:08:41<br>
>>> >>> 2015<br>
>>> >>> @@ -0,0 +1,21 @@<br>
>>> >>> +// Simple test for a fuzzer. The fuzzer must find the string "Hi!".<br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +static volatile int Sink;<br>
>>> >>> +static volatile int *Null = 0;<br>
>>> >>> +<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size) {<br>
>>> >>> +  if (Size > 0 && Data[0] == 'H') {<br>
>>> >>> +    Sink = 1;<br>
>>> >>> +    if (Size > 1 && Data[1] == 'i') {<br>
>>> >>> +      Sink = 2;<br>
>>> >>> +      if (Size > 2 && Data[2] == '!') {<br>
>>> >>> +        std::cout << "Found the target, dereferencing NULL\n";<br>
>>> >>> +        *Null = 1;<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/SimpleTest.cpp Tue Jan 27 16:08:41<br>
>>> >>> 2015<br>
>>> >>> @@ -0,0 +1,20 @@<br>
>>> >>> +// Simple test for a fuzzer. The fuzzer must find the string "Hi!".<br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +static volatile int Sink;<br>
>>> >>> +<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size) {<br>
>>> >>> +  if (Size > 0 && Data[0] == 'H') {<br>
>>> >>> +    Sink = 1;<br>
>>> >>> +    if (Size > 1 && Data[1] == 'i') {<br>
>>> >>> +      Sink = 2;<br>
>>> >>> +      if (Size > 2 && Data[2] == '!') {<br>
>>> >>> +        std::cout << "Found the target, exiting\n";<br>
>>> >>> +        exit(0);<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/TestFuzzerCrossOver.cpp Tue Jan 27<br>
>>> >>> 16:08:41 2015<br>
>>> >>> @@ -0,0 +1,13 @@<br>
>>> >>> +#include "FuzzerInternal.h"<br>
>>> >>> +<br>
>>> >>> +int main() {<br>
>>> >>> +  using namespace fuzzer;<br>
>>> >>> +  Unit A({0, 1, 2, 3, 4}), B({5, 6, 7, 8, 9});<br>
>>> >>> +  Unit C;<br>
>>> >>> +  for (size_t Len = 1; Len < 15; Len++) {<br>
>>> >>> +    for (int Iter = 0; Iter < 1000; Iter++) {<br>
>>> >>> +      CrossOver(A, B, &C, Len);<br>
>>> >>> +      Print(C);<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>><br>
>>> >>> Added: llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp<br>
>>> >>> URL:<br>
>>> >>> <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp?rev=227252&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp?rev=227252&view=auto</a><br>
>>> >>><br>
>>> >>> ==============================================================================<br>
>>> >>> --- llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp (added)<br>
>>> >>> +++ llvm/trunk/lib/Fuzzer/test/TimeoutTest.cpp Tue Jan 27 16:08:41<br>
>>> >>> 2015<br>
>>> >>> @@ -0,0 +1,21 @@<br>
>>> >>> +// Simple test for a fuzzer. The fuzzer must find the string "Hi!".<br>
>>> >>> +#include <cstdlib><br>
>>> >>> +#include <cstddef><br>
>>> >>> +#include <iostream><br>
>>> >>> +<br>
>>> >>> +static volatile int Sink;<br>
>>> >>> +<br>
>>> >>> +extern "C" void TestOneInput(const uint8_t *Data, size_t Size) {<br>
>>> >>> +  if (Size > 0 && Data[0] == 'H') {<br>
>>> >>> +    Sink = 1;<br>
>>> >>> +    if (Size > 1 && Data[1] == 'i') {<br>
>>> >>> +      Sink = 2;<br>
>>> >>> +      if (Size > 2 && Data[2] == '!') {<br>
>>> >>> +        Size = 2;<br>
>>> >>> +        while (Sink)<br>
>>> >>> +          ;<br>
>>> >>> +      }<br>
>>> >>> +    }<br>
>>> >>> +  }<br>
>>> >>> +}<br>
>>> >>> +<br>
>>> ><br>
>>> > Aside from the obvious errors for MSVC, it does not compile cleanly:<br>
>>> ><br>
>>> > Warning 1 warning C4530: C++ exception handler used, but unwind<br>
>>> > semantics are not enabled. Specify /EHsc<br>
>>> > (E:\llvm\llvm\lib\Fuzzer\FuzzerLoop.cpp) D:\Program Files Warning 5<br>
>>> > warning C4305: 'initializing' : truncation from 'int' to 'bool'<br>
>>> > (E:\llvm\llvm\lib\Fuzzer\FuzzerIO.cpp)<br>
>>> > e:\llvm\llvm\lib\fuzzer\FuzzerInternal.h 44<br>
>>> > Warning 13 warning C4530: C++ exception handler used, but unwind<br>
>>> > semantics are not enabled. Specify /EHsc D:\Program Files<br>
>>> > (x86)\Microsoft Visual Studio<br>
>>> ><br>
>>> > (And some variation of these repeat dozens of times.)<br>
>>> ><br>
>>> > ~Aaron<br>
>>> ><br>
>>> >>><br>
>>> >>><br>
>>> >>> _______________________________________________<br>
>>> >>> llvm-commits mailing list<br>
>>> >>> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
>>> >>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
>><br>
>><br>
><br>
</div></div></blockquote></div><br></div></div>