[compiler-rt] r209121 - [sanitizer] Support sandboxing in sanitizer coverage.

Sergey Matveev earthdok at google.com
Mon May 19 05:53:04 PDT 2014


Author: smatveev
Date: Mon May 19 07:53:03 2014
New Revision: 209121

URL: http://llvm.org/viewvc/llvm-project?rev=209121&view=rev
Log:
[sanitizer] Support sandboxing in sanitizer coverage.

Summary:
Sandboxed code may now pass additional arguments to
__sanitizer_sandbox_on_notify() to force all coverage data to be dumped to a
single file (the default is one file per module). The user may supply a file or
socket to write to. The latter option can be used to broker out the file writing
functionality. If -1  is passed, we pre-open a file.

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/coverage-sandboxing.cc
Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
    compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py
    compiler-rt/trunk/test/asan/lit.cfg

Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Mon May 19 07:53:03 2014
@@ -24,13 +24,28 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+  // Arguments for __sanitizer_sandbox_on_notify() below.
+  typedef struct {
+    // Enable sandbox support in sanitizer coverage.
+    int coverage_sandboxed;
+    // File descriptor to write coverage data to. If -1 is passed, a file will
+    // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
+    // effect if coverage_sandboxed == 0.
+    intptr_t coverage_fd;
+    // If non-zero, split the coverage data into well-formed blocks. This is
+    // useful when coverage_fd is a socket descriptor. Each block will contain
+    // a header, allowing data from multiple processes to be sent over the same
+    // socket.
+    unsigned int coverage_max_block_size;
+  } __sanitizer_sandbox_arguments;
+
   // Tell the tools to write their reports to "path.<pid>" instead of stderr.
   void __sanitizer_set_report_path(const char *path);
 
   // Notify the tools that the sandbox is going to be turned on. The reserved
   // parameter will be used in the future to hold a structure with functions
   // that the tools may call to bypass the sandbox.
-  void __sanitizer_sandbox_on_notify(void *reserved);
+  void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
 
   // This function is called by the tool when it has just finished reporting
   // an error. 'error_summary' is a one-line string that summarizes

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Mon May 19 07:53:03 2014
@@ -300,9 +300,9 @@ void __sanitizer_set_report_path(const c
   }
 }
 
-void NOINLINE __sanitizer_sandbox_on_notify(void *reserved) {
-  (void)reserved;
-  PrepareForSandboxing();
+void NOINLINE
+__sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args) {
+  PrepareForSandboxing(args);
   if (sandboxing_callback)
     sandboxing_callback();
 }

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=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Mon May 19 07:53:03 2014
@@ -183,7 +183,8 @@ void ReExec();
 bool StackSizeIsUnlimited();
 void SetStackSizeLimitInBytes(uptr limit);
 void AdjustStackSize(void *attr);
-void PrepareForSandboxing();
+void PrepareForSandboxing(__sanitizer_sandbox_arguments *args);
+void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args);
 void SetSandboxingCallback(void (*f)());
 
 void InitTlsSize();

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage.cc Mon May 19 07:53:03 2014
@@ -43,7 +43,7 @@
 atomic_uint32_t dump_once_guard;  // Ensure that CovDump runs only once.
 
 // pc_array is the array containing the covered PCs.
-// To make the pc_array thread- and AS- safe it has to be large enough.
+// To make the pc_array thread- and async-signal-safe it has to be large enough.
 // 128M counters "ought to be enough for anybody" (4M on 32-bit).
 // pc_array is allocated with MmapNoReserveOrDie and so it uses only as
 // much RAM as it really needs.
@@ -51,6 +51,10 @@ static const uptr kPcArraySize = FIRST_3
 static uptr *pc_array;
 static atomic_uintptr_t pc_array_index;
 
+static bool cov_sandboxed = false;
+static int cov_fd = kInvalidFd;
+static unsigned int cov_max_block_size = 0;
+
 namespace __sanitizer {
 
 // Simply add the pc into the vector under lock. If the function is called more
@@ -71,8 +75,56 @@ static inline bool CompareLess(const upt
   return a < b;
 }
 
+// Block layout for packed file format: header, followed by module name (no
+// trailing zero), followed by data blob.
+struct CovHeader {
+  int pid;
+  unsigned int module_name_length;
+  unsigned int data_length;
+};
+
+static void CovWritePacked(int pid, const char *module, const void *blob,
+                           unsigned int blob_size) {
+  CHECK_GE(cov_fd, 0);
+  unsigned module_name_length = internal_strlen(module);
+  CovHeader header = {pid, module_name_length, blob_size};
+
+  if (cov_max_block_size == 0) {
+    // Writing to a file. Just go ahead.
+    internal_write(cov_fd, &header, sizeof(header));
+    internal_write(cov_fd, module, module_name_length);
+    internal_write(cov_fd, blob, blob_size);
+  } else {
+    // Writing to a socket. We want to split the data into appropriately sized
+    // blocks.
+    InternalScopedBuffer<char> block(cov_max_block_size);
+    CHECK_EQ((uptr)block.data(), (uptr)(CovHeader *)block.data());
+    uptr header_size_with_module = sizeof(header) + module_name_length;
+    CHECK_LT(header_size_with_module, cov_max_block_size);
+    unsigned int max_payload_size =
+        cov_max_block_size - header_size_with_module;
+    char *block_pos = block.data();
+    internal_memcpy(block_pos, &header, sizeof(header));
+    block_pos += sizeof(header);
+    internal_memcpy(block_pos, module, module_name_length);
+    block_pos += module_name_length;
+    char *block_data_begin = block_pos;
+    char *blob_pos = (char *)blob;
+    while (blob_size > 0) {
+      unsigned int payload_size = Min(blob_size, max_payload_size);
+      blob_size -= payload_size;
+      internal_memcpy(block_data_begin, blob_pos, payload_size);
+      blob_pos += payload_size;
+      ((CovHeader *)block.data())->data_length = payload_size;
+      internal_write(cov_fd, block.data(),
+                     header_size_with_module + payload_size);
+    }
+  }
+}
+
 // Dump the coverage on disk.
-void CovDump() {
+static void CovDump() {
+  if (!common_flags()->coverage) return;
 #if !SANITIZER_WINDOWS
   if (atomic_fetch_add(&dump_once_guard, 1, memory_order_relaxed))
     return;
@@ -81,7 +133,7 @@ void CovDump() {
   InternalMmapVector<u32> offsets(size);
   const uptr *vb = pc_array;
   const uptr *ve = vb + size;
-  MemoryMappingLayout proc_maps(/*cache_enabled*/false);
+  MemoryMappingLayout proc_maps(/*cache_enabled*/true);
   uptr mb, me, off, prot;
   InternalScopedBuffer<char> module(4096);
   InternalScopedBuffer<char> path(4096 * 2);
@@ -102,22 +154,57 @@ void CovDump() {
         offsets.push_back(static_cast<u32>(diff));
       }
       char *module_name = StripModuleName(module.data());
-      internal_snprintf((char *)path.data(), path.size(), "%s.%zd.sancov",
-                        module_name, internal_getpid());
-      InternalFree(module_name);
-      uptr fd = OpenFile(path.data(), true);
-      if (internal_iserror(fd)) {
-        Report(" CovDump: failed to open %s for writing\n", path.data());
+      if (cov_sandboxed) {
+        CovWritePacked(internal_getpid(), module_name, offsets.data(),
+                       offsets.size() * sizeof(u32));
+        VReport(1, " CovDump: %zd PCs written to packed file\n", vb - old_vb);
       } else {
-        internal_write(fd, offsets.data(), offsets.size() * sizeof(u32));
-        internal_close(fd);
-        VReport(1, " CovDump: %s: %zd PCs written\n", path.data(), vb - old_vb);
+        // One file per module per process.
+        internal_snprintf((char *)path.data(), path.size(), "%s.%zd.sancov",
+                          module_name, internal_getpid());
+        uptr fd = OpenFile(path.data(), true);
+        if (internal_iserror(fd)) {
+          Report(" CovDump: failed to open %s for writing\n", path.data());
+        } else {
+          internal_write(fd, offsets.data(), offsets.size() * sizeof(u32));
+          internal_close(fd);
+          VReport(1, " CovDump: %s: %zd PCs written\n", path.data(),
+                  vb - old_vb);
+        }
       }
+      InternalFree(module_name);
     }
   }
+  if (cov_fd >= 0)
+    internal_close(cov_fd);
 #endif  // !SANITIZER_WINDOWS
 }
 
+static void OpenPackedFileForWriting() {
+  CHECK(cov_fd == kInvalidFd);
+  InternalScopedBuffer<char> path(1024);
+  internal_snprintf((char *)path.data(), path.size(), "%zd.sancov.packed",
+                    internal_getpid());
+  uptr fd = OpenFile(path.data(), true);
+  if (internal_iserror(fd)) {
+    Report(" Coverage: failed to open %s for writing\n", path.data());
+    Die();
+  }
+  cov_fd = fd;
+}
+
+void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
+  if (!args) return;
+  if (!common_flags()->coverage) return;
+  cov_sandboxed = args->coverage_sandboxed;
+  if (!cov_sandboxed) return;
+  cov_fd = args->coverage_fd;
+  cov_max_block_size = args->coverage_max_block_size;
+  if (cov_fd < 0)
+    // Pre-open the file now. The sandbox won't allow us to do it later.
+    OpenPackedFileForWriting();
+}
+
 }  // namespace __sanitizer
 
 extern "C" {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Mon May 19 07:53:03 2014
@@ -91,11 +91,15 @@ extern "C" {
   SANITIZER_INTERFACE_ATTRIBUTE
   void __sanitizer_set_report_path(const char *path);
 
-  // Notify the tools that the sandbox is going to be turned on. The reserved
-  // parameter will be used in the future to hold a structure with functions
-  // that the tools may call to bypass the sandbox.
-  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
-  void __sanitizer_sandbox_on_notify(void *reserved);
+  typedef struct {
+      int coverage_sandboxed;
+      __sanitizer::sptr coverage_fd;
+      unsigned int coverage_max_block_size;
+  } __sanitizer_sandbox_arguments;
+
+  // Notify the tools that the sandbox is going to be turned on.
+  SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void
+      __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
 
   // This function is called by the tool when it has just finished reporting
   // an error. 'error_summary' is a one-line string that summarizes

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Mon May 19 07:53:03 2014
@@ -390,7 +390,7 @@ void GetThreadStackAndTls(bool main, upt
 }
 #endif  // SANITIZER_GO
 
-void PrepareForSandboxing() {
+void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
   // Some kinds of sandboxes may forbid filesystem access, so we won't be able
   // to read the file mappings from /proc/self/maps. Luckily, neither the
   // process will be able to load additional libraries, so it's fine to use the
@@ -401,6 +401,7 @@ void PrepareForSandboxing() {
   if (Symbolizer *sym = Symbolizer::GetOrNull())
     sym->PrepareForSandboxing();
 #endif
+  CovPrepareForSandboxing(args);
 }
 
 enum MutexState {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Mon May 19 07:53:03 2014
@@ -196,7 +196,8 @@ void ReExec() {
   UNIMPLEMENTED();
 }
 
-void PrepareForSandboxing() {
+void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
+  (void)args;
   // Nothing here for now.
 }
 

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=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Mon May 19 07:53:03 2014
@@ -192,7 +192,8 @@ void ReExec() {
   UNIMPLEMENTED();
 }
 
-void PrepareForSandboxing() {
+void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
+  (void)args;
   // Nothing here for now.
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py (original)
+++ compiler-rt/trunk/lib/sanitizer_common/scripts/sancov.py Mon May 19 07:53:03 2014
@@ -4,6 +4,7 @@
 # We need to merge these integers into a set and then
 # either print them (as hex) or dump them into another file.
 import array
+import struct
 import sys
 
 prog_name = "";
@@ -11,16 +12,16 @@ prog_name = "";
 def Usage():
   print >> sys.stderr, "Usage: \n" + \
       " " + prog_name + " merge file1 [file2 ...]  > output\n" \
-      " " + prog_name + " print file1 [file2 ...]\n"
+      " " + prog_name + " print file1 [file2 ...]\n" \
+      " " + prog_name + " unpack file1 [file2 ...]\n"
   exit(1)
 
 def ReadOneFile(path):
-  f = open(path, mode="rb")
-  f.seek(0, 2)
-  size = f.tell()
-  f.seek(0, 0)
-  s = set(array.array('I', f.read(size)))
-  f.close()
+  with open(path, mode="rb") as f:
+    f.seek(0, 2)
+    size = f.tell()
+    f.seek(0, 0)
+    s = set(array.array('I', f.read(size)))
   print >>sys.stderr, "%s: read %d PCs from %s" % (prog_name, size / 4, path)
   return s
 
@@ -44,6 +45,36 @@ def MergeAndPrint(files):
   a = array.array('I', s)
   a.tofile(sys.stdout)
 
+
+def UnpackOneFile(path):
+  with open(path, mode="rb") as f:
+    print >> sys.stderr, "%s: unpacking %s" % (prog_name, path)
+    while True:
+      header = f.read(12)
+      if not header: return
+      if len(header) < 12:
+        break
+      pid, module_length, blob_size = struct.unpack('iII', header)
+      module = f.read(module_length)
+      blob = f.read(blob_size)
+      assert(len(module) == module_length)
+      assert(len(blob) == blob_size)
+      extracted_file = "%s.%d.sancov" % (module, pid)
+      print >> sys.stderr, "%s: extracting %s" % \
+        (prog_name, extracted_file)
+      # The packed file may contain multiple blobs for the same pid/module
+      # pair. Append to the end of the file instead of overwriting.
+      with open(extracted_file, 'ab') as f2:
+        f2.write(blob)
+    # fail
+    raise Exception('Error reading file %s' % path)
+
+
+def Unpack(files):
+  for f in files:
+    UnpackOneFile(f)
+
+
 if __name__ == '__main__':
   prog_name = sys.argv[0]
   if len(sys.argv) <= 2:
@@ -52,5 +83,7 @@ if __name__ == '__main__':
     PrintFiles(sys.argv[2:])
   elif sys.argv[1] == "merge":
     MergeAndPrint(sys.argv[2:])
+  elif sys.argv[1] == "unpack":
+    Unpack(sys.argv[2:])
   else:
     Usage()

Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-sandboxing.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-sandboxing.cc?rev=209121&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-sandboxing.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-sandboxing.cc Mon May 19 07:53:03 2014
@@ -0,0 +1,85 @@
+// RUN: %clangxx_asan -mllvm -asan-coverage=2 -DSHARED %s -shared -o %T/libcoverage_sandboxing_test.so -fPIC
+// RUN: %clangxx_asan -mllvm -asan-coverage=1 %s   -o %t -Wl,-R,\$ORIGIN -L%T -lcoverage_sandboxing_test
+// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1
+// RUN: rm -rf %T/coverage_sandboxing_test
+// RUN: mkdir %T/coverage_sandboxing_test && cd %T/coverage_sandboxing_test
+// RUN: mkdir vanilla && cd vanilla
+// RUN: %run %t 2>&1         | FileCheck %s --check-prefix=CHECK-vanilla
+// RUN: mkdir ../sandbox1 && cd ../sandbox1
+// RUN: %run %t a 2>&1       | FileCheck %s --check-prefix=CHECK-sandbox
+// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed 
+// RUN: mkdir ../sandbox2 && cd ../sandbox2
+// RUN: %run %t a b 2>&1     | FileCheck %s --check-prefix=CHECK-sandbox
+// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed 
+// RUN: cd ..
+// RUN: %sancov print vanilla/libcoverage_sandboxing_test.so.*.sancov > vanilla.txt
+// RUN: %sancov print sandbox1/libcoverage_sandboxing_test.so.*.sancov > sandbox1.txt
+// RUN: %sancov print sandbox2/libcoverage_sandboxing_test.so.*.sancov > sandbox2.txt
+// RUN: diff vanilla.txt sandbox1.txt
+// RUN: diff vanilla.txt sandbox2.txt
+// RUN: cd ../ && rm coverage_sandboxing_test -r
+// https://code.google.com/p/address-sanitizer/issues/detail?id=263
+// XFAIL: android
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sanitizer/common_interface_defs.h>
+
+#define bb0(n)                        \
+  case n:                             \
+    fprintf(stderr, "foo: %d\n", n);  \
+    break;
+
+#define bb1(n) bb0(n) bb0(n + 1)
+#define bb2(n) bb1(n) bb1(n + 2)
+#define bb3(n) bb2(n) bb2(n + 4)
+#define bb4(n) bb3(n) bb3(n + 8)
+#define bb5(n) bb4(n) bb4(n + 16)
+#define bb6(n) bb5(n) bb5(n + 32)
+#define bb7(n) bb6(n) bb6(n + 64)
+#define bb8(n) bb7(n) bb7(n + 128)
+
+#ifdef SHARED
+void foo(int i) {
+  switch(i) {
+    // 256 basic blocks
+    bb8(0)
+  }
+}
+#else
+extern void foo(int i);
+
+int main(int argc, char **argv) {
+  assert(argc <= 3);
+  for (int i = 0; i < 256; i++) foo(i);
+  fprintf(stderr, "PID: %d\n", getpid());
+  if (argc == 1) {
+    // Vanilla mode, dump to individual files.
+    return 0;
+  }
+  // Dump to packed file.
+  int fd = creat("coverage_sandboxing_test.sancov.packed", 0660);
+  __sanitizer_sandbox_arguments args = {0};
+  args.coverage_sandboxed = 1;
+  args.coverage_fd = fd;
+  if (argc == 2)
+    // Write to packed file, do not split into blocks.
+    args.coverage_max_block_size = 0;
+  else if (argc == 3)
+    // Write to packed file, split into blocks (as if writing to a socket).
+    args.coverage_max_block_size = 100;
+  __sanitizer_sandbox_on_notify(&args);
+  return 0;
+}
+#endif
+
+// CHECK-vanilla: PID: [[PID:[0-9]+]]
+// CHECK-vanilla: [[PID]].sancov: 1 PCs written
+// CHECK-vanilla: .so.[[PID]].sancov: 258 PCs written
+
+// CHECK-sandbox: PID: [[PID:[0-9]+]]
+// CHECK-sandbox: 258 PCs written to packed file

Modified: compiler-rt/trunk/test/asan/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/lit.cfg?rev=209121&r1=209120&r2=209121&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/lit.cfg (original)
+++ compiler-rt/trunk/test/asan/lit.cfg Mon May 19 07:53:03 2014
@@ -85,6 +85,14 @@ if not os.path.exists(asan_symbolize):
   lit_config.fatal("Can't find script on path %r" % asan_symbolize)
 python_exec = get_required_attr(config, "python_executable")
 config.substitutions.append( ("%asan_symbolize", python_exec + " " + asan_symbolize + " ") )
+# Setup path to sancov.py script.
+sanitizer_common_source_dir = os.path.join(
+  get_required_attr(config, "compiler_rt_src_root"), "lib", "sanitizer_common")
+sancov = os.path.join(sanitizer_common_source_dir, "scripts", "sancov.py")
+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 + " ") )
 
 # Determine kernel bitness
 if config.host_arch.find('64') != -1 and config.android != "TRUE":





More information about the llvm-commits mailing list