[libFuzzer] refactor the implementation of -print_coverage
llvm-svn: 332073
This commit is contained in:
parent
a2759327fd
commit
6a6e690d24
|
@ -211,6 +211,24 @@ static std::string GetModuleName(uintptr_t PC) {
|
||||||
return ModulePathRaw;
|
return ModulePathRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class CallBack>
|
||||||
|
void TracePC::IterateCoveredFunctions(CallBack CB) {
|
||||||
|
for (size_t i = 0; i < NumPCTables; i++) {
|
||||||
|
auto &M = ModulePCTable[i];
|
||||||
|
assert(M.Start < M.Stop);
|
||||||
|
auto ModuleName = GetModuleName(M.Start->PC);
|
||||||
|
for (auto NextFE = M.Start; NextFE < M.Stop; ) {
|
||||||
|
auto FE = NextFE;
|
||||||
|
assert((FE->PCFlags & 1) && "Not a function entry point");
|
||||||
|
do {
|
||||||
|
NextFE++;
|
||||||
|
} while (NextFE < M.Stop && !(NextFE->PCFlags & 1));
|
||||||
|
if (ObservedFuncs.count(FE->PC))
|
||||||
|
CB(FE, NextFE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TracePC::PrintCoverage() {
|
void TracePC::PrintCoverage() {
|
||||||
if (!EF->__sanitizer_symbolize_pc ||
|
if (!EF->__sanitizer_symbolize_pc ||
|
||||||
!EF->__sanitizer_get_module_and_offset_for_pc) {
|
!EF->__sanitizer_get_module_and_offset_for_pc) {
|
||||||
|
@ -220,53 +238,31 @@ void TracePC::PrintCoverage() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Printf("COVERAGE:\n");
|
Printf("COVERAGE:\n");
|
||||||
std::string LastFunctionName = "";
|
auto CoveredFunctionCallback = [&](const PCTableEntry *First, const PCTableEntry *Last) {
|
||||||
std::string LastFileStr = "";
|
assert(First < Last);
|
||||||
Set<size_t> UncoveredLines;
|
auto VisualizePC = GetNextInstructionPc(First->PC);
|
||||||
Set<size_t> CoveredLines;
|
std::string FileStr = DescribePC("%s", VisualizePC);
|
||||||
|
if (!IsInterestingCoverageFile(FileStr)) return;
|
||||||
auto FunctionEndCallback = [&](const std::string &CurrentFunc,
|
std::string FunctionStr = DescribePC("%F", VisualizePC);
|
||||||
const std::string &CurrentFile) {
|
std::string LineStr = DescribePC("%l", VisualizePC);
|
||||||
if (LastFunctionName != CurrentFunc) {
|
size_t Line = std::stoul(LineStr);
|
||||||
if (CoveredLines.empty() && !UncoveredLines.empty()) {
|
std::vector<uintptr_t> UncoveredPCs;
|
||||||
Printf("UNCOVERED_FUNC: %s\n", LastFunctionName.c_str());
|
for (auto TE = First; TE < Last; TE++)
|
||||||
} else {
|
if (!ObservedPCs.count(TE->PC))
|
||||||
for (auto Line : UncoveredLines) {
|
UncoveredPCs.push_back(TE->PC);
|
||||||
if (!CoveredLines.count(Line))
|
Printf("COVERED_FUNC: ");
|
||||||
Printf("UNCOVERED_LINE: %s %s:%zd\n", LastFunctionName.c_str(),
|
UncoveredPCs.empty()
|
||||||
LastFileStr.c_str(), Line);
|
? 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);
|
||||||
UncoveredLines.clear();
|
for (auto PC: UncoveredPCs) {
|
||||||
CoveredLines.clear();
|
Printf(" UNCOVERED_PC: %s\n",
|
||||||
LastFunctionName = CurrentFunc;
|
DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
|
||||||
LastFileStr = CurrentFile;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < NumPCTables; i++) {
|
IterateCoveredFunctions(CoveredFunctionCallback);
|
||||||
auto &M = ModulePCTable[i];
|
|
||||||
assert(M.Start < M.Stop);
|
|
||||||
auto ModuleName = GetModuleName(M.Start->PC);
|
|
||||||
for (auto Ptr = M.Start; Ptr < M.Stop; Ptr++) {
|
|
||||||
auto PC = Ptr->PC;
|
|
||||||
auto VisualizePC = GetNextInstructionPc(PC);
|
|
||||||
bool IsObserved = ObservedPCs.count(PC);
|
|
||||||
std::string FileStr = DescribePC("%s", VisualizePC);
|
|
||||||
if (!IsInterestingCoverageFile(FileStr)) continue;
|
|
||||||
std::string FunctionStr = DescribePC("%F", VisualizePC);
|
|
||||||
FunctionEndCallback(FunctionStr, FileStr);
|
|
||||||
std::string LineStr = DescribePC("%l", VisualizePC);
|
|
||||||
size_t Line = std::stoul(LineStr);
|
|
||||||
if (IsObserved && CoveredLines.insert(Line).second)
|
|
||||||
Printf("COVERED: %s %s:%zd\n", FunctionStr.c_str(), FileStr.c_str(),
|
|
||||||
Line);
|
|
||||||
else
|
|
||||||
UncoveredLines.insert(Line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FunctionEndCallback("", "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value profile.
|
// Value profile.
|
||||||
|
|
|
@ -103,6 +103,9 @@ class TracePC {
|
||||||
|
|
||||||
void PrintCoverage();
|
void PrintCoverage();
|
||||||
|
|
||||||
|
template<class CallBack>
|
||||||
|
void IterateCoveredFunctions(CallBack CB);
|
||||||
|
|
||||||
void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
|
void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
|
||||||
size_t n, bool StopAtZero);
|
size_t n, bool StopAtZero);
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,14 @@ RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSO2.cpp -fPIC -shar
|
||||||
RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
|
RUN: %cpp_compiler -mllvm -use-unknown-locations=Disable %S/DSOTestMain.cpp %S/DSOTestExtra.cpp -L. %t-DSO1.so %t-DSO2.so -o %t-DSOTest
|
||||||
|
|
||||||
CHECK: COVERAGE:
|
CHECK: COVERAGE:
|
||||||
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
|
CHECK: COVERED_FUNC: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
|
||||||
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
|
|
||||||
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16
|
|
||||||
RUN: not %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
|
RUN: not %t-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
|
||||||
|
|
||||||
RUN: %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
|
RUN: %t-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
|
||||||
DSO: COVERAGE:
|
DSO: COVERAGE:
|
||||||
DSO-DAG: COVERED:{{.*}}DSO1{{.*}}DSO1.cpp
|
DSO-DAG: COVERED_FUNC:{{.*}}DSO1{{.*}}DSO1.cpp
|
||||||
DSO-DAG: COVERED:{{.*}}DSO2{{.*}}DSO2.cpp
|
DSO-DAG: COVERED_FUNC:{{.*}}DSO2{{.*}}DSO2.cpp
|
||||||
DSO-DAG: COVERED:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
|
DSO-DAG: COVERED_FUNC:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
|
||||||
DSO-DAG: UNCOVERED_LINE:{{.*}}DSO1{{.*}}DSO1.cpp
|
DSO-DAG: UNCOVERED_PC:{{.*}}DSO1.cpp
|
||||||
DSO-DAG: UNCOVERED_LINE:{{.*}}DSO2{{.*}}DSO2.cpp
|
DSO-DAG: UNCOVERED_PC:{{.*}}DSO2.cpp
|
||||||
DSO-DAG: UNCOVERED_FUNC: in Uncovered1
|
DSO-DAG: UNCOVERED_PC:{{.*}}DSOTestMain
|
||||||
DSO-DAG: UNCOVERED_FUNC: in Uncovered2
|
|
||||||
DSO-DAG: UNCOVERED_LINE: in LLVMFuzzerTestOneInput
|
|
||||||
|
|
Loading…
Reference in New Issue