|
@@ -25,17 +25,10 @@ following compile-time flags:
|
|
|
**extra** slowdown).
|
|
|
* ``-fsanitize-coverage=edge`` for edge-level coverage (up to 40% slowdown).
|
|
|
|
|
|
-You may also specify ``-fsanitize-coverage=indirect-calls`` for
|
|
|
-additional `caller-callee coverage`_.
|
|
|
-
|
|
|
At run time, pass ``coverage=1`` in ``ASAN_OPTIONS``,
|
|
|
``LSAN_OPTIONS``, ``MSAN_OPTIONS`` or ``UBSAN_OPTIONS``, as
|
|
|
appropriate. For the standalone coverage mode, use ``UBSAN_OPTIONS``.
|
|
|
|
|
|
-To get `Coverage counters`_, add ``-fsanitize-coverage=8bit-counters``
|
|
|
-to one of the above compile-time flags. At runtime, use
|
|
|
-``*SAN_OPTIONS=coverage=1:coverage_counters=1``.
|
|
|
-
|
|
|
Example:
|
|
|
|
|
|
.. code-block:: console
|
|
@@ -199,110 +192,6 @@ edges by introducing new dummy blocks and then instruments those blocks:
|
|
|
|/
|
|
|
C
|
|
|
|
|
|
-Bitset
|
|
|
-======
|
|
|
-
|
|
|
-**coverage_bitset=1 is deprecated, don't use**
|
|
|
-
|
|
|
-Caller-callee coverage
|
|
|
-======================
|
|
|
-
|
|
|
-**Deprecated, don't use**
|
|
|
-
|
|
|
-Every indirect function call is instrumented with a run-time function call that
|
|
|
-captures caller and callee. At the shutdown time the process dumps a separate
|
|
|
-file called ``caller-callee.PID.sancov`` which contains caller/callee pairs as
|
|
|
-pairs of lines (odd lines are callers, even lines are callees)
|
|
|
-
|
|
|
-.. code-block:: console
|
|
|
-
|
|
|
- a.out 0x4a2e0c
|
|
|
- a.out 0x4a6510
|
|
|
- a.out 0x4a2e0c
|
|
|
- a.out 0x4a87f0
|
|
|
-
|
|
|
-Current limitations:
|
|
|
-
|
|
|
-* Only the first 14 callees for every caller are recorded, the rest are silently
|
|
|
- ignored.
|
|
|
-* The output format is not very compact since caller and callee may reside in
|
|
|
- different modules and we need to spell out the module names.
|
|
|
-* The routine that dumps the output is not optimized for speed
|
|
|
-* Only Linux x86_64 is tested so far.
|
|
|
-* Sandboxes are not supported.
|
|
|
-
|
|
|
-Coverage counters
|
|
|
-=================
|
|
|
-
|
|
|
-**Deprecated, don't use**
|
|
|
-
|
|
|
-This experimental feature is inspired by
|
|
|
-`AFL <http://lcamtuf.coredump.cx/afl/technical_details.txt>`__'s coverage
|
|
|
-instrumentation. With additional compile-time and run-time flags you can get
|
|
|
-more sensitive coverage information. In addition to boolean values assigned to
|
|
|
-every basic block (edge) the instrumentation will collect imprecise counters.
|
|
|
-On exit, every counter will be mapped to a 8-bit bitset representing counter
|
|
|
-ranges: ``1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+`` and those 8-bit bitsets will
|
|
|
-be dumped to disk.
|
|
|
-
|
|
|
-.. code-block:: console
|
|
|
-
|
|
|
- % clang++ -g cov.cc -fsanitize=address -fsanitize-coverage=edge,8bit-counters
|
|
|
- % ASAN_OPTIONS="coverage=1:coverage_counters=1" ./a.out
|
|
|
- % ls -l *counters-sancov
|
|
|
- ... a.out.17110.counters-sancov
|
|
|
- % xxd *counters-sancov
|
|
|
- 0000000: 0001 0100 01
|
|
|
-
|
|
|
-These counters may also be used for in-process coverage-guided fuzzers. See
|
|
|
-``include/sanitizer/coverage_interface.h``:
|
|
|
-
|
|
|
-.. code-block:: c++
|
|
|
-
|
|
|
- // 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.
|
|
|
- // Every counter is associated with 8 bits in the bitset.
|
|
|
- // We define 8 value ranges: 1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+
|
|
|
- // The i-th bit is set to 1 if the counter value is in the i-th range.
|
|
|
- // This counter-based coverage implementation is *not* thread-safe.
|
|
|
-
|
|
|
- // Returns the number of registered coverage counters.
|
|
|
- uintptr_t __sanitizer_get_number_of_counters();
|
|
|
- // Updates the counter 'bitset', clears the counters and returns the number of
|
|
|
- // new bits in 'bitset'.
|
|
|
- // If 'bitset' is nullptr, only clears the counters.
|
|
|
- // Otherwise 'bitset' should be at least
|
|
|
- // __sanitizer_get_number_of_counters bytes long and 8-aligned.
|
|
|
- uintptr_t
|
|
|
- __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
|
|
|
-
|
|
|
-Tracing basic blocks
|
|
|
-====================
|
|
|
-
|
|
|
-**Deprecated, don't use**
|
|
|
-
|
|
|
-Experimental support for basic block (or edge) tracing.
|
|
|
-With ``-fsanitize-coverage=trace-bb`` the compiler will insert
|
|
|
-``__sanitizer_cov_trace_basic_block(s32 *id)`` before every function, basic block, or edge
|
|
|
-(depending on the value of ``-fsanitize-coverage=[func,bb,edge]``).
|
|
|
-Example:
|
|
|
-
|
|
|
-.. code-block:: console
|
|
|
-
|
|
|
- % clang -g -fsanitize=address -fsanitize-coverage=edge,trace-bb foo.cc
|
|
|
- % ASAN_OPTIONS=coverage=1 ./a.out
|
|
|
-
|
|
|
-This will produce two files after the process exit:
|
|
|
-`trace-points.PID.sancov` and `trace-events.PID.sancov`.
|
|
|
-The first file will contain a textual description of all the instrumented points in the program
|
|
|
-in the form that you can feed into llvm-symbolizer (e.g. `a.out 0x4dca89`), one per line.
|
|
|
-The second file will contain the actual execution trace as a sequence of 4-byte integers
|
|
|
--- these integers are the indices into the array of instrumented points (the first file).
|
|
|
-
|
|
|
-Basic block tracing is currently supported only for single-threaded applications.
|
|
|
-
|
|
|
-
|
|
|
Tracing PCs
|
|
|
===========
|
|
|
|
|
@@ -507,62 +396,3 @@ memory-mapped file as soon as it collected.
|
|
|
Note that on 64-bit platforms, this method writes 2x more data than the default,
|
|
|
because it stores full PC values instead of 32-bit offsets.
|
|
|
|
|
|
-In-process fuzzing
|
|
|
-==================
|
|
|
-
|
|
|
-Coverage data could be useful for fuzzers and sometimes it is preferable to run
|
|
|
-a fuzzer in the same process as the code being fuzzed (in-process fuzzer).
|
|
|
-
|
|
|
-You can use ``__sanitizer_get_total_unique_coverage()`` from
|
|
|
-``<sanitizer/coverage_interface.h>`` which returns the number of currently
|
|
|
-covered entities in the program. This will tell the fuzzer if the coverage has
|
|
|
-increased after testing every new input.
|
|
|
-
|
|
|
-If a fuzzer finds a bug in the ASan run, you will need to save the reproducer
|
|
|
-before exiting the process. Use ``__asan_set_death_callback`` from
|
|
|
-``<sanitizer/asan_interface.h>`` to do that.
|
|
|
-
|
|
|
-An example of such fuzzer can be found in `the LLVM tree
|
|
|
-<http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/README.txt?view=markup>`_.
|
|
|
-
|
|
|
-Performance
|
|
|
-===========
|
|
|
-
|
|
|
-This coverage implementation is **fast**. With function-level coverage
|
|
|
-(``-fsanitize-coverage=func``) the overhead is not measurable. With
|
|
|
-basic-block-level coverage (``-fsanitize-coverage=bb``) the overhead varies
|
|
|
-between 0 and 25%.
|
|
|
-
|
|
|
-============== ========= ========= ========= ========= ========= =========
|
|
|
- benchmark cov0 cov1 diff 0-1 cov2 diff 0-2 diff 1-2
|
|
|
-============== ========= ========= ========= ========= ========= =========
|
|
|
- 400.perlbench 1296.00 1307.00 1.01 1465.00 1.13 1.12
|
|
|
- 401.bzip2 858.00 854.00 1.00 1010.00 1.18 1.18
|
|
|
- 403.gcc 613.00 617.00 1.01 683.00 1.11 1.11
|
|
|
- 429.mcf 605.00 582.00 0.96 610.00 1.01 1.05
|
|
|
- 445.gobmk 896.00 880.00 0.98 1050.00 1.17 1.19
|
|
|
- 456.hmmer 892.00 892.00 1.00 918.00 1.03 1.03
|
|
|
- 458.sjeng 995.00 1009.00 1.01 1217.00 1.22 1.21
|
|
|
-462.libquantum 497.00 492.00 0.99 534.00 1.07 1.09
|
|
|
- 464.h264ref 1461.00 1467.00 1.00 1543.00 1.06 1.05
|
|
|
- 471.omnetpp 575.00 590.00 1.03 660.00 1.15 1.12
|
|
|
- 473.astar 658.00 652.00 0.99 715.00 1.09 1.10
|
|
|
- 483.xalancbmk 471.00 491.00 1.04 582.00 1.24 1.19
|
|
|
- 433.milc 616.00 627.00 1.02 627.00 1.02 1.00
|
|
|
- 444.namd 602.00 601.00 1.00 654.00 1.09 1.09
|
|
|
- 447.dealII 630.00 634.00 1.01 653.00 1.04 1.03
|
|
|
- 450.soplex 365.00 368.00 1.01 395.00 1.08 1.07
|
|
|
- 453.povray 427.00 434.00 1.02 495.00 1.16 1.14
|
|
|
- 470.lbm 357.00 375.00 1.05 370.00 1.04 0.99
|
|
|
- 482.sphinx3 927.00 928.00 1.00 1000.00 1.08 1.08
|
|
|
-============== ========= ========= ========= ========= ========= =========
|
|
|
-
|
|
|
-Why another coverage?
|
|
|
-=====================
|
|
|
-
|
|
|
-Why did we implement yet another code coverage?
|
|
|
- * We needed something that is lightning fast, plays well with
|
|
|
- AddressSanitizer, and does not significantly increase the binary size.
|
|
|
- * Traditional coverage implementations based in global counters
|
|
|
- `suffer from contention on counters
|
|
|
- <https://groups.google.com/forum/#!topic/llvm-dev/cDqYgnxNEhY>`_.
|