summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2016-09-29 18:58:17 +0000
committerKostya Serebryany <kcc@google.com>2016-09-29 18:58:17 +0000
commitd6ae22a7ab7333f4c0d588715462d22c9a6068d8 (patch)
tree27fd1e5c4a425c1f9fb7f0d5904ceb1dd17c51a8
parent6d91fce526ee8e36fa24d95dfc0fc379d3662939 (diff)
downloadbcm5719-llvm-d6ae22a7ab7333f4c0d588715462d22c9a6068d8.tar.gz
bcm5719-llvm-d6ae22a7ab7333f4c0d588715462d22c9a6068d8.zip
[sanitizer-coverage] more docs
llvm-svn: 282751
-rw-r--r--clang/docs/SanitizerCoverage.rst67
1 files changed, 67 insertions, 0 deletions
diff --git a/clang/docs/SanitizerCoverage.rst b/clang/docs/SanitizerCoverage.rst
index e2bd7fbe1de..051a365e34f 100644
--- a/clang/docs/SanitizerCoverage.rst
+++ b/clang/docs/SanitizerCoverage.rst
@@ -349,6 +349,73 @@ Similarly to `trace-pc,indirect-calls`, with `trace-pc-guards,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
=================
OpenPOWER on IntegriCloud