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