<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jan 28, 2015 at 2:39 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kcc<br>
Date: Wed Jan 28 16:39:44 2015<br>
New Revision: 227387<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=227387&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=227387&view=rev</a><br>
Log:<br>
[sanitizer] allow to reset the bb/edge coverage data inside the process while it is running (single-threaded). Also expose the current coverage set to the process.<br>
<br>
Added:<br>
    compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc<br>
Modified:<br>
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc<br>
<br>
Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=227387&r1=227386&r2=227387&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=227387&r1=227386&r2=227387&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)<br>
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Wed Jan 28 16:39:44 2015<br>
@@ -74,6 +74,14 @@ extern "C" {<br>
   // This can be useful for coverage-directed in-process fuzzers.<br>
   uintptr_t __sanitizer_get_total_unique_coverage();<br>
<br>
+  // Reset the basic-block (edge) coverage to the initial state.<br>
+  // Useful for in-process fuzzing to start collecting coverage from scratch.<br>
+  // Experimental, will likely not work for multi-threaded process.<br>
+  void __sanitizer_reset_coverage();<br>
+  // Set *data to the array of covered PCs and return the size of that array.<br>
+  // Some of the entries in *data will be zero.<br>
+  uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data);<br></blockquote><div><br></div><div>^^^</div><div>I feel that the number of coverage-related functions is substantial enough to move them to a dedicated <sanitizer/coverage_interface.h> header.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
   // Annotate the current state of a contiguous container, such as<br>
   // std::vector, std::string or similar.<br>
   // A contiguous container is a container that keeps all of its elements<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=227387&r1=227386&r2=227387&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc?rev=227387&r1=227386&r2=227387&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Wed Jan 28 16:39:44 2015<br>
@@ -83,6 +83,7 @@ class CoverageData {<br>
<br>
   void InitializeGuardArray(s32 *guards);<br>
   void InitializeGuards(s32 *guards, uptr n);<br>
+  void ReinitializeGuards();<br>
<br>
   uptr *data();<br>
   uptr size();<br>
@@ -211,6 +212,13 @@ void CoverageData::Disable() {<br>
   }<br>
 }<br>
<br>
+void CoverageData::ReinitializeGuards() {<br>
+  // Assuming single thread.<br>
+  atomic_store(&pc_array_index, 0, memory_order_relaxed);<br>
+  for (uptr i = 0; i < guard_array_vec.size(); i++)<br>
+    InitializeGuardArray(guard_array_vec[i]);<br>
+}<br>
+<br>
 void CoverageData::ReInit() {<br>
   Disable();<br>
   if (coverage_enabled) {<br>
@@ -228,8 +236,7 @@ void CoverageData::ReInit() {<br>
   // Re-initialize the guards.<br>
   // We are single-threaded now, no need to grab any lock.<br>
   CHECK_EQ(atomic_load(&pc_array_index, memory_order_relaxed), 0);<br>
-  for (uptr i = 0; i < guard_array_vec.size(); i++)<br>
-    InitializeGuardArray(guard_array_vec[i]);<br>
+  ReinitializeGuards();<br>
 }<br>
<br>
 void CoverageData::BeforeFork() {<br>
@@ -689,4 +696,16 @@ SANITIZER_INTERFACE_ATTRIBUTE<br>
 void __sanitizer_cov_trace_basic_block(s32 *id) {<br>
   coverage_data.TraceBasicBlock(id);<br>
 }<br>
+SANITIZER_INTERFACE_ATTRIBUTE<br>
+void __sanitizer_reset_coverage() {<br>
+  coverage_data.ReinitializeGuards();<br>
+  internal_bzero_aligned16(<br>
+      coverage_data.data(),<br>
+      RoundUpTo(coverage_data.size() * sizeof(coverage_data.data()[0]), 16));<br>
+}<br>
+SANITIZER_INTERFACE_ATTRIBUTE<br>
+uptr __sanitizer_get_coverage_guards(uptr **data) {<br>
+  *data = coverage_data.data();<br>
+  return coverage_data.size();<br>
+}<br>
 }  // extern "C"<br>
<br>
Added: compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc?rev=227387&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc?rev=227387&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc (added)<br>
+++ compiler-rt/trunk/test/asan/TestCases/Linux/coverage-reset.cc Wed Jan 28 16:39:44 2015<br>
@@ -0,0 +1,52 @@<br>
+// Test __sanitizer_reset_coverage().<br>
+<br>
+// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t<br>
+// RUN: ASAN_OPTIONS=coverage=1 %run %t<br>
+<br>
+#include <sanitizer/common_interface_defs.h><br>
+#include <stdio.h><br>
+#include <assert.h><br>
+static volatile int sink;<br>
+__attribute__((noinline)) void bar() { sink = 2; }<br>
+__attribute__((noinline)) void foo() { sink = 1; }<br>
+<br>
+#define GET_AND_PRINT_COVERAGE()                                       \<br>
+  bitset = 0;                                                  \<br>
+  for (size_t i = 0; i < n_guards; i++)                        \<br>
+    if (guards[i]) bitset |= 1U << i;                          \<br>
+  printf("line %d: bitset %zd total: %zd\n", __LINE__, bitset, \<br>
+         __sanitizer_get_total_unique_coverage());<br>
+<br>
+#define IS_POWER_OF_TWO(a) ((a & ((a) - 1)) == 0)<br>
+<br>
+int main() {<br>
+  size_t *guards = 0;<br>
+  size_t bitset;<br>
+  size_t n_guards = __sanitizer_get_coverage_guards(&guards);<br>
+<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  size_t main_bit = bitset;<br>
+  assert(IS_POWER_OF_TWO(main_bit));<br>
+<br>
+  foo();<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  size_t foo_bit = bitset & ~main_bit;<br>
+  assert(IS_POWER_OF_TWO(foo_bit));<br>
+<br>
+  bar();<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  size_t bar_bit = bitset & ~(main_bit | foo_bit);<br>
+  assert(IS_POWER_OF_TWO(bar_bit));<br>
+<br>
+  __sanitizer_reset_coverage();<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  assert(bitset == 0);<br>
+<br>
+  foo();<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  assert(bitset == foo_bit);<br>
+<br>
+  bar();<br>
+  GET_AND_PRINT_COVERAGE();<br>
+  assert(bitset == (foo_bit | bar_bit));<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr">Alexey Samsonov<br><a href="mailto:vonosmas@gmail.com" target="_blank">vonosmas@gmail.com</a></div></div>
</div></div>