[libc] Deprecate LLVM_ENABLE_PROJECTS in favor of LLVM_ENABLE_RUNTIMES. (#117265)
[llvm-project.git] / clang / docs / SanitizerCoverage.rst
blob6ea1d14829005c7acdd9de7c7b139b225ab6a90b
1 =================
2 SanitizerCoverage
3 =================
5 .. contents::
6    :local:
8 Introduction
9 ============
11 LLVM has a simple code coverage instrumentation built in (SanitizerCoverage).
12 It inserts calls to user-defined functions on function-, basic-block-, and edge- levels.
13 Default implementations of those callbacks are provided and implement
14 simple coverage reporting and visualization,
15 however if you need *just* coverage visualization you may want to use
16 :doc:`SourceBasedCodeCoverage <SourceBasedCodeCoverage>` instead.
18 Tracing PCs with guards
19 =======================
21 With ``-fsanitize-coverage=trace-pc-guard`` the compiler will insert the following code
22 on every edge:
24 .. code-block:: none
26    __sanitizer_cov_trace_pc_guard(&guard_variable)
28 Every edge will have its own `guard_variable` (uint32_t).
30 The compiler will also insert calls to a module constructor:
32 .. code-block:: c++
34    // The guards are [start, stop).
35    // This function will be called at least once per DSO and may be called
36    // more than once with the same values of start/stop.
37    __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop);
39 With an additional ``...=trace-pc,indirect-calls`` flag
40 ``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
42 The functions `__sanitizer_cov_trace_pc_*` should be defined by the user.
44 Example:
46 .. code-block:: c++
48   // trace-pc-guard-cb.cc
49   #include <stdint.h>
50   #include <stdio.h>
51   #include <sanitizer/coverage_interface.h>
53   // This callback is inserted by the compiler as a module constructor
54   // into every DSO. 'start' and 'stop' correspond to the
55   // beginning and end of the section with the guards for the entire
56   // binary (executable or DSO). The callback will be called at least
57   // once per DSO and may be called multiple times with the same parameters.
58   extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
59                                                       uint32_t *stop) {
60     static uint64_t N;  // Counter for the guards.
61     if (start == stop || *start) return;  // Initialize only once.
62     printf("INIT: %p %p\n", start, stop);
63     for (uint32_t *x = start; x < stop; x++)
64       *x = ++N;  // Guards should start from 1.
65   }
67   // This callback is inserted by the compiler on every edge in the
68   // control flow (some optimizations apply).
69   // Typically, the compiler will emit the code like this:
70   //    if(*guard)
71   //      __sanitizer_cov_trace_pc_guard(guard);
72   // But for large functions it will emit a simple call:
73   //    __sanitizer_cov_trace_pc_guard(guard);
74   extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
75     if (!*guard) return;  // Duplicate the guard check.
76     // If you set *guard to 0 this code will not be called again for this edge.
77     // Now you can get the PC and do whatever you want:
78     //   store it somewhere or symbolize it and print right away.
79     // The values of `*guard` are as you set them in
80     // __sanitizer_cov_trace_pc_guard_init and so you can make them consecutive
81     // and use them to dereference an array or a bit vector.
82     void *PC = __builtin_return_address(0);
83     char PcDescr[1024];
84     // This function is a part of the sanitizer run-time.
85     // To use it, link with AddressSanitizer or other sanitizer.
86     __sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr));
87     printf("guard: %p %x PC %s\n", guard, *guard, PcDescr);
88   }
90 .. code-block:: c++
92   // trace-pc-guard-example.cc
93   void foo() { }
94   int main(int argc, char **argv) {
95     if (argc > 1) foo();
96   }
98 .. code-block:: console
100   clang++ -g  -fsanitize-coverage=trace-pc-guard trace-pc-guard-example.cc -c
101   clang++ trace-pc-guard-cb.cc trace-pc-guard-example.o -fsanitize=address
102   ASAN_OPTIONS=strip_path_prefix=`pwd`/ ./a.out
104 .. code-block:: console
106   INIT: 0x71bcd0 0x71bce0
107   guard: 0x71bcd4 2 PC 0x4ecd5b in main trace-pc-guard-example.cc:2
108   guard: 0x71bcd8 3 PC 0x4ecd9e in main trace-pc-guard-example.cc:3:7
110 .. code-block:: console
112   ASAN_OPTIONS=strip_path_prefix=`pwd`/ ./a.out with-foo
115 .. code-block:: console
117   INIT: 0x71bcd0 0x71bce0
118   guard: 0x71bcd4 2 PC 0x4ecd5b in main trace-pc-guard-example.cc:3
119   guard: 0x71bcdc 4 PC 0x4ecdc7 in main trace-pc-guard-example.cc:4:17
120   guard: 0x71bcd0 1 PC 0x4ecd20 in foo() trace-pc-guard-example.cc:2:14
122 Inline 8bit-counters
123 ====================
125 **Experimental, may change or disappear in future**
127 With ``-fsanitize-coverage=inline-8bit-counters`` the compiler will insert
128 inline counter increments on every edge.
129 This is similar to ``-fsanitize-coverage=trace-pc-guard`` but instead of a
130 callback the instrumentation simply increments a counter.
132 Users need to implement a single function to capture the counters at startup.
134 .. code-block:: c++
136   extern "C"
137   void __sanitizer_cov_8bit_counters_init(char *start, char *end) {
138     // [start,end) is the array of 8-bit counters created for the current DSO.
139     // Capture this array in order to read/modify the counters.
140   }
143 Inline bool-flag
144 ================
146 **Experimental, may change or disappear in future**
148 With ``-fsanitize-coverage=inline-bool-flag`` the compiler will insert
149 setting an inline boolean to true on every edge.
150 This is similar to ``-fsanitize-coverage=inline-8bit-counter`` but instead of
151 an increment of a counter, it just sets a boolean to true.
153 Users need to implement a single function to capture the flags at startup.
155 .. code-block:: c++
157   extern "C"
158   void __sanitizer_cov_bool_flag_init(bool *start, bool *end) {
159     // [start,end) is the array of boolean flags created for the current DSO.
160     // Capture this array in order to read/modify the flags.
161   }
164 PC-Table
165 ========
167 **Experimental, may change or disappear in future**
169 **Note:** this instrumentation might be incompatible with dead code stripping
170 (``-Wl,-gc-sections``) for linkers other than LLD, thus resulting in a
171 significant binary size overhead. For more information, see
172 `Bug 34636 <https://bugs.llvm.org/show_bug.cgi?id=34636>`_.
174 With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
175 instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters``,
176 or ``-fsanitize-coverage=inline-bool-flag``, or ``-fsanitize-coverage=trace-pc-guard``.
178 Users need to implement a single function to capture the PC table at startup:
180 .. code-block:: c++
182   extern "C"
183   void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
184                                 const uintptr_t *pcs_end) {
185     // [pcs_beg,pcs_end) is the array of ptr-sized integers representing
186     // pairs [PC,PCFlags] for every instrumented block in the current DSO.
187     // Capture this array in order to read the PCs and their Flags.
188     // The number of PCs and PCFlags for a given DSO is the same as the number
189     // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters), or
190     // boolean flags (-fsanitize-coverage=inline=bool-flags), or trace_pc_guard
191     // callbacks (-fsanitize-coverage=trace-pc-guard).
192     // A PCFlags describes the basic block:
193     //  * bit0: 1 if the block is the function entry block, 0 otherwise.
194   }
197 Tracing PCs
198 ===========
200 With ``-fsanitize-coverage=trace-pc`` the compiler will insert
201 ``__sanitizer_cov_trace_pc()`` on every edge.
202 With an additional ``...=trace-pc,indirect-calls`` flag
203 ``__sanitizer_cov_trace_pc_indirect(void *callee)`` will be inserted on every indirect call.
204 These callbacks are not implemented in the Sanitizer run-time and should be defined
205 by the user.
206 This mechanism is used for fuzzing the Linux kernel
207 (https://github.com/google/syzkaller).
209 Instrumentation points
210 ======================
211 Sanitizer Coverage offers different levels of instrumentation.
213 * ``edge`` (default): edges are instrumented (see below).
214 * ``bb``: basic blocks are instrumented.
215 * ``func``: only the entry block of every function will be instrumented.
217 Use these flags together with ``trace-pc-guard`` or ``trace-pc``,
218 like this: ``-fsanitize-coverage=func,trace-pc-guard``.
220 When ``edge`` or ``bb`` is used, some of the edges/blocks may still be left
221 uninstrumented (pruned) if such instrumentation is considered redundant.
222 Use ``no-prune`` (e.g. ``-fsanitize-coverage=bb,no-prune,trace-pc-guard``)
223 to disable pruning. This could be useful for better coverage visualization.
226 Edge coverage
227 -------------
229 Consider this code:
231 .. code-block:: c++
233     void foo(int *a) {
234       if (a)
235         *a = 0;
236     }
238 It contains 3 basic blocks, let's name them A, B, C:
240 .. code-block:: none
242     A
243     |\
244     | \
245     |  B
246     | /
247     |/
248     C
250 If blocks A, B, and C are all covered we know for certain that the edges A=>B
251 and B=>C were executed, but we still don't know if the edge A=>C was executed.
252 Such edges of control flow graph are called
253 `critical <https://en.wikipedia.org/wiki/Control_flow_graph#Special_edges>`_.
254 The edge-level coverage simply splits all critical edges by introducing new
255 dummy blocks and then instruments those blocks:
257 .. code-block:: none
259     A
260     |\
261     | \
262     D  B
263     | /
264     |/
265     C
267 Tracing data flow
268 =================
270 Support for data-flow-guided fuzzing.
271 With ``-fsanitize-coverage=trace-cmp`` the compiler will insert extra instrumentation
272 around comparison instructions and switch statements.
273 Similarly, with ``-fsanitize-coverage=trace-div`` the compiler will instrument
274 integer division instructions (to capture the right argument of division)
275 and with  ``-fsanitize-coverage=trace-gep`` --
276 the `LLVM GEP instructions <https://llvm.org/docs/GetElementPtr.html>`_
277 (to capture array indices).
278 Similarly, with ``-fsanitize-coverage=trace-loads`` and ``-fsanitize-coverage=trace-stores``
279 the compiler will instrument loads and stores, respectively.
281 Currently, these flags do not work by themselves - they require one
282 of ``-fsanitize-coverage={trace-pc,inline-8bit-counters,inline-bool}``
283 flags to work.
285 Unless ``no-prune`` option is provided, some of the comparison instructions
286 will not be instrumented.
288 .. code-block:: c++
290   // Called before a comparison instruction.
291   // Arg1 and Arg2 are arguments of the comparison.
292   void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2);
293   void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2);
294   void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2);
295   void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2);
297   // Called before a comparison instruction if exactly one of the arguments is constant.
298   // Arg1 and Arg2 are arguments of the comparison, Arg1 is a compile-time constant.
299   // These callbacks are emitted by -fsanitize-coverage=trace-cmp since 2017-08-11
300   void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2);
301   void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2);
302   void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2);
303   void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2);
305   // Called before a switch statement.
306   // Val is the switch operand.
307   // Cases[0] is the number of case constants.
308   // Cases[1] is the size of Val in bits.
309   // Cases[2:] are the case constants.
310   void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases);
312   // Called before a division statement.
313   // Val is the second argument of division.
314   void __sanitizer_cov_trace_div4(uint32_t Val);
315   void __sanitizer_cov_trace_div8(uint64_t Val);
317   // Called before a GetElemementPtr (GEP) instruction
318   // for every non-constant array index.
319   void __sanitizer_cov_trace_gep(uintptr_t Idx);
321   // Called before a load of appropriate size. Addr is the address of the load.
322   void __sanitizer_cov_load1(uint8_t *addr);
323   void __sanitizer_cov_load2(uint16_t *addr);
324   void __sanitizer_cov_load4(uint32_t *addr);
325   void __sanitizer_cov_load8(uint64_t *addr);
326   void __sanitizer_cov_load16(__int128 *addr);
327   // Called before a store of appropriate size. Addr is the address of the store.
328   void __sanitizer_cov_store1(uint8_t *addr);
329   void __sanitizer_cov_store2(uint16_t *addr);
330   void __sanitizer_cov_store4(uint32_t *addr);
331   void __sanitizer_cov_store8(uint64_t *addr);
332   void __sanitizer_cov_store16(__int128 *addr);
335 Tracing control flow
336 ====================
338 With ``-fsanitize-coverage=control-flow`` the compiler will create a table to collect
339 control flow for each function. More specifically, for each basic block in the function,
340 two lists are populated. One list for successors of the basic block and another list for
341 non-intrinsic called functions.
343 **TODO:** in the current implementation, indirect calls are not tracked
344 and are only marked with special value (-1) in the list.
346 Each table row consists of the basic block address
347 followed by ``null``-ended lists of successors and callees.
348 The table is encoded in a special section named ``sancov_cfs``
350 Example:
352 .. code-block:: c++
354   int foo (int x) {
355     if (x > 0)
356       bar(x);
357     else
358       x = 0;
359     return x;
360   }
362 The code above contains 4 basic blocks, let's name them A, B, C, D:
364 .. code-block:: none
366     A
367     |\
368     | \
369     B  C
370     | /
371     |/
372     D
374 The collected control flow table is as follows:
375 ``A, B, C, null, null, B, D, null, @bar, null, C, D, null, null, D, null, null.``
377 Users need to implement a single function to capture the CF table at startup:
379 .. code-block:: c++
381   extern "C"
382   void __sanitizer_cov_cfs_init(const uintptr_t *cfs_beg,
383                                 const uintptr_t *cfs_end) {
384     // [cfs_beg,cfs_end) is the array of ptr-sized integers representing
385     // the collected control flow.
386   }
388 Gated Trace Callbacks
389 =====================
391 Gate the invocation of the tracing callbacks with
392 ``-sanitizer-coverage-gated-trace-callbacks``.
394 When this option is enabled, the instrumentation will not call into the
395 runtime-provided callbacks for tracing, thus only incurring in a trivial
396 branch without going through a function call.
398 It is up to the runtime to toggle the value of the global variable in order to
399 enable tracing.
401 This option is only supported for trace-pc-guard and trace-cmp.
403 Disabling instrumentation with ``__attribute__((no_sanitize("coverage")))``
404 ===========================================================================
406 It is possible to disable coverage instrumentation for select functions via the
407 function attribute ``__attribute__((no_sanitize("coverage")))``. Because this
408 attribute may not be supported by other compilers, it is recommended to use it
409 together with ``__has_feature(coverage_sanitizer)``.
411 Disabling instrumentation without source modification
412 =====================================================
414 It is sometimes useful to tell SanitizerCoverage to instrument only a subset of the
415 functions in your target without modifying source files.
416 With ``-fsanitize-coverage-allowlist=allowlist.txt``
417 and ``-fsanitize-coverage-ignorelist=blocklist.txt``,
418 you can specify such a subset through the combination of an allowlist and a blocklist.
420 SanitizerCoverage will only instrument functions that satisfy two conditions.
421 First, the function should belong to a source file with a path that is both allowlisted
422 and not blocklisted.
423 Second, the function should have a mangled name that is both allowlisted and not blocklisted.
425 The allowlist and blocklist format is similar to that of the sanitizer blocklist format.
426 The default allowlist will match every source file and every function.
427 The default blocklist will match no source file and no function.
429 A common use case is to have the allowlist list folders or source files for which you want
430 instrumentation and allow all function names, while the blocklist will opt out some specific
431 files or functions that the allowlist loosely allowed.
433 Here is an example allowlist:
435 .. code-block:: none
437   # Enable instrumentation for a whole folder
438   src:bar/*
439   # Enable instrumentation for a specific source file
440   src:foo/a.cpp
441   # Enable instrumentation for all functions in those files
442   fun:*
444 And an example blocklist:
446 .. code-block:: none
448   # Disable instrumentation for a specific source file that the allowlist allowed
449   src:bar/b.cpp
450   # Disable instrumentation for a specific function that the allowlist allowed
451   fun:*myFunc*
453 The use of ``*`` wildcards above is required because function names are matched after mangling.
454 Without the wildcards, one would have to write the whole mangled name.
456 Be careful that the paths of source files are matched exactly as they are provided on the clang
457 command line.
458 For example, the allowlist above would include file ``bar/b.cpp`` if the path was provided
459 exactly like this, but would it would fail to include it with other ways to refer to the same
460 file such as ``./bar/b.cpp``, or ``bar\b.cpp`` on Windows.
461 So, please make sure to always double check that your lists are correctly applied.
463 Default implementation
464 ======================
466 The sanitizer run-time (AddressSanitizer, MemorySanitizer, etc) provide a
467 default implementations of some of the coverage callbacks.
468 You may use this implementation to dump the coverage on disk at the process
469 exit.
471 Example:
473 .. code-block:: console
475     % cat -n cov.cc
476          1  #include <stdio.h>
477          2  __attribute__((noinline))
478          3  void foo() { printf("foo\n"); }
479          4
480          5  int main(int argc, char **argv) {
481          6    if (argc == 2)
482          7      foo();
483          8    printf("main\n");
484          9  }
485     % clang++ -g cov.cc -fsanitize=address -fsanitize-coverage=trace-pc-guard
486     % ASAN_OPTIONS=coverage=1 ./a.out; wc -c *.sancov
487     main
488     SanitizerCoverage: ./a.out.7312.sancov 2 PCs written
489     24 a.out.7312.sancov
490     % ASAN_OPTIONS=coverage=1 ./a.out foo ; wc -c *.sancov
491     foo
492     main
493     SanitizerCoverage: ./a.out.7316.sancov 3 PCs written
494     24 a.out.7312.sancov
495     32 a.out.7316.sancov
497 Every time you run an executable instrumented with SanitizerCoverage
498 one ``*.sancov`` file is created during the process shutdown.
499 If the executable is dynamically linked against instrumented DSOs,
500 one ``*.sancov`` file will be also created for every DSO.
502 Sancov data format
503 ------------------
505 The format of ``*.sancov`` files is very simple: the first 8 bytes is the magic,
506 one of ``0xC0BFFFFFFFFFFF64`` and ``0xC0BFFFFFFFFFFF32``. The last byte of the
507 magic defines the size of the following offsets. The rest of the data is the
508 offsets in the corresponding binary/DSO that were executed during the run.
510 Sancov Tool
511 -----------
513 A simple ``sancov`` tool is provided to process coverage files.
514 The tool is part of LLVM project and is currently supported only on Linux.
515 It can handle symbolization tasks autonomously without any extra support
516 from the environment. You need to pass .sancov files (named
517 ``<module_name>.<pid>.sancov`` and paths to all corresponding binary elf files.
518 Sancov matches these files using module names and binaries file names.
520 .. code-block:: console
522     USAGE: sancov [options] <action> (<binary file>|<.sancov file>)...
524     Action (required)
525       -print                    - Print coverage addresses
526       -covered-functions        - Print all covered functions.
527       -not-covered-functions    - Print all not covered functions.
528       -symbolize                - Symbolizes the report.
530     Options
531       -blocklist=<string>         - Blocklist file (sanitizer blocklist format).
532       -demangle                   - Print demangled function name.
533       -strip_path_prefix=<string> - Strip this prefix from file paths in reports
536 Coverage Reports
537 ----------------
539 **Experimental**
541 ``.sancov`` files do not contain enough information to generate a source-level
542 coverage report. The missing information is contained
543 in debug info of the binary. Thus the ``.sancov`` has to be symbolized
544 to produce a ``.symcov`` file first:
546 .. code-block:: console
548     sancov -symbolize my_program.123.sancov my_program > my_program.123.symcov
550 The ``.symcov`` file can be browsed overlaid over the source code by
551 running ``tools/sancov/coverage-report-server.py`` script that will start
552 an HTTP server.
554 Output directory
555 ----------------
557 By default, .sancov files are created in the current working directory.
558 This can be changed with ``ASAN_OPTIONS=coverage_dir=/path``:
560 .. code-block:: console
562     % ASAN_OPTIONS="coverage=1:coverage_dir=/tmp/cov" ./a.out foo
563     % ls -l /tmp/cov/*sancov
564     -rw-r----- 1 kcc eng 4 Nov 27 12:21 a.out.22673.sancov
565     -rw-r----- 1 kcc eng 8 Nov 27 12:21 a.out.22679.sancov