[compiler-rt] r222060 - [asan] add interface function __sanitizer_get_total_unique_coverage; useful for coverage-guided in-process fuzzers

Kostya Serebryany kcc at google.com
Fri Nov 14 15:15:56 PST 2014


Author: kcc
Date: Fri Nov 14 17:15:55 2014
New Revision: 222060

URL: http://llvm.org/viewvc/llvm-project?rev=222060&view=rev
Log:
[asan] add interface function __sanitizer_get_total_unique_coverage; useful for coverage-guided in-process fuzzers

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc
Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
    compiler-rt/trunk/test/asan/TestCases/Linux/coverage.cc

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=222060&r1=222059&r2=222060&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Fri Nov 14 17:15:55 2014
@@ -70,6 +70,9 @@ extern "C" {
   // descriptor. Returns -1 on failure, or if coverage dumping is disabled.
   // This is intended for use by sandboxing code.
   intptr_t __sanitizer_maybe_open_cov_file(const char *name);
+  // Get the number of total unique covered entities (blocks, edges, calls).
+  // This can be useful for coverage-directed in-process fuzzers.
+  uintptr_t __sanitizer_get_total_unique_coverage();
 
   // Annotate the current state of a contiguous container, such as
   // std::vector, std::string or similar.

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=222060&r1=222059&r2=222060&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Fri Nov 14 17:15:55 2014
@@ -41,7 +41,9 @@
 #include "sanitizer_symbolizer.h"
 #include "sanitizer_flags.h"
 
-atomic_uint32_t dump_once_guard;  // Ensure that CovDump runs only once.
+static atomic_uint32_t dump_once_guard;  // Ensure that CovDump runs only once.
+
+static atomic_uintptr_t coverage_counter;
 
 // pc_array is the array containing the covered PCs.
 // To make the pc_array thread- and async-signal-safe it has to be large enough.
@@ -201,6 +203,7 @@ void CoverageData::Add(uptr pc) {
   CHECK_LT(idx * sizeof(uptr),
            atomic_load(&pc_array_size, memory_order_acquire));
   pc_array[idx] = pc;
+  atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed);
 }
 
 // Registers a pair caller=>callee.
@@ -228,8 +231,10 @@ void CoverageData::IndirCall(uptr caller
   for (uptr i = 2; i < cache_size; i++) {
     uptr was = 0;
     if (atomic_compare_exchange_strong(&atomic_callee_cache[i], &was, callee,
-                                       memory_order_seq_cst))
+                                       memory_order_seq_cst)) {
+      atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed);
       return;
+    }
     if (was == callee)  // Already have this callee.
       return;
   }
@@ -469,4 +474,8 @@ SANITIZER_INTERFACE_ATTRIBUTE
 sptr __sanitizer_maybe_open_cov_file(const char *name) {
   return MaybeOpenCovFile(name);
 }
+SANITIZER_INTERFACE_ATTRIBUTE
+uptr __sanitizer_get_total_unique_coverage() {
+  return atomic_load(&coverage_counter, memory_order_relaxed);
+}
 }  // extern "C"

Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc?rev=222060&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc Fri Nov 14 17:15:55 2014
@@ -0,0 +1,41 @@
+// Test __sanitizer_get_total_unique_coverage for caller-callee coverage
+
+// RUN: %clangxx_asan -fsanitize-coverage=4 %s -o %t
+// RUN: ASAN_OPTIONS=coverage=1 %run %t
+// RUN: rm -f caller-callee*.sancov
+//
+// REQUIRES: asan-64-bits
+
+#include <sanitizer/common_interface_defs.h>
+#include <stdio.h>
+#include <assert.h>
+int P = 0;
+struct Foo {virtual void f() {if (P) printf("Foo::f()\n");}};
+struct Foo1 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
+struct Foo2 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}};
+
+Foo *foo[3] = {new Foo, new Foo1, new Foo2};
+
+uintptr_t CheckNewTotalUniqueCoverageIsLargerAndReturnIt(uintptr_t old_total) {
+  uintptr_t new_total = __sanitizer_get_total_unique_coverage();
+  assert(new_total > old_total);
+  return new_total;
+}
+
+int main(int argc, char **argv) {
+  uintptr_t total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(0);
+  foo[0]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+  foo[1]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+  foo[2]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+  // Ok, called every function once.
+  // Now call them again from another call site. Should get new coverage.
+  foo[0]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+  foo[1]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+  foo[2]->f();
+  total = CheckNewTotalUniqueCoverageIsLargerAndReturnIt(total);
+}

Modified: compiler-rt/trunk/test/asan/TestCases/Linux/coverage.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage.cc?rev=222060&r1=222059&r2=222060&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/coverage.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage.cc Fri Nov 14 17:15:55 2014
@@ -13,6 +13,8 @@
 // https://code.google.com/p/address-sanitizer/issues/detail?id=263
 // XFAIL: android
 
+#include "sanitizer/common_interface_defs.h"
+#include <assert.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -29,8 +31,12 @@ int G[4];
 int main(int argc, char **argv) {
   fprintf(stderr, "PID: %d\n", getpid());
   for (int i = 1; i < argc; i++) {
-    if (!strcmp(argv[i], "foo"))
+    if (!strcmp(argv[i], "foo")) {
+      uintptr_t old_coverage = __sanitizer_get_total_unique_coverage();
       foo();
+      uintptr_t new_coverage = __sanitizer_get_total_unique_coverage();
+      assert(new_coverage > old_coverage);
+    }
     if (!strcmp(argv[i], "bar"))
       bar();
   }





More information about the llvm-commits mailing list