[compiler-rt] r332073 - [libFuzzer] refactor the implementation of -print_coverage

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Thu May 10 18:17:52 PDT 2018


Author: kcc
Date: Thu May 10 18:17:52 2018
New Revision: 332073

URL: http://llvm.org/viewvc/llvm-project?rev=332073&view=rev
Log:
[libFuzzer] refactor the implementation of -print_coverage

Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h
    compiler-rt/trunk/test/fuzzer/coverage.test

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp?rev=332073&r1=332072&r2=332073&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.cpp Thu May 10 18:17:52 2018
@@ -211,6 +211,24 @@ static std::string GetModuleName(uintptr
   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() {
   if (!EF->__sanitizer_symbolize_pc ||
       !EF->__sanitizer_get_module_and_offset_for_pc) {
@@ -220,53 +238,31 @@ void TracePC::PrintCoverage() {
     return;
   }
   Printf("COVERAGE:\n");
-  std::string LastFunctionName = "";
-  std::string LastFileStr = "";
-  Set<size_t> UncoveredLines;
-  Set<size_t> CoveredLines;
-
-  auto FunctionEndCallback = [&](const std::string &CurrentFunc,
-                                 const std::string &CurrentFile) {
-    if (LastFunctionName != CurrentFunc) {
-      if (CoveredLines.empty() && !UncoveredLines.empty()) {
-        Printf("UNCOVERED_FUNC: %s\n", LastFunctionName.c_str());
-      } else {
-        for (auto Line : UncoveredLines) {
-          if (!CoveredLines.count(Line))
-            Printf("UNCOVERED_LINE: %s %s:%zd\n", LastFunctionName.c_str(),
-                   LastFileStr.c_str(), Line);
-        }
-      }
-
-      UncoveredLines.clear();
-      CoveredLines.clear();
-      LastFunctionName = CurrentFunc;
-      LastFileStr = CurrentFile;
+  auto CoveredFunctionCallback = [&](const PCTableEntry *First, const PCTableEntry *Last) {
+    assert(First < Last);
+    auto VisualizePC = GetNextInstructionPc(First->PC);
+    std::string FileStr = DescribePC("%s", VisualizePC);
+    if (!IsInterestingCoverageFile(FileStr)) return;
+    std::string FunctionStr = DescribePC("%F", VisualizePC);
+    std::string LineStr = DescribePC("%l", VisualizePC);
+    size_t Line = std::stoul(LineStr);
+    std::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("  UNCOVERED_PC: %s\n",
+             DescribePC("%s:%l", GetNextInstructionPc(PC)).c_str());
     }
   };
 
-  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 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("", "");
+  IterateCoveredFunctions(CoveredFunctionCallback);
 }
 
 // Value profile.

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h?rev=332073&r1=332072&r2=332073&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerTracePC.h Thu May 10 18:17:52 2018
@@ -103,6 +103,9 @@ class TracePC {
 
   void PrintCoverage();
 
+  template<class CallBack>
+  void IterateCoveredFunctions(CallBack CB);
+
   void AddValueForMemcmp(void *caller_pc, const void *s1, const void *s2,
                          size_t n, bool StopAtZero);
 

Modified: compiler-rt/trunk/test/fuzzer/coverage.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/coverage.test?rev=332073&r1=332072&r2=332073&view=diff
==============================================================================
--- compiler-rt/trunk/test/fuzzer/coverage.test (original)
+++ compiler-rt/trunk/test/fuzzer/coverage.test Thu May 10 18:17:52 2018
@@ -4,18 +4,14 @@ RUN: %cpp_compiler -mllvm -use-unknown-l
 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-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
-CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
-CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16
+CHECK: COVERED_FUNC: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
 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
 DSO: COVERAGE:
-DSO-DAG: COVERED:{{.*}}DSO1{{.*}}DSO1.cpp
-DSO-DAG: COVERED:{{.*}}DSO2{{.*}}DSO2.cpp
-DSO-DAG: COVERED:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
-DSO-DAG: UNCOVERED_LINE:{{.*}}DSO1{{.*}}DSO1.cpp
-DSO-DAG: UNCOVERED_LINE:{{.*}}DSO2{{.*}}DSO2.cpp
-DSO-DAG: UNCOVERED_FUNC: in Uncovered1
-DSO-DAG: UNCOVERED_FUNC: in Uncovered2
-DSO-DAG: UNCOVERED_LINE: in LLVMFuzzerTestOneInput
+DSO-DAG: COVERED_FUNC:{{.*}}DSO1{{.*}}DSO1.cpp
+DSO-DAG: COVERED_FUNC:{{.*}}DSO2{{.*}}DSO2.cpp
+DSO-DAG: COVERED_FUNC:{{.*}}LLVMFuzzerTestOneInput{{.*}}DSOTestMain
+DSO-DAG: UNCOVERED_PC:{{.*}}DSO1.cpp
+DSO-DAG: UNCOVERED_PC:{{.*}}DSO2.cpp
+DSO-DAG: UNCOVERED_PC:{{.*}}DSOTestMain




More information about the llvm-commits mailing list