[compiler-rt] r360378 - [libFuzzer] implement -focus_function=auto, to be used with Data Flow Traces

Russell Gallop via llvm-commits llvm-commits at lists.llvm.org
Tue May 28 07:23:29 PDT 2019


Hi Kostya,

I think that the last line of only-some-bytes.test fails intermittently.
About 1 in 100 runs of the test, the line:
RUN: not %t-Fuzz -focus_function=auto -data_flow_trace=%t/C_DFT %t/C
-jobs=50 -runs=200000 -use_value_profile=1 2> %t/log

does not produce the "BINGO" message. It just keeps getting to 200000 (e.g.)
...
#145518 REDUCE cov: 14 ft: 109 corp: 66/172Kb focus: 66 lim: 4099 exec/s:
145518 rss: 389Mb L: 2056/4099 MS: 1 EraseBytes-
#145801 REDUCE cov: 14 ft: 109 corp: 66/172Kb focus: 66 lim: 4099 exec/s:
145801 rss: 389Mb L: 2055/4099 MS: 3 CMP-EraseBytes-InsertRepeatedBytes-
DE: "h\xd8V\x00"-
#170053 RELOAD cov: 14 ft: 116 corp: 72/184Kb focus: 72 lim: 4099 exec/s:
85026 rss: 395Mb
#200000 DONE   cov: 14 ft: 116 corp: 72/184Kb focus: 72 lim: 4099 exec/s:
100000 rss: 396Mb

I'm testing with:
#!/bin/bash -xe
for ((i=1;i<=1000;i++));
do
  echo "Run ${i}"
  ./bin/llvm-lit -v ../compiler-rt/test/fuzzer/only-some-bytes.test
done

Please could you take a look?

Thanks
Russ

On Thu, 9 May 2019 at 22:27, Kostya Serebryany via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: kcc
> Date: Thu May  9 14:29:45 2019
> New Revision: 360378
>
> URL: http://llvm.org/viewvc/llvm-project?rev=360378&view=rev
> Log:
> [libFuzzer] implement -focus_function=auto, to be used with Data Flow
> Traces
>
> Modified:
>     compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp
>     compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.h
>     compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
>     compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
>     compiler-rt/trunk/lib/fuzzer/tests/FuzzerUnittest.cpp
>     compiler-rt/trunk/test/fuzzer/OnlySomeBytesTest.cpp
>     compiler-rt/trunk/test/fuzzer/dataflow.test
>     compiler-rt/trunk/test/fuzzer/only-some-bytes.test
>
> Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp (original)
> +++ compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.cpp Thu May  9
> 14:29:45 2019
> @@ -10,34 +10,141 @@
>
>  #include "FuzzerDataFlowTrace.h"
>  #include "FuzzerIO.h"
> +#include "FuzzerRandom.h"
>
>  #include <cstdlib>
>  #include <fstream>
> +#include <sstream>
>  #include <string>
>  #include <vector>
>
>  namespace fuzzer {
> +static const char *kFunctionsTxt = "functions.txt";
> +
> +bool BlockCoverage::AppendCoverage(const std::string &S) {
> +  std::stringstream SS(S);
> +  return AppendCoverage(SS);
> +}
> +
> +// Coverage lines have this form:
> +// CN X Y Z T
> +// where N is the number of the function, T is the total number of
> instrumented
> +// BBs, and X,Y,Z, if present, are the indecies of covered BB.
> +// BB #0, which is the entry block, is not explicitly listed.
> +bool BlockCoverage::AppendCoverage(std::istream &IN) {
> +  std::string L;
> +  while (std::getline(IN, L, '\n')) {
> +    if (L.empty() || L[0] != 'C')
> +      continue; // Ignore non-coverage lines.
> +    std::stringstream SS(L.c_str() + 1);
> +    size_t FunctionId  = 0;
> +    SS >> FunctionId;
> +    Vector<uint32_t> CoveredBlocks;
> +    while (true) {
> +      uint32_t BB = 0;
> +      SS >> BB;
> +      if (!SS) break;
> +      CoveredBlocks.push_back(BB);
> +    }
> +    if (CoveredBlocks.empty()) return false;
> +    uint32_t NumBlocks = CoveredBlocks.back();
> +    CoveredBlocks.pop_back();
> +    for (auto BB : CoveredBlocks)
> +      if (BB >= NumBlocks) return false;
> +    auto It = Functions.find(FunctionId);
> +    auto &Counters =
> +        It == Functions.end()
> +            ? Functions.insert({FunctionId, Vector<uint32_t>(NumBlocks)})
> +                  .first->second
> +            : It->second;
> +
> +    if (Counters.size() != NumBlocks) return false;  // wrong number of
> blocks.
> +
> +    Counters[0]++;
> +    for (auto BB : CoveredBlocks)
> +      Counters[BB]++;
> +  }
> +  return true;
> +}
> +
> +// Assign weights to each function.
> +// General principles:
> +//   * any uncovered function gets weight 0.
> +//   * a function with lots of uncovered blocks gets bigger weight.
> +//   * a function with a less frequently executed code gets bigger weight.
> +Vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
> +  Vector<double> Res(NumFunctions);
> +  for (auto It : Functions) {
> +    auto FunctionID = It.first;
> +    auto Counters = It.second;
> +    auto &Weight = Res[FunctionID];
> +    Weight = 1000.;  // this function is covered.
> +    Weight /= SmallestNonZeroCounter(Counters);
> +    Weight *= NumberOfUncoveredBlocks(Counters) + 1;  // make sure it's
> not 0.
> +  }
> +  return Res;
> +}
> +
> +void DataFlowTrace::ReadCoverage(const std::string &DirPath) {
> +  Vector<SizedFile> Files;
> +  GetSizedFilesFromDir(DirPath, &Files);
> +  for (auto &SF : Files) {
> +    auto Name = Basename(SF.File);
> +    if (Name == kFunctionsTxt) continue;
> +    std::ifstream IF(SF.File);
> +    Coverage.AppendCoverage(IF);
> +  }
> +}
>
>  void DataFlowTrace::Init(const std::string &DirPath,
> -                         const std::string &FocusFunction) {
> +                         std::string *FocusFunction,
> +                         Random &Rand) {
>    if (DirPath.empty()) return;
> -  const char *kFunctionsTxt = "functions.txt";
>    Printf("INFO: DataFlowTrace: reading from '%s'\n", DirPath.c_str());
>    Vector<SizedFile> Files;
>    GetSizedFilesFromDir(DirPath, &Files);
>    std::string L;
> +  size_t FocusFuncIdx = SIZE_MAX;
> +  Vector<std::string> FunctionNames;
>
>    // Read functions.txt
>    std::ifstream IF(DirPlusFile(DirPath, kFunctionsTxt));
> -  size_t FocusFuncIdx = SIZE_MAX;
>    size_t NumFunctions = 0;
>    while (std::getline(IF, L, '\n')) {
> +    FunctionNames.push_back(L);
>      NumFunctions++;
> -    if (FocusFunction == L)
> +    if (*FocusFunction == L)
>        FocusFuncIdx = NumFunctions - 1;
>    }
> +
> +  if (*FocusFunction == "auto") {
> +    // AUTOFOCUS works like this:
> +    // * reads the coverage data from the DFT files.
> +    // * assigns weights to functions based on coverage.
> +    // * chooses a random function according to the weights.
> +    ReadCoverage(DirPath);
> +    auto Weights = Coverage.FunctionWeights(NumFunctions);
> +    Vector<double> Intervals(NumFunctions + 1);
> +    std::iota(Intervals.begin(), Intervals.end(), 0);
> +    auto Distribution = std::piecewise_constant_distribution<double>(
> +        Intervals.begin(), Intervals.end(), Weights.begin());
> +    FocusFuncIdx = static_cast<size_t>(Distribution(Rand));
> +    *FocusFunction = FunctionNames[FocusFuncIdx];
> +    assert(FocusFuncIdx < NumFunctions);
> +    Printf("INFO: AUTOFOCUS: %zd %s\n", FocusFuncIdx,
> +           FunctionNames[FocusFuncIdx].c_str());
> +    for (size_t i = 0; i < NumFunctions; i++) {
> +      if (!Weights[i]) continue;
> +      Printf("  [%zd] W %g\tBB-tot %u\tBB-cov %u\tEntryFreq %u:\t%s\n", i,
> +             Weights[i], Coverage.GetNumberOfBlocks(i),
> +             Coverage.GetNumberOfCoveredBlocks(i), Coverage.GetCounter(i,
> 0),
> +             FunctionNames[i].c_str());
> +    }
> +  }
> +
>    if (!NumFunctions || FocusFuncIdx == SIZE_MAX || Files.size() <= 1)
>      return;
> +
>    // Read traces.
>    size_t NumTraceFiles = 0;
>    size_t NumTracesWithFocusFunction = 0;
>
> Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.h?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.h (original)
> +++ compiler-rt/trunk/lib/fuzzer/FuzzerDataFlowTrace.h Thu May  9 14:29:45
> 2019
> @@ -35,9 +35,80 @@
>  #include <string>
>
>  namespace fuzzer {
> +
> +class BlockCoverage {
> + public:
> +  bool AppendCoverage(std::istream &IN);
> +  bool AppendCoverage(const std::string &S);
> +
> +  size_t NumCoveredFunctions() const { return Functions.size(); }
> +
> +  uint32_t GetCounter(size_t FunctionId, size_t BasicBlockId) {
> +    auto It = Functions.find(FunctionId);
> +    if (It == Functions.end()) return 0;
> +    const auto &Counters = It->second;
> +    if (BasicBlockId < Counters.size())
> +      return Counters[BasicBlockId];
> +    return 0;
> +  }
> +
> +  uint32_t GetNumberOfBlocks(size_t FunctionId) {
> +    auto It = Functions.find(FunctionId);
> +    if (It == Functions.end()) return 0;
> +    const auto &Counters = It->second;
> +    return Counters.size();
> +  }
> +
> +  uint32_t GetNumberOfCoveredBlocks(size_t FunctionId) {
> +    auto It = Functions.find(FunctionId);
> +    if (It == Functions.end()) return 0;
> +    const auto &Counters = It->second;
> +    uint32_t Result = 0;
> +    for (auto Cnt: Counters)
> +      if (Cnt)
> +        Result++;
> +    return Result;
> +  }
> +
> +  Vector<double> FunctionWeights(size_t NumFunctions) const;
> +  void clear() { Functions.clear(); }
> +
> + private:
> +
> +  typedef Vector<uint32_t> CoverageVector;
> +
> +  uint32_t NumberOfCoveredBlocks(const CoverageVector &Counters) const {
> +    uint32_t Res = 0;
> +    for (auto Cnt : Counters)
> +      if (Cnt)
> +        Res++;
> +    return Res;
> +  }
> +
> +  uint32_t NumberOfUncoveredBlocks(const CoverageVector &Counters) const {
> +    return Counters.size() - NumberOfCoveredBlocks(Counters);
> +  }
> +
> +  uint32_t SmallestNonZeroCounter(const CoverageVector &Counters) const {
> +    assert(!Counters.empty());
> +    uint32_t Res = Counters[0];
> +    for (auto Cnt : Counters)
> +      if (Cnt)
> +        Res = Min(Res, Cnt);
> +    assert(Res);
> +    return Res;
> +  }
> +
> +  // Function ID => vector of counters.
> +  // Each counter represents how many input files trigger the given basic
> block.
> +  std::unordered_map<size_t, CoverageVector> Functions;
> +};
> +
>  class DataFlowTrace {
>   public:
> -  void Init(const std::string &DirPath, const std::string &FocusFunction);
> +  void ReadCoverage(const std::string &DirPath);
> +  void Init(const std::string &DirPath, std::string *FocusFunction,
> +            Random &Rand);
>    void Clear() { Traces.clear(); }
>    const Vector<uint8_t> *Get(const std::string &InputSha1) const {
>      auto It = Traces.find(InputSha1);
> @@ -49,6 +120,7 @@ class DataFlowTrace {
>   private:
>    // Input's sha1 => DFT for the FocusFunction.
>    std::unordered_map<std::string, Vector<uint8_t> > Traces;
> +  BlockCoverage Coverage;
>  };
>  }  // namespace fuzzer
>
>
> Modified: compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def (original)
> +++ compiler-rt/trunk/lib/fuzzer/FuzzerFlags.def Thu May  9 14:29:45 2019
> @@ -151,7 +151,9 @@ FUZZER_FLAG_INT(ignore_remaining_args, 0
>                  "after this one. Useful for fuzzers that need to do their
> own "
>                  "argument parsing.")
>  FUZZER_FLAG_STRING(focus_function, "Experimental. "
> -     "Fuzzing will focus on inputs that trigger calls to this function")
> +     "Fuzzing will focus on inputs that trigger calls to this function. "
> +     "If -focus_function=auto and -data_flow_trace is used, libFuzzer "
> +     "will choose the focus functions automatically.")
>
>  FUZZER_FLAG_INT(analyze_dict, 0, "Experimental")
>  FUZZER_DEPRECATED_FLAG(use_clang_coverage)
>
> Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
> +++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Thu May  9 14:29:45 2019
> @@ -157,8 +157,9 @@ Fuzzer::Fuzzer(UserCallback CB, InputCor
>    AllocateCurrentUnitData();
>    CurrentUnitSize = 0;
>    memset(BaseSha1, 0, sizeof(BaseSha1));
> -  TPC.SetFocusFunction(Options.FocusFunction);
> -  DFT.Init(Options.DataFlowTrace, Options.FocusFunction);
> +  auto FocusFunctionOrAuto = Options.FocusFunction;
> +  DFT.Init(Options.DataFlowTrace, &FocusFunctionOrAuto , MD.GetRand());
> +  TPC.SetFocusFunction(FocusFunctionOrAuto);
>  }
>
>  Fuzzer::~Fuzzer() {}
>
> Modified: compiler-rt/trunk/lib/fuzzer/tests/FuzzerUnittest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/tests/FuzzerUnittest.cpp?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/fuzzer/tests/FuzzerUnittest.cpp (original)
> +++ compiler-rt/trunk/lib/fuzzer/tests/FuzzerUnittest.cpp Thu May  9
> 14:29:45 2019
> @@ -762,6 +762,92 @@ TEST(Merge, Merge) {
>          {"B", "D"}, 3);
>  }
>
> +TEST(DFT, BlockCoverage) {
> +  BlockCoverage Cov;
> +  // Assuming C0 has 5 instrumented blocks,
> +  // C1: 7 blocks, C2: 4, C3: 9, C4 never covered, C5: 15,
> +
> +  // Add C0
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(0, 1), 0U);  // not seen this BB yet.
> +  EXPECT_EQ(Cov.GetCounter(0, 5), 0U);  // BB ID out of bounds.
> +  EXPECT_EQ(Cov.GetCounter(1, 0), 0U);  // not seen this function yet.
> +
> +  EXPECT_EQ(Cov.GetNumberOfBlocks(0), 5U);
> +  EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 1U);
> +  EXPECT_EQ(Cov.GetNumberOfBlocks(1), 0U);
> +
> +  // Various errors.
> +  EXPECT_FALSE(Cov.AppendCoverage("C0\n"));  // No total number.
> +  EXPECT_FALSE(Cov.AppendCoverage("C0 7\n"));  // No total number.
> +  EXPECT_FALSE(Cov.AppendCoverage("CZ\n"));  // Wrong function number.
> +  EXPECT_FALSE(Cov.AppendCoverage("C1 7 7"));  // BB ID is too big.
> +  EXPECT_FALSE(Cov.AppendCoverage("C1 100 7")); // BB ID is too big.
> +
> +  // Add C0 more times.
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 2U);
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 5\n"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 3U);
> +  EXPECT_EQ(Cov.GetCounter(0, 1), 1U);
> +  EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
> +  EXPECT_EQ(Cov.GetCounter(0, 3), 0U);
> +  EXPECT_EQ(Cov.GetCounter(0, 4), 0U);
> +  EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 3U);
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 1 3 4 5\n"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 4U);
> +  EXPECT_EQ(Cov.GetCounter(0, 1), 2U);
> +  EXPECT_EQ(Cov.GetCounter(0, 2), 1U);
> +  EXPECT_EQ(Cov.GetCounter(0, 3), 1U);
> +  EXPECT_EQ(Cov.GetCounter(0, 4), 1U);
> +  EXPECT_EQ(Cov.GetNumberOfCoveredBlocks(0), 5U);
> +
> +  EXPECT_TRUE(Cov.AppendCoverage("C1 7\nC2 4\nC3 9\nC5 15\nC0 5\n"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
> +  EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(3, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
> +  EXPECT_EQ(Cov.GetCounter(5, 0), 1U);
> +
> +  EXPECT_TRUE(Cov.AppendCoverage("C3 4 5 9\nC5 11 12 15"));
> +  EXPECT_EQ(Cov.GetCounter(0, 0), 5U);
> +  EXPECT_EQ(Cov.GetCounter(1, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(2, 0), 1U);
> +  EXPECT_EQ(Cov.GetCounter(3, 0), 2U);
> +  EXPECT_EQ(Cov.GetCounter(3, 4), 1U);
> +  EXPECT_EQ(Cov.GetCounter(3, 5), 1U);
> +  EXPECT_EQ(Cov.GetCounter(3, 6), 0U);
> +  EXPECT_EQ(Cov.GetCounter(4, 0), 0U);
> +  EXPECT_EQ(Cov.GetCounter(5, 0), 2U);
> +  EXPECT_EQ(Cov.GetCounter(5, 10), 0U);
> +  EXPECT_EQ(Cov.GetCounter(5, 11), 1U);
> +  EXPECT_EQ(Cov.GetCounter(5, 12), 1U);
> +}
> +
> +TEST(DFT, FunctionWeights) {
> +  BlockCoverage Cov;
> +  // unused function gets zero weight.
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 5\n"));
> +  auto Weights = Cov.FunctionWeights(2);
> +  EXPECT_GT(Weights[0], 0.);
> +  EXPECT_EQ(Weights[1], 0.);
> +
> +  // Less frequently used function gets less weight.
> +  Cov.clear();
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 5\nC1 5\nC1 5\n"));
> +  Weights = Cov.FunctionWeights(2);
> +  EXPECT_GT(Weights[0], Weights[1]);
> +
> +  // A function with more uncovered bclocks gets more weight.
> +  Cov.clear();
> +  EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n"));
> +  Weights = Cov.FunctionWeights(2);
> +  EXPECT_GT(Weights[1], Weights[0]);
> +}
> +
> +
>  TEST(Fuzzer, ForEachNonZeroByte) {
>    const size_t N = 64;
>    alignas(64) uint8_t Ar[N + 8] = {
>
> Modified: compiler-rt/trunk/test/fuzzer/OnlySomeBytesTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/OnlySomeBytesTest.cpp?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/fuzzer/OnlySomeBytesTest.cpp (original)
> +++ compiler-rt/trunk/test/fuzzer/OnlySomeBytesTest.cpp Thu May  9
> 14:29:45 2019
> @@ -24,8 +24,16 @@ __attribute__((noinline)) void bad() {
>
>  __attribute__((noinline)) void f0(IN in) {
>    uint32_t x = in[5] + 251 * in[7] + 251 * 251 * in[9];
> -  if (x == 'F' + 251 * 'U' + 251 * 251 * 'Z')
> +  if (x == 'F' + 251 * 'U' + 251 * 251 * 'Z') {
> +    // artificially inflate uncovered control in f0
> +    // so that auto-focus is more likely to chose this function.
> +    if (one == -1) {
> +      if (one == 2) one = 1;    if (one == 3) one = 1;    if (one == 4)
> one = 1;
> +      if (one == 5) one = 1;    if (one == 6) one = 1;    if (one == 7)
> one = 1;
> +      if (one == 8) one = 1;    if (one == 9) one = 1;    if (one == 0)
> one = 1;
> +    }
>      bad();
> +  }
>  }
>
>  __attribute__((noinline)) void fC(IN in) { if (in[2] == 'C') f0(in); }
>
> Modified: compiler-rt/trunk/test/fuzzer/dataflow.test
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/dataflow.test?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/fuzzer/dataflow.test (original)
> +++ compiler-rt/trunk/test/fuzzer/dataflow.test Thu May  9 14:29:45 2019
> @@ -92,11 +92,11 @@ RUN: %libfuzzer_src/scripts/collect_data
>  RUN: rm -rf %t/OUT
>  RUN: %libfuzzer_src/scripts/collect_data_flow.py %t-ThreeFunctionsTestDF
> %t/IN %t/OUT
>  RUN: %t-ThreeFunctionsTest -data_flow_trace=%t/OUT -runs=0
> -focus_function=Func2 2>&1 | FileCheck %s --check-prefix=USE_DATA_FLOW_TRACE
> -USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
>  USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: reading from {{.*}}/OUT
>  USE_DATA_FLOW_TRACE-DAG: ca8eefe2fd5d6b32028f355fafa3e739a6bf5edc =>
> |000001|
>  USE_DATA_FLOW_TRACE-DAG: d28cb407e8e1a702c72d25473f0553d3ec172262 =>
> |0000011|
>  USE_DATA_FLOW_TRACE: INFO: DataFlowTrace: 6 trace files, 3 functions, 2
> traces with focus function
> +USE_DATA_FLOW_TRACE: INFO: Focus function is set to 'Func2'
>
>  # Test that we can run collect_data_flow on a long input (>2**16 bytes)
>  RUN: rm -rf %t/OUT
>
> Modified: compiler-rt/trunk/test/fuzzer/only-some-bytes.test
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/only-some-bytes.test?rev=360378&r1=360377&r2=360378&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/test/fuzzer/only-some-bytes.test (original)
> +++ compiler-rt/trunk/test/fuzzer/only-some-bytes.test Thu May  9 14:29:45
> 2019
> @@ -31,7 +31,16 @@ RUN: %t-Fuzz -focus_function=f0 -data_fl
>  HAVE_DFT: INFO: 1/{{.*}} inputs have the Data Flow Trace
>
>  # Collect DFT, then use it.
> -RUN: rm -rf %t/C  && mkdir %t/C &&  cp %t/IN/* %t/C
> +RUN: rm -rf %t/C %t/C1  && mkdir %t/C %t/C1 &&  cp %t/IN/* %t/C
>  RUN: rm -rf %t/C_DFT && %libfuzzer_src/scripts/collect_data_flow.py
> %t-DFT %t/C %t/C_DFT > /dev/null 2>&1
> -RUN: not %t-Fuzz -focus_function=f0 -data_flow_trace=%t/C_DFT -seed=1
> -runs=1000000 -use_value_profile=1 %t/C 2> %t/log
> +RUN: not %t-Fuzz -focus_function=f0 -data_flow_trace=%t/C_DFT -seed=1
> -runs=1000000 -use_value_profile=1 %t/C1 %t/C 2> %t/log
> +RUN: grep BINGO %t/log
> +
> +# Test -focus_function=auto: run 50 times and verify that 'f0' is the
> most frequent focus function.
> +RUN: %t-Fuzz -focus_function=auto -data_flow_trace=%t/C_DFT -runs=0 %t/C
> -jobs=50 2>&1 | grep AUTOFOCUS  | sort | uniq -c | sort -g -r | head -n 1 |
> FileCheck %s --check-prefix=AUTOFOCUS
> +AUTOFOCUS: INFO: AUTOFOCUS: {{.*}} f0
> +
> +# Actually execute 50 fuzzing processes with a small number of runs, to
> test  -focus_function=auto for real.
> +# We can not test data_flow_trace=auto in just a single run, because it
> may choose to focus on a wrong function.
> +RUN: not %t-Fuzz -focus_function=auto -data_flow_trace=%t/C_DFT %t/C
> -jobs=50 -runs=200000 -use_value_profile=1 2> %t/log
>  RUN: grep BINGO %t/log
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190528/88180328/attachment.html>


More information about the llvm-commits mailing list