diff options
author | Kostya Serebryany <kcc@google.com> | 2016-09-29 18:58:17 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2016-09-29 18:58:17 +0000 |
commit | d6ae22a7ab7333f4c0d588715462d22c9a6068d8 (patch) | |
tree | 27fd1e5c4a425c1f9fb7f0d5904ceb1dd17c51a8 | |
parent | 6d91fce526ee8e36fa24d95dfc0fc379d3662939 (diff) | |
download | bcm5719-llvm-d6ae22a7ab7333f4c0d588715462d22c9a6068d8.tar.gz bcm5719-llvm-d6ae22a7ab7333f4c0d588715462d22c9a6068d8.zip |
[sanitizer-coverage] more docs
llvm-svn: 282751
-rw-r--r-- | clang/docs/SanitizerCoverage.rst | 67 |
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 ================= |