2 .\" Copyright (c) 2020 The FreeBSD Foundation
4 .\" This documentation was written by Mark Johnston under sponsorship from
5 .\" the FreeBSD Foundation.
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
10 .\" 1. Redistributions of source code must retain the above copyright
11 .\" notice, this list of conditions and the following disclaimer.
12 .\" 2. Redistributions in binary form must reproduce the above copyright
13 .\" notice, this list of conditions and the following disclaimer in the
14 .\" documentation and/or other materials provided with the distribution.
16 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 .Nd interface for collecting kernel code coverage information
37 To compile KCOV into the kernel, place the following lines in your kernel
39 .Bd -ragged -offset indent
40 .Cd "options COVERAGE"
44 The following header file defines the application interface provided
50 is a module that enables collection of code coverage information from the
52 It relies on code instrumentation enabled by the
57 is enabled by a user-mode thread, it collects coverage information only for
58 that thread, excluding hard interrupt handlers.
61 is not suited to collect comprehensive coverage data for the entire kernel;
62 its main purpose is to provide input for coverage-guided system call fuzzers.
64 In typical usage, a user-mode thread first allocates a chunk of memory to be
67 The thread then enables coverage tracing, with coverage data being written by
68 the kernel to the shared memory region.
69 When tracing is disabled, the kernel relinquishes its access to the shared
70 memory region, and the written coverage data may be consumed.
72 The shared memory buffer can be treated as a 64-bit unsigned integer followed
73 by an array of records.
74 The integer records the number of valid records and is updated by the kernel as
75 coverage information is recorded.
76 The state of the tracing buffer can be reset by writing the value 0 to this
78 The record layout depends on the tracing mode set using the
82 Two tracing modes are implemented,
83 .Dv KCOV_MODE_TRACE_PC
85 .Dv KCOV_MODE_TRACE_CMP .
86 PC-tracing records a program counter value for each basic block executed while
88 In this mode, each record is a single 64-bit unsigned integer containing the
89 program counter value.
90 Comparison tracing provides information about data flow; information about
91 dynamic variable comparisons is recorded.
92 Such records provide information about the results of
97 statements, for example.
98 In this mode each record consists of four 64-bit unsigned integers.
99 The first integer is a bitmask defining attributes of the variables involved in
102 is set if one of the variables has a constant value at compile-time, and
104 specifies the width of the variables:
106 .Bl -inset -offset indent -compact
107 .It Dv KCOV_CMP_SIZE(0) :
108 a comparison of 8-bit integers
109 .It Dv KCOV_CMP_SIZE(1) :
110 a comparison of 16-bit integers
111 .It Dv KCOV_CMP_SIZE(2) :
112 a comparison of 32-bit integers
113 .It Dv KCOV_CMP_SIZE(3) :
114 a comparison of 64-bit integers
117 The second and third fields record the values of the two variables, and the
118 fourth and final field stores the program counter value of the comparison.
120 Applications interact with
125 Each thread making use of
127 must use a separate file descriptor for
129 The following ioctls are defined:
130 .Bl -tag -width indent
131 .It Dv KIOSETBUFSIZE Fa size_t entries
132 Set the size of the tracing buffer in units of
133 .Dv KCOV_ENTRY_SIZE .
134 The buffer may then be mapped into the calling thread's address space by
140 .It Dv KIOENABLE Fa int mode
141 Enable coverage tracing for the calling thread.
143 .Dv KCOV_MODE_TRACE_PC
145 .Dv KCOV_MODE_TRACE_CMP .
147 Disable coverage tracing for the calling thread.
155 The following code sample collects information about basic block coverage for
156 kernel code executed while printing
163 fd = open("/dev/kcov", O_RDWR);
165 err(1, "open(/dev/kcov)");
166 sz = 1ul << 20; /* 1MB */
167 if (ioctl(fd, KIOSETBUFSIZE, sz / KCOV_ENTRY_SIZE) != 0)
168 err(1, "ioctl(KIOSETBUFSIZE)");
169 buf = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
170 if (buf == MAP_FAILED)
173 /* Enable PC tracing. */
174 if (ioctl(fd, KIOENABLE, KCOV_MODE_TRACE_PC) != 0)
175 err(1, "ioctl(KIOENABLE)");
177 /* Clear trace records from the preceding ioctl() call. */
180 printf("Hello, world!\\n");
182 /* Disable PC tracing. */
183 if (ioctl(fd, KIODISABLE, 0) != 0)
184 err(1, "ioctl(KIODISABLE)");
186 for (uint64_t i = 1; i < buf[0]; i++)
187 printf("%#jx\\n", (uintmax_t)buf[i]);
189 The output of this program can be approximately mapped to line numbers
190 in kernel source code:
192 # ./kcov-test | sed 1d | addr2line -e /usr/lib/debug/boot/kernel/kernel.debug
206 does not yet support remote tracing.