r282751 - [sanitizer-coverage] more docs

Kostya Serebryany via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 29 11:58:17 PDT 2016


Author: kcc
Date: Thu Sep 29 13:58:17 2016
New Revision: 282751

URL: http://llvm.org/viewvc/llvm-project?rev=282751&view=rev
Log:
[sanitizer-coverage] more docs

Modified:
    cfe/trunk/docs/SanitizerCoverage.rst

Modified: cfe/trunk/docs/SanitizerCoverage.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/SanitizerCoverage.rst?rev=282751&r1=282750&r2=282751&view=diff
==============================================================================
--- cfe/trunk/docs/SanitizerCoverage.rst (original)
+++ cfe/trunk/docs/SanitizerCoverage.rst Thu Sep 29 13:58:17 2016
@@ -349,6 +349,73 @@ Similarly to `trace-pc,indirect-calls`,
 
 The functions `__sanitizer_cov_trace_pc_*` should be defined by the user.
 
+Example: 
+
+.. code-block:: c++
+
+  // trace-pc-guard-cb.cc
+  #include <stdint.h>
+  #include <stdio.h>
+  #include <sanitizer/coverage_interface.h>
+
+  // This callback is inserted by the compiler as a module constructor
+  // into every compilation unit. 'start' and 'stop' correspond to the
+  // beginning and end of the section with the guards for the entire
+  // binary (executable or DSO) and so it will be called multiple times
+  // with the same parameters.
+  extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
+                                                      uint32_t *stop) {
+    static uint64_t N;  // Counter for the guards.
+    if (start == stop || *start) return;  // Initialize only once.
+    printf("INIT: %p %p\n", start, stop);
+    for (uint32_t *x = start; x < stop; x++)
+      *x = ++N;  // Guards should start from 1.
+  }
+
+  // This callback is inserted by the compiler on every edge in the
+  // control flow (some optimizations apply).
+  // Typically, the compiler will emit the code like this:
+  //    if(*guard)
+  //      __sanitizer_cov_trace_pc_guard(guard);
+  // But for large functions it will emit a simple call:
+  //    __sanitizer_cov_trace_pc_guard(guard);
+  extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
+    if (!*guard) return;  // Duplicate the guard check.
+    // If you set *guard to 0 this code will not be called again for this edge.
+    // Now you can get the PC and do whatever you want: 
+    //   store it somewhere or symbolize it and print right away.
+    // The values of `*guard` are as you set them in
+    // __sanitizer_cov_trace_pc_guard_init and so you can make the consecutive
+    // and use them to dereference an array or a bit vector.
+    void *PC = __builtin_return_address(0);
+    char PcDescr[1024];
+    // This function is a part of the sanitizer run-time.
+    // To use it, link with AddressSanitizer or other sanitizer.
+    __sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));
+    printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
+  }
+
+.. code-block:: c++
+
+  // trace-pc-guard-example.cc
+  void foo() { }
+  int main(int argc, char **argv) {
+    if (argc > 1) foo();
+  }
+
+.. code-block:: console
+  
+  clang++ -g  -fsanitize-coverage=trace-pc-guard trace-pc-guard-example.cc -c
+  clang++ trace-pc-guard-cb.cc trace-pc-guard-example.o -fsanitize=address
+  ASAN_OPTIONS=strip_path_prefix=`pwd`/ ./a.out
+
+.. code-block:: console
+
+  INIT: 0x71bcd0 0x71bce0
+  guard: 0x71bcd4 2 PC 0x4ecd5b in main trace-pc-guard-example.cc:2
+  guard: 0x71bcd8 3 PC 0x4ecd9e in main trace-pc-guard-example.cc:3:7
+
+
 Tracing data flow
 =================
 




More information about the cfe-commits mailing list