[compiler-rt] r258999 - [sanitizers] generating html report on coverage dump

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 27 15:51:36 PST 2016


Author: aizatsky
Date: Wed Jan 27 17:51:36 2016
New Revision: 258999

URL: http://llvm.org/viewvc/llvm-project?rev=258999&view=rev
Log:
[sanitizers] generating html report on coverage dump

Subscribers: tberghammer, danalbert, srhines

Differential Revision: http://reviews.llvm.org/D16374

Added:
    compiler-rt/trunk/test/asan/TestCases/Posix/coverage_html_report.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
    compiler-rt/trunk/test/CMakeLists.txt
    compiler-rt/trunk/test/asan/lit.cfg
    compiler-rt/trunk/test/lit.common.cfg

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Wed Jan 27 17:51:36 2016
@@ -291,6 +291,9 @@ pid_t StartSubprocess(const char *filena
                       fd_t stderr_fd = kInvalidFd);
 // Checks if specified process is still running
 bool IsProcessRunning(pid_t pid);
+// Waits for the process to finish and returns its exit code.
+// Returns -1 in case of an error.
+int WaitForProcess(pid_t pid);
 
 u32 GetUid();
 void ReExec();

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Wed Jan 27 17:51:36 2016
@@ -783,12 +783,43 @@ void CoverageData::GetRangeOffsets(const
     (*offsets)[i] = UnbundlePc((*offsets)[i]);
 }
 
+static void GenerateHtmlReport(const InternalMmapVector<char *> &sancov_argv) {
+  if (!common_flags()->html_cov_report || sancov_argv[0] == nullptr) {
+    return;
+  }
+
+  InternalScopedString report_path(kMaxPathLength);
+  fd_t report_fd =
+      CovOpenFile(&report_path, false /* packed */, GetProcessName(), "html");
+  int pid = StartSubprocess(sancov_argv[0], sancov_argv.data(),
+                            kInvalidFd /* stdin */, report_fd /* std_out */);
+  if (pid > 0) {
+    int result = WaitForProcess(pid);
+    if (result == 0) {
+      VReport(1, " CovDump: html report generated to %s (%d)\n",
+              report_path.data(), result);
+    }
+  }
+}
+
 void CoverageData::DumpOffsets() {
   auto sym = Symbolizer::GetOrInit();
   if (!common_flags()->coverage_pcs) return;
   CHECK_NE(sym, nullptr);
   InternalMmapVector<uptr> offsets(0);
   InternalScopedString path(kMaxPathLength);
+
+  InternalMmapVector<char *> sancov_argv(module_name_vec.size() + 2);
+  sancov_argv.push_back(FindPathToBinary(common_flags()->sancov_path));
+  sancov_argv.push_back(internal_strdup("-obj"));
+  sancov_argv.push_back(internal_strdup(GetArgv()[0]));
+  sancov_argv.push_back(internal_strdup("-html-report"));
+  auto argv_deleter = at_scope_exit([&] {
+    for (uptr i = 0; i < sancov_argv.size(); ++i) {
+      InternalFree(sancov_argv[i]);
+    }
+  });
+
   for (uptr m = 0; m < module_name_vec.size(); m++) {
     auto r = module_name_vec[m];
     GetRangeOffsets(r, sym, &offsets);
@@ -813,11 +844,15 @@ void CoverageData::DumpOffsets() {
       if (fd == kInvalidFd) continue;
       WriteToFile(fd, offsets.data(), offsets.size() * sizeof(offsets[0]));
       CloseFile(fd);
+      sancov_argv.push_back(internal_strdup(path.data()));
       VReport(1, " CovDump: %s: %zd PCs written\n", path.data(), num_offsets);
     }
   }
   if (cov_fd != kInvalidFd)
     CloseFile(cov_fd);
+
+  sancov_argv.push_back(nullptr);
+  GenerateHtmlReport(sancov_argv);
 }
 
 void CoverageData::DumpAll() {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Wed Jan 27 17:51:36 2016
@@ -202,3 +202,5 @@ COMMON_FLAG(bool, suppress_equal_pcs, tr
             "halt_on_error=false mode (asan only).")
 COMMON_FLAG(bool, print_cmdline, false, "Print command line on crash "
             "(asan only).")
+COMMON_FLAG(bool, html_cov_report, false, "Generate html coverage report.")
+COMMON_FLAG(const char *, sancov_path, "sancov", "Sancov tool location.")

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix_libcdep.cc Wed Jan 27 17:51:36 2016
@@ -383,6 +383,17 @@ bool IsProcessRunning(pid_t pid) {
   return waitpid_status == 0;
 }
 
+int WaitForProcess(pid_t pid) {
+  int process_status;
+  uptr waitpid_status = internal_waitpid(pid, &process_status, 0);
+  int local_errno;
+  if (internal_iserror(waitpid_status, &local_errno)) {
+    VReport(1, "Waiting on the process failed (errno %d).\n", local_errno);
+    return -1;
+  }
+  return process_status;
+}
+
 } // namespace __sanitizer
 
 #endif // SANITIZER_POSIX

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Wed Jan 27 17:51:36 2016
@@ -789,6 +789,8 @@ bool IsProcessRunning(pid_t pid) {
   return false;
 }
 
+int WaitForProcess(pid_t pid) { return -1; }
+
 }  // namespace __sanitizer
 
 #endif  // _WIN32

Modified: compiler-rt/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/CMakeLists.txt?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/test/CMakeLists.txt (original)
+++ compiler-rt/trunk/test/CMakeLists.txt Wed Jan 27 17:51:36 2016
@@ -20,7 +20,7 @@ if(NOT ANDROID)
     # Use LLVM utils and Clang from the same build tree.
     list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS
       clang clang-headers FileCheck count not llvm-config llvm-nm llvm-objdump
-      llvm-symbolizer compiler-rt-headers)
+      llvm-symbolizer compiler-rt-headers sancov)
     if (COMPILER_RT_HAS_PROFILE)
       list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile)
     endif()

Added: compiler-rt/trunk/test/asan/TestCases/Posix/coverage_html_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/coverage_html_report.cc?rev=258999&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/coverage_html_report.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/coverage_html_report.cc Wed Jan 27 17:51:36 2016
@@ -0,0 +1,24 @@
+// REQUIRES: has_sancovcc
+// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t
+// RUN: rm -rf %T/coverage_html_report
+// RUN: mkdir -p %T/coverage_html_report
+// RUN: cd %T/coverage_html_report
+// RUN: %env_asan_opts=coverage=1:verbosity=1:html_cov_report=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main
+// RUN: ls *.html | FileCheck %s --check-prefix=CHECK-ls
+// RUN: rm -r %T/coverage_html_report
+
+#include <stdio.h>
+#include <unistd.h>
+
+void bar() { printf("bar\n"); }
+
+int main(int argc, char **argv) {
+  fprintf(stderr, "PID: %d\n", getpid());
+  bar();
+  return 0;
+}
+
+// CHECK-main: PID: [[PID:[0-9]+]]
+// CHECK-main: [[PID]].sancov: 2 PCs written
+// CHECK-main: html report generated to ./coverage_html_report.cc.tmp.[[PID]].html
+// CHECK-ls: coverage_html_report.cc.tmp.{{[0-9]+}}.html

Modified: compiler-rt/trunk/test/asan/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/lit.cfg?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/lit.cfg (original)
+++ compiler-rt/trunk/test/asan/lit.cfg Wed Jan 27 17:51:36 2016
@@ -138,7 +138,7 @@ sancov = os.path.join(sanitizer_common_s
 if not os.path.exists(sancov):
   lit_config.fatal("Can't find script on path %r" % sancov)
 python_exec = get_required_attr(config, "python_executable")
-config.substitutions.append( ("%sancov", python_exec + " " + sancov + " ") )
+config.substitutions.append( ("%sancov ", python_exec + " " + sancov + " ") )
 
 # Determine kernel bitness
 if config.host_arch.find('64') != -1 and config.android != "1":

Modified: compiler-rt/trunk/test/lit.common.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lit.common.cfg?rev=258999&r1=258998&r2=258999&view=diff
==============================================================================
--- compiler-rt/trunk/test/lit.common.cfg (original)
+++ compiler-rt/trunk/test/lit.common.cfg Wed Jan 27 17:51:36 2016
@@ -115,6 +115,11 @@ if config.can_symbolize:
 
 lit.util.usePlatformSdkOnDarwin(config, lit_config)
 
+sancovcc_path = os.path.join(llvm_tools_dir, "sancov") 
+if os.path.exists(sancovcc_path):
+  config.available_features.add("has_sancovcc")
+  config.substitutions.append( ("%sancovcc ", sancovcc_path) )
+
 def is_darwin_lto_supported():
   return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib'))
 




More information about the llvm-commits mailing list