[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