[libFuzzer] in autofocus mode, give more weight to functions with DFT

llvm-svn: 363473
This commit is contained in:
Kostya Serebryany 2019-06-14 23:29:56 +00:00
parent 9967a6c60a
commit 0feed5d585
3 changed files with 21 additions and 5 deletions

View File

@ -42,11 +42,16 @@ bool BlockCoverage::AppendCoverage(const std::string &S) {
bool BlockCoverage::AppendCoverage(std::istream &IN) { bool BlockCoverage::AppendCoverage(std::istream &IN) {
std::string L; std::string L;
while (std::getline(IN, L, '\n')) { while (std::getline(IN, L, '\n')) {
if (L.empty() || L[0] != 'C') if (L.empty())
continue; // Ignore non-coverage lines. continue;
std::stringstream SS(L.c_str() + 1); std::stringstream SS(L.c_str() + 1);
size_t FunctionId = 0; size_t FunctionId = 0;
SS >> FunctionId; SS >> FunctionId;
if (L[0] == 'F') {
FunctionsWithDFT.insert(FunctionId);
continue;
}
if (L[0] != 'C') continue;
Vector<uint32_t> CoveredBlocks; Vector<uint32_t> CoveredBlocks;
while (true) { while (true) {
uint32_t BB = 0; uint32_t BB = 0;
@ -87,9 +92,12 @@ Vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
auto Counters = It.second; auto Counters = It.second;
assert(FunctionID < NumFunctions); assert(FunctionID < NumFunctions);
auto &Weight = Res[FunctionID]; auto &Weight = Res[FunctionID];
Weight = 1000.; // this function is covered. // Give higher weight if the function has a DFT.
Weight = FunctionsWithDFT.count(FunctionID) ? 1000. : 1;
// Give higher weight to functions with less frequently seen basic blocks.
Weight /= SmallestNonZeroCounter(Counters); Weight /= SmallestNonZeroCounter(Counters);
Weight *= NumberOfUncoveredBlocks(Counters) + 1; // make sure it's not 0. // Give higher weight to functions with the most uncovered basic blocks.
Weight *= NumberOfUncoveredBlocks(Counters) + 1;
} }
return Res; return Res;
} }

View File

@ -107,6 +107,8 @@ class BlockCoverage {
// Function ID => vector of counters. // Function ID => vector of counters.
// Each counter represents how many input files trigger the given basic block. // Each counter represents how many input files trigger the given basic block.
std::unordered_map<size_t, CoverageVector> Functions; std::unordered_map<size_t, CoverageVector> Functions;
// Functions that have DFT entry.
std::unordered_set<size_t> FunctionsWithDFT;
}; };
class DataFlowTrace { class DataFlowTrace {

View File

@ -840,11 +840,17 @@ TEST(DFT, FunctionWeights) {
Weights = Cov.FunctionWeights(2); Weights = Cov.FunctionWeights(2);
EXPECT_GT(Weights[0], Weights[1]); EXPECT_GT(Weights[0], Weights[1]);
// A function with more uncovered bclocks gets more weight. // A function with more uncovered blocks gets more weight.
Cov.clear(); Cov.clear();
EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n")); EXPECT_TRUE(Cov.AppendCoverage("C0 1 2 3 5\nC1 2 4\n"));
Weights = Cov.FunctionWeights(2); Weights = Cov.FunctionWeights(2);
EXPECT_GT(Weights[1], Weights[0]); EXPECT_GT(Weights[1], Weights[0]);
// A function with DFT gets more weight than the function w/o DFT.
Cov.clear();
EXPECT_TRUE(Cov.AppendCoverage("F1 111\nC0 3\nC1 1 2 3\n"));
Weights = Cov.FunctionWeights(2);
EXPECT_GT(Weights[1], Weights[0]);
} }