summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2018-07-19 22:00:48 +0000
committerKostya Serebryany <kcc@google.com>2018-07-19 22:00:48 +0000
commitc78bd23b8c7d61cd53fdd1d47a964d158ab7a09d (patch)
tree8801a1444eff5bbf7497075d0fd5487c3ae292a5
parentfe6fc19e8a5c8c3628c92ab7bb31c198b112c760 (diff)
[libFuzzer] when -print_coverage=1 is given, print more stats (the number of seeds that hit every given function)
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@337501 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/fuzzer/FuzzerTracePC.cpp29
-rw-r--r--lib/fuzzer/FuzzerTracePC.h3
-rw-r--r--test/fuzzer/OnlySomeBytesTest.cpp5
-rw-r--r--test/fuzzer/coverage.test2
4 files changed, 23 insertions, 16 deletions
diff --git a/lib/fuzzer/FuzzerTracePC.cpp b/lib/fuzzer/FuzzerTracePC.cpp
index 0385b36be..983b47411 100644
--- a/lib/fuzzer/FuzzerTracePC.cpp
+++ b/lib/fuzzer/FuzzerTracePC.cpp
@@ -184,7 +184,7 @@ void TracePC::UpdateObservedPCs() {
auto Observe = [&](const PCTableEntry &TE) {
if (TE.PCFlags & 1)
- if (ObservedFuncs.insert(TE.PC).second && NumPrintNewFuncs)
+ if (++ObservedFuncs[TE.PC] == 1 && NumPrintNewFuncs)
CoveredFuncs.push_back(TE.PC);
ObservePC(TE.PC);
};
@@ -209,7 +209,8 @@ void TracePC::UpdateObservedPCs() {
}
}
- for (size_t i = 0, N = Min(CoveredFuncs.size(), NumPrintNewFuncs); i < N; i++) {
+ for (size_t i = 0, N = Min(CoveredFuncs.size(), NumPrintNewFuncs); i < N;
+ i++) {
Printf("\tNEW_FUNC[%zd/%zd]: ", i + 1, CoveredFuncs.size());
PrintPC("%p %F %L", "%p", CoveredFuncs[i] + 1);
Printf("\n");
@@ -251,7 +252,7 @@ void TracePC::IterateCoveredFunctions(CallBack CB) {
NextFE++;
} while (NextFE < M.Stop && !(NextFE->PCFlags & 1));
if (ObservedFuncs.count(FE->PC))
- CB(FE, NextFE);
+ CB(FE, NextFE, ObservedFuncs[FE->PC]);
}
}
}
@@ -298,28 +299,30 @@ void TracePC::PrintCoverage() {
return;
}
Printf("COVERAGE:\n");
- auto CoveredFunctionCallback = [&](const PCTableEntry *First, const PCTableEntry *Last) {
+ auto CoveredFunctionCallback = [&](const PCTableEntry *First,
+ const PCTableEntry *Last,
+ uintptr_t Counter) {
assert(First < Last);
auto VisualizePC = GetNextInstructionPc(First->PC);
std::string FileStr = DescribePC("%s", VisualizePC);
- if (!IsInterestingCoverageFile(FileStr)) return;
+ if (!IsInterestingCoverageFile(FileStr))
+ return;
std::string FunctionStr = DescribePC("%F", VisualizePC);
+ if (FunctionStr.find("in ") == 0)
+ FunctionStr = FunctionStr.substr(3);
std::string LineStr = DescribePC("%l", VisualizePC);
size_t Line = std::stoul(LineStr);
+ size_t NumEdges = Last - First;
Vector<uintptr_t> UncoveredPCs;
for (auto TE = First; TE < Last; TE++)
if (!ObservedPCs.count(TE->PC))
UncoveredPCs.push_back(TE->PC);
- Printf("COVERED_FUNC: ");
- UncoveredPCs.empty()
- ? Printf("all")
- : Printf("%zd/%zd", (Last - First) - UncoveredPCs.size(), Last - First);
- Printf(" PCs covered %s %s:%zd\n", FunctionStr.c_str(), FileStr.c_str(),
- Line);
- for (auto PC: UncoveredPCs) {
+ Printf("COVERED_FUNC: hits: %zd", Counter);
+ Printf(" edges: %zd/%zd", NumEdges - UncoveredPCs.size(), NumEdges);
+ Printf(" %s %s:%zd\n", FunctionStr.c_str(), FileStr.c_str(), Line);
+ for (auto PC: UncoveredPCs)
Printf(" UNCOVERED_PC: %s\n",
DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
- }
};
IterateCoveredFunctions(CoveredFunctionCallback);
diff --git a/lib/fuzzer/FuzzerTracePC.h b/lib/fuzzer/FuzzerTracePC.h
index d9a427cbe..b37989dbd 100644
--- a/lib/fuzzer/FuzzerTracePC.h
+++ b/lib/fuzzer/FuzzerTracePC.h
@@ -17,6 +17,7 @@
#include "FuzzerValueBitMap.h"
#include <set>
+#include <unordered_map>
namespace fuzzer {
@@ -176,7 +177,7 @@ private:
uintptr_t *PCs() const;
Set<uintptr_t> ObservedPCs;
- Set<uintptr_t> ObservedFuncs;
+ std::unordered_map<uintptr_t, uintptr_t> ObservedFuncs; // PC => Counter.
template <class Callback>
void IterateInline8bitCounters(Callback CB) const;
diff --git a/test/fuzzer/OnlySomeBytesTest.cpp b/test/fuzzer/OnlySomeBytesTest.cpp
index 3873b710b..076cda063 100644
--- a/test/fuzzer/OnlySomeBytesTest.cpp
+++ b/test/fuzzer/OnlySomeBytesTest.cpp
@@ -12,10 +12,13 @@
const size_t N = 2048;
typedef const uint8_t *IN;
+static volatile int one = 1;
+
extern "C" {
__attribute__((noinline)) void bad() {
fprintf(stderr, "BINGO\n");
- abort();
+ if (one)
+ abort();
}
__attribute__((noinline)) void f0(IN in) {
diff --git a/test/fuzzer/coverage.test b/test/fuzzer/coverage.test
index 83a4b12cb..3b2341f21 100644
--- a/test/fuzzer/coverage.test
+++ b/test/fuzzer/coverage.test
@@ -5,7 +5,7 @@ RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC %ld_f
RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t-DSOTest
CHECK: COVERAGE:
-CHECK: COVERED_FUNC: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
+CHECK: COVERED_FUNC: {{.*}}LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
RUN: not %run %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
RUN: %run %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO