[compiler-rt] r277858 - [sanitizers] trace buffer API to use user-allocated buffer.

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 5 13:09:42 PDT 2016


Author: aizatsky
Date: Fri Aug  5 15:09:42 2016
New Revision: 277858

URL: http://llvm.org/viewvc/llvm-project?rev=277858&view=rev
Log:
[sanitizers] trace buffer API to use user-allocated buffer.

Subscribers: kubabrecka

Differential Revision: https://reviews.llvm.org/D23186

Modified:
    compiler-rt/trunk/include/sanitizer/coverage_interface.h
    compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
    compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc

Modified: compiler-rt/trunk/include/sanitizer/coverage_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/coverage_interface.h?rev=277858&r1=277857&r2=277858&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/coverage_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/coverage_interface.h Fri Aug  5 15:09:42 2016
@@ -41,13 +41,6 @@ extern "C" {
   // Some of the entries in *data will be zero.
   uintptr_t __sanitizer_get_coverage_guards(uintptr_t **data);
 
-  // Set *data to the growing buffer with covered PCs and return the size
-  // of the buffer. The entries are never zero.
-  // When only unique pcs are collected, the size is equal to
-  // __sanitizer_get_total_unique_coverage.
-  // WARNING: EXPERIMENTAL API.
-  uintptr_t __sanitizer_get_coverage_pc_buffer(uintptr_t **data);
-
   // The coverage instrumentation may optionally provide imprecise counters.
   // Rather than exposing the counter values to the user we instead map
   // the counters to a bitset.
@@ -65,6 +58,15 @@ extern "C" {
   // __sanitizer_get_number_of_counters bytes long and 8-aligned.
   uintptr_t
   __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
+
+  // EXPERIMENTAL API
+  // Set allocated buffer to record new coverage PCs as they are executed.
+  // Buffer length is specified in uptrs.
+  void __sanitizer_set_coverage_pc_buffer(uintptr_t *buffer, uintptr_t length);
+  // Number of pcs recorded in the buffer.
+  // Reset by __sanitizer_reset_coverage();
+  uintptr_t __sanitizer_get_coverage_pc_buffer_pos();
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif

Modified: compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc?rev=277858&r1=277857&r2=277858&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win_dll_thunk.cc Fri Aug  5 15:09:42 2016
@@ -320,7 +320,7 @@ INTERFACE_FUNCTION(__sanitizer_cov_trace
 INTERFACE_FUNCTION(__sanitizer_cov_with_check)
 INTERFACE_FUNCTION(__sanitizer_get_allocated_size)
 INTERFACE_FUNCTION(__sanitizer_get_coverage_guards)
-INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer)
+INTERFACE_FUNCTION(__sanitizer_get_coverage_pc_buffer_pos)
 INTERFACE_FUNCTION(__sanitizer_get_current_allocated_bytes)
 INTERFACE_FUNCTION(__sanitizer_get_estimated_allocated_size)
 INTERFACE_FUNCTION(__sanitizer_get_free_bytes)
@@ -338,6 +338,7 @@ INTERFACE_FUNCTION(__sanitizer_reset_cov
 INTERFACE_FUNCTION(__sanitizer_get_number_of_counters)
 INTERFACE_FUNCTION(__sanitizer_update_counter_bitset_and_clear_counters)
 INTERFACE_FUNCTION(__sanitizer_sandbox_on_notify)
+INTERFACE_FUNCTION(__sanitizer_set_coverage_pc_buffer)
 INTERFACE_FUNCTION(__sanitizer_set_death_callback)
 INTERFACE_FUNCTION(__sanitizer_set_report_path)
 INTERFACE_FUNCTION(__sanitizer_set_report_fd)

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=277858&r1=277857&r2=277858&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_coverage_libcdep.cc Fri Aug  5 15:09:42 2016
@@ -110,7 +110,8 @@ class CoverageData {
 
   uptr *data();
   uptr size() const;
-  uptr *buffer() const { return pc_buffer; }
+
+  void SetPcBuffer(uptr* data, uptr length);
 
  private:
   struct NamedPcRange {
@@ -143,6 +144,7 @@ class CoverageData {
   fd_t pc_fd;
 
   uptr *pc_buffer;
+  uptr pc_buffer_len;
 
   // Vector of coverage guard arrays, protected by mu.
   InternalMmapVectorNoCtor<s32*> guard_array_vec;
@@ -216,9 +218,7 @@ void CoverageData::Enable() {
   }
 
   pc_buffer = nullptr;
-  if (common_flags()->coverage_pc_buffer)
-    pc_buffer = reinterpret_cast<uptr *>(MmapNoReserveOrDie(
-        sizeof(uptr) * kPcArrayMaxSize, "CovInit::pc_buffer"));
+  pc_buffer_len = 0;
 
   cc_array = reinterpret_cast<uptr **>(MmapNoReserveOrDie(
       sizeof(uptr *) * kCcArrayMaxSize, "CovInit::cc_array"));
@@ -257,10 +257,6 @@ void CoverageData::Disable() {
     UnmapOrDie(cc_array, sizeof(uptr *) * kCcArrayMaxSize);
     cc_array = nullptr;
   }
-  if (pc_buffer) {
-    UnmapOrDie(pc_buffer, sizeof(uptr) * kPcArrayMaxSize);
-    pc_buffer = nullptr;
-  }
   if (tr_event_array) {
     UnmapOrDie(tr_event_array,
                sizeof(tr_event_array[0]) * kTrEventArrayMaxSize +
@@ -429,7 +425,7 @@ void CoverageData::Add(uptr pc, u32 *gua
            atomic_load(&pc_array_size, memory_order_acquire));
   uptr counter = atomic_fetch_add(&coverage_counter, 1, memory_order_relaxed);
   pc_array[idx] = BundlePcAndCounter(pc, counter);
-  if (pc_buffer) pc_buffer[counter] = pc;
+  if (pc_buffer && counter < pc_buffer_len) pc_buffer[counter] = pc;
 }
 
 // Registers a pair caller=>callee.
@@ -883,6 +879,11 @@ void CoverageData::DumpAll() {
   DumpCallerCalleePairs();
 }
 
+void CoverageData::SetPcBuffer(uptr* data, uptr length) {
+  pc_buffer = data;
+  pc_buffer_len = length;
+}
+
 void CovPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
   if (!args) return;
   if (!coverage_enabled) return;
@@ -1018,8 +1019,12 @@ uptr __sanitizer_get_coverage_guards(upt
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE
-uptr __sanitizer_get_coverage_pc_buffer(uptr **data) {
-  *data = coverage_data.buffer();
+void __sanitizer_set_coverage_pc_buffer(uptr *data, uptr length) {
+  coverage_data.SetPcBuffer(data, length);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+uptr __sanitizer_get_coverage_pc_buffer_pos() {
   return __sanitizer_get_total_unique_coverage();
 }
 

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=277858&r1=277857&r2=277858&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Fri Aug  5 15:09:42 2016
@@ -144,9 +144,6 @@ COMMON_FLAG(bool, coverage_direct, SANIT
 COMMON_FLAG(const char *, coverage_dir, ".",
             "Target directory for coverage dumps. Defaults to the current "
             "directory.")
-COMMON_FLAG(bool, coverage_pc_buffer, true,
-            "If set (and if 'coverage' is set too), the pcs would be collected "
-            "in a buffer.")
 COMMON_FLAG(bool, full_address_space, false,
             "Sanitize complete address space; "
             "by default kernel area on 32-bit platforms will not be sanitized")

Modified: compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc?rev=277858&r1=277857&r2=277858&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/coverage-pc-buffer.cc Fri Aug  5 15:09:42 2016
@@ -1,11 +1,13 @@
 // Test __sanitizer_coverage_pc_buffer().
 
-// RUN: %clangxx_asan -fsanitize-coverage=edge %s -o %t && %run %t
+// RUN: %clangxx_asan -fsanitize-coverage=edge -std=c++11 %s -O3 -o %t && %run %t
 
 // UNSUPPORTED: android
 
 #include <assert.h>
+#include <memory>
 #include <sanitizer/coverage_interface.h>
+#include <stdint.h>
 #include <stdio.h>
 
 static volatile int sink;
@@ -19,47 +21,41 @@ void assertNotZeroPcs(uintptr_t *buf, ui
 }
 
 int main() {
+  uintptr_t buf_size = 1 << 20;
+  std::unique_ptr<uintptr_t[]> buf(new uintptr_t[buf_size]);
+  __sanitizer_set_coverage_pc_buffer(buf.get(), buf_size);
+
   {
-    uintptr_t *buf = NULL;
-    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
-    assertNotZeroPcs(buf, sz);
+    uintptr_t sz = __sanitizer_get_coverage_pc_buffer_pos();
+    assertNotZeroPcs(buf.get(), sz);
     assert(sz);
   }
 
   {
-    uintptr_t *buf = NULL;
-    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+    uintptr_t sz = __sanitizer_get_coverage_pc_buffer_pos();
     // call functions for the first time.
     foo();
     bar();
-    uintptr_t *buf1 = NULL;
-    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
-    assertNotZeroPcs(buf1, sz1);
-    assert(buf1 == buf);
+    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer_pos();
+    assertNotZeroPcs(buf.get(), sz1);
     assert(sz1 > sz);
   }
 
   {
-    uintptr_t *buf = NULL;
-    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+    uintptr_t sz = __sanitizer_get_coverage_pc_buffer_pos();
     // second call shouldn't increase coverage.
     bar();
-    uintptr_t *buf1 = NULL;
-    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
-    assertNotZeroPcs(buf1, sz1);
-    assert(buf1 == buf);
+    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer_pos();
     assert(sz1 == sz);
+    assertNotZeroPcs(buf.get(), sz1);
   }
 
   {
-    uintptr_t *buf = NULL;
-    uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+    uintptr_t sz = __sanitizer_get_coverage_pc_buffer_pos();
     // reset coverage to 0.
     __sanitizer_reset_coverage();
-    uintptr_t *buf1 = NULL;
-    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
-    assertNotZeroPcs(buf1, sz1);
-    assert(buf1 == buf);
+    uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer_pos();
+    assertNotZeroPcs(buf.get(), sz1);
     assert(sz1 < sz);
   }
 }




More information about the llvm-commits mailing list