OSDN Git Service

[libFuzzer] extend -print_coverage to print the comma-separated list of covered dirs...
authorKostya Serebryany <kcc@google.com>
Wed, 30 Nov 2016 21:53:32 +0000 (21:53 +0000)
committerKostya Serebryany <kcc@google.com>
Wed, 30 Nov 2016 21:53:32 +0000 (21:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288276 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Fuzzer/FuzzerIO.h
lib/Fuzzer/FuzzerIOPosix.cpp
lib/Fuzzer/FuzzerIOWindows.cpp
lib/Fuzzer/FuzzerTracePC.cpp
lib/Fuzzer/test/coverage.test

index b1ac69c..39634f9 100644 (file)
@@ -33,6 +33,9 @@ void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
 std::string DirPlusFile(const std::string &DirPath,
                         const std::string &FileName);
 
+// Returns the name of the dir, similar to the 'dirname' utility.
+std::string DirName(const std::string &FileName);
+
 void DupAndCloseStderr();
 
 void CloseStdout();
index 740d52d..a4290fa 100644 (file)
@@ -18,8 +18,9 @@
 #include <dirent.h>
 #include <fstream>
 #include <iterator>
-#include <sys/types.h>
+#include <libgen.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 namespace fuzzer {
@@ -74,5 +75,13 @@ void DeleteFile(const std::string &Path) {
   unlink(Path.c_str());
 }
 
+std::string DirName(const std::string &FileName) {
+  char *Tmp = new char[FileName.size() + 1];
+  memcpy(Tmp, FileName.c_str(), FileName.size() + 1);
+  std::string Res = dirname(Tmp);
+  delete [] Tmp;
+  return Res;
+}
+
 }  // namespace fuzzer
 #endif // LIBFUZZER_POSIX
index f19353c..aaa2e34 100644 (file)
@@ -139,5 +139,9 @@ void DeleteFile(const std::string &Path) {
   _unlink(Path.c_str());
 }
 
+std::string DirName(const std::string &FileName) {
+  assert(0 && "Unimplemented");
+}
+
 }  // namespace fuzzer
 #endif // LIBFUZZER_WINDOWS
index eabf0d0..8d58a6d 100644 (file)
@@ -131,7 +131,8 @@ void TracePC::PrintCoverage() {
   }
   std::map<std::string, std::vector<uintptr_t>> CoveredPCsPerModule;
   std::map<std::string, uintptr_t> ModuleOffsets;
-  std::set<std::string> CoveredFiles, CoveredFunctions, CoveredLines;
+  std::set<std::string> CoveredDirs, CoveredFiles, CoveredFunctions,
+      CoveredLines;
   Printf("COVERAGE:\n");
   for (size_t i = 1; i < GetNumPCs(); i++) {
     if (!PCs[i]) continue;
@@ -150,12 +151,21 @@ void TracePC::PrintCoverage() {
     CoveredPCsPerModule[Module].push_back(PcOffset);
     CoveredFunctions.insert(FunctionStr);
     CoveredFiles.insert(FileStr);
+    CoveredDirs.insert(DirName(FileStr));
     if (!CoveredLines.insert(FileStr + ":" + LineStr).second)
       continue;
     Printf("COVERED: %s %s:%s\n", FunctionStr.c_str(),
            FileStr.c_str(), LineStr.c_str());
   }
 
+  std::string CoveredDirsStr;
+  for (auto &Dir : CoveredDirs) {
+    if (!CoveredDirsStr.empty())
+      CoveredDirsStr += ",";
+    CoveredDirsStr += Dir;
+  }
+  Printf("COVERED_DIRS: %s\n", CoveredDirsStr.c_str());
+
   for (auto &M : CoveredPCsPerModule) {
     std::set<std::string> UncoveredFiles, UncoveredFunctions;
     std::map<std::string, std::set<int> > UncoveredLines;  // Func+File => lines
index b41a262..a5420bb 100644 (file)
@@ -3,6 +3,7 @@ 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-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:19
+CHECK: COVERED_DIRS: {{.*}}lib/Fuzzer/test
 RUN: not LLVMFuzzer-NullDerefTest-TracePC -print_coverage=1 2>&1 | FileCheck %s
 
 RUN: LLVMFuzzer-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO