xref: /freebsd/share/man/man4/kcov.4 (revision 7d604fb5f37695f017c85c413d7cfd3e969dc7f8)
1*7d604fb5SMark Johnston.\"-
2*7d604fb5SMark Johnston.\" Copyright (c) 2020 The FreeBSD Foundation
3*7d604fb5SMark Johnston.\"
4*7d604fb5SMark Johnston.\" This documentation was written by Mark Johnston under sponsorship from
5*7d604fb5SMark Johnston.\" the FreeBSD Foundation.
6*7d604fb5SMark Johnston.\"
7*7d604fb5SMark Johnston.\" Redistribution and use in source and binary forms, with or without
8*7d604fb5SMark Johnston.\" modification, are permitted provided that the following conditions
9*7d604fb5SMark Johnston.\" are met:
10*7d604fb5SMark Johnston.\" 1. Redistributions of source code must retain the above copyright
11*7d604fb5SMark Johnston.\"    notice, this list of conditions and the following disclaimer.
12*7d604fb5SMark Johnston.\" 2. Redistributions in binary form must reproduce the above copyright
13*7d604fb5SMark Johnston.\"    notice, this list of conditions and the following disclaimer in the
14*7d604fb5SMark Johnston.\"    documentation and/or other materials provided with the distribution.
15*7d604fb5SMark Johnston.\"
16*7d604fb5SMark Johnston.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*7d604fb5SMark Johnston.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*7d604fb5SMark Johnston.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*7d604fb5SMark Johnston.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*7d604fb5SMark Johnston.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*7d604fb5SMark Johnston.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*7d604fb5SMark Johnston.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*7d604fb5SMark Johnston.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*7d604fb5SMark Johnston.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*7d604fb5SMark Johnston.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*7d604fb5SMark Johnston.\" SUCH DAMAGE.
27*7d604fb5SMark Johnston.\"
28*7d604fb5SMark Johnston.\" $FreeBSD$
29*7d604fb5SMark Johnston.\"
30*7d604fb5SMark Johnston.Dd August 18, 2020
31*7d604fb5SMark Johnston.Dt KCOV 4
32*7d604fb5SMark Johnston.Os
33*7d604fb5SMark Johnston.Sh NAME
34*7d604fb5SMark Johnston.Nm kcov
35*7d604fb5SMark Johnston.Nd interface for collecting kernel code coverage information
36*7d604fb5SMark Johnston.Sh SYNOPSIS
37*7d604fb5SMark JohnstonTo compile KCOV into the kernel, place the following lines in your kernel
38*7d604fb5SMark Johnstonconfiguration file:
39*7d604fb5SMark Johnston.Bd -ragged -offset indent
40*7d604fb5SMark Johnston.Cd "options COVERAGE"
41*7d604fb5SMark Johnston.Cd "options KCOV"
42*7d604fb5SMark Johnston.Ed
43*7d604fb5SMark Johnston.Pp
44*7d604fb5SMark JohnstonThe following header file defines the application interface provided
45*7d604fb5SMark Johnstonby KCOV:
46*7d604fb5SMark Johnston.Pp
47*7d604fb5SMark Johnston.In sys/kcov.h
48*7d604fb5SMark Johnston.Sh DESCRIPTION
49*7d604fb5SMark Johnston.Nm
50*7d604fb5SMark Johnstonis a module that enables collection of code coverage information from the
51*7d604fb5SMark Johnstonkernel.
52*7d604fb5SMark JohnstonIt relies on code instrumentation enabled by the
53*7d604fb5SMark Johnston.Dv COVERAGE
54*7d604fb5SMark Johnstonkernel option.
55*7d604fb5SMark JohnstonWhen
56*7d604fb5SMark Johnston.Nm
57*7d604fb5SMark Johnstonis enabled by a user-mode thread, it collects coverage information only for
58*7d604fb5SMark Johnstonthat thread, excluding hard interrupt handlers.
59*7d604fb5SMark JohnstonAs a result,
60*7d604fb5SMark Johnston.Nm
61*7d604fb5SMark Johnstonis not suited to collect comprehensive coverage data for the entire kernel;
62*7d604fb5SMark Johnstonits main purpose is to provide input for coverage-guided system call fuzzers.
63*7d604fb5SMark Johnston.Pp
64*7d604fb5SMark JohnstonIn typical usage, a user-mode thread first allocates a chunk of memory to be
65*7d604fb5SMark Johnstonshared with
66*7d604fb5SMark Johnston.Nm .
67*7d604fb5SMark JohnstonThe thread then enables coverage tracing, with coverage data being written by
68*7d604fb5SMark Johnstonthe kernel to the shared memory region.
69*7d604fb5SMark JohnstonWhen tracing is disabled, the kernel relinquishes its access to the shared
70*7d604fb5SMark Johnstonmemory region, and the written coverage data may be consumed.
71*7d604fb5SMark Johnston.Pp
72*7d604fb5SMark JohnstonThe shared memory buffer can be treated as a 64-bit unsigned integer followed
73*7d604fb5SMark Johnstonby an array of records.
74*7d604fb5SMark JohnstonThe integer records the number of valid records and is updated by the kernel as
75*7d604fb5SMark Johnstoncoverage information is recorded.
76*7d604fb5SMark JohnstonThe state of the tracing buffer can be reset by writing the value 0 to this
77*7d604fb5SMark Johnstonfield.
78*7d604fb5SMark JohnstonThe record layout depends on the tracing mode set using the
79*7d604fb5SMark Johnston.Dv KIOENABLE
80*7d604fb5SMark Johnstonioctl.
81*7d604fb5SMark Johnston.Pp
82*7d604fb5SMark JohnstonTwo tracing modes are implemented,
83*7d604fb5SMark Johnston.Dv KCOV_MODE_TRACE_PC
84*7d604fb5SMark Johnstonand
85*7d604fb5SMark Johnston.Dv KCOV_MODE_TRACE_CMP .
86*7d604fb5SMark JohnstonPC-tracing records a program counter value for each basic block executed while
87*7d604fb5SMark Johnstontracing is enabled.
88*7d604fb5SMark JohnstonIn this mode, each record is a single 64-bit unsigned integer containing the
89*7d604fb5SMark Johnstonprogram counter value.
90*7d604fb5SMark JohnstonComparison tracing provides information about data flow; information about
91*7d604fb5SMark Johnstondynamic variable comparisons is recorded.
92*7d604fb5SMark JohnstonSuch records provide information about the results of
93*7d604fb5SMark Johnston.Xr c 7
94*7d604fb5SMark Johnston.Ql if
95*7d604fb5SMark Johnstonor
96*7d604fb5SMark Johnston.Ql switch
97*7d604fb5SMark Johnstonstatements, for example.
98*7d604fb5SMark JohnstonIn this mode each record consists of four 64-bit unsigned integers.
99*7d604fb5SMark JohnstonThe first integer is a bitmask defining attributes of the variables involved in
100*7d604fb5SMark Johnstonthe comparison.
101*7d604fb5SMark Johnston.Dv KCOV_CMP_CONST
102*7d604fb5SMark Johnstonis set if one of the variables has a constant value at compile-time, and
103*7d604fb5SMark Johnston.Dv KCOV_CMP_SIZE(n)
104*7d604fb5SMark Johnstonspecifies the width of the variables:
105*7d604fb5SMark Johnston.Pp
106*7d604fb5SMark Johnston.Bl -inset -offset indent -compact
107*7d604fb5SMark Johnston.It Dv KCOV_CMP_SIZE(0) :
108*7d604fb5SMark Johnstona comparison of 8-bit integers
109*7d604fb5SMark Johnston.It Dv KCOV_CMP_SIZE(1) :
110*7d604fb5SMark Johnstona comparison of 16-bit integers
111*7d604fb5SMark Johnston.It Dv KCOV_CMP_SIZE(2) :
112*7d604fb5SMark Johnstona comparison of 32-bit integers
113*7d604fb5SMark Johnston.It Dv KCOV_CMP_SIZE(3) :
114*7d604fb5SMark Johnstona comparison of 64-bit integers
115*7d604fb5SMark Johnston.El
116*7d604fb5SMark Johnston.Pp
117*7d604fb5SMark JohnstonThe second and third fields record the values of the two variables, and the
118*7d604fb5SMark Johnstonfourth and final field stores the program counter value of the comparison.
119*7d604fb5SMark Johnston.Sh IOCTL INTERFACE
120*7d604fb5SMark JohnstonApplications interact with
121*7d604fb5SMark Johnston.Nm
122*7d604fb5SMark Johnstonusing the
123*7d604fb5SMark Johnston.Xr ioctl 2
124*7d604fb5SMark Johnstonsystem call.
125*7d604fb5SMark JohnstonEach thread making use of
126*7d604fb5SMark Johnston.Nm
127*7d604fb5SMark Johnstonmust use a separate file descriptor for
128*7d604fb5SMark Johnston.Fa /dev/kcov .
129*7d604fb5SMark JohnstonThe following ioctls are defined:
130*7d604fb5SMark Johnston.Bl -tag -width indent
131*7d604fb5SMark Johnston.It Dv KIOSETBUFSIZE Fa size_t entries
132*7d604fb5SMark JohnstonSet the size of the tracing buffer in units of
133*7d604fb5SMark Johnston.Dv KCOV_ENTRY_SIZE .
134*7d604fb5SMark JohnstonThe buffer may then be mapped into the calling thread's address space by
135*7d604fb5SMark Johnstoncalling
136*7d604fb5SMark Johnston.Xr mmap 2
137*7d604fb5SMark Johnstonon the
138*7d604fb5SMark Johnston.Nm
139*7d604fb5SMark Johnstondevice file.
140*7d604fb5SMark Johnston.It Dv KIOENABLE Fa int mode
141*7d604fb5SMark JohnstonEnable coverage tracing for the calling thread.
142*7d604fb5SMark JohnstonValid modes are
143*7d604fb5SMark Johnston.Dv KCOV_MODE_TRACE_PC
144*7d604fb5SMark Johnstonand
145*7d604fb5SMark Johnston.Dv KCOV_MODE_TRACE_CMP .
146*7d604fb5SMark Johnston.It Dv KIODISABLE
147*7d604fb5SMark JohnstonDisable coverage tracing for the calling thread.
148*7d604fb5SMark Johnston.El
149*7d604fb5SMark Johnston.Sh FILES
150*7d604fb5SMark Johnston.Nm
151*7d604fb5SMark Johnstoncreates the
152*7d604fb5SMark Johnston.Pa /dev/kcov
153*7d604fb5SMark Johnstondevice file.
154*7d604fb5SMark Johnston.Sh EXAMPLES
155*7d604fb5SMark JohnstonThe following code sample collects information about basic block coverage for
156*7d604fb5SMark Johnstonkernel code executed while printing
157*7d604fb5SMark Johnston.Ql "Hello, world" .
158*7d604fb5SMark Johnston.Bd -literal
159*7d604fb5SMark Johnstonsize_t sz;
160*7d604fb5SMark Johnstonuint64_t *buf;
161*7d604fb5SMark Johnstonint fd;
162*7d604fb5SMark Johnston
163*7d604fb5SMark Johnstonfd = open("/dev/kcov", O_RDWR);
164*7d604fb5SMark Johnstonif (fd == -1)
165*7d604fb5SMark Johnston	err(1, "open(/dev/kcov)");
166*7d604fb5SMark Johnstonsz = 1ul << 20; /* 1MB */
167*7d604fb5SMark Johnstonif (ioctl(fd, KIOSETBUFSIZE, sz / KCOV_ENTRY_SIZE) != 0)
168*7d604fb5SMark Johnston	err(1, "ioctl(KIOSETBUFSIZE)");
169*7d604fb5SMark Johnstonbuf = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
170*7d604fb5SMark Johnstonif (buf == MAP_FAILED)
171*7d604fb5SMark Johnston	err(1, "mmap");
172*7d604fb5SMark Johnston
173*7d604fb5SMark Johnston/* Enable PC tracing. */
174*7d604fb5SMark Johnstonif (ioctl(fd, KIOENABLE, KCOV_MODE_TRACE_PC) != 0)
175*7d604fb5SMark Johnston	err(1, "ioctl(KIOENABLE)");
176*7d604fb5SMark Johnston
177*7d604fb5SMark Johnston/* Clear trace records from the preceding ioctl() call. */
178*7d604fb5SMark Johnstonbuf[0] = 0;
179*7d604fb5SMark Johnston
180*7d604fb5SMark Johnstonprintf("Hello, world!\\n");
181*7d604fb5SMark Johnston
182*7d604fb5SMark Johnston/* Disable PC tracing. */
183*7d604fb5SMark Johnstonif (ioctl(fd, KIODISABLE, 0) != 0)
184*7d604fb5SMark Johnston	err(1, "ioctl(KIODISABLE)");
185*7d604fb5SMark Johnston
186*7d604fb5SMark Johnstonfor (uint64_t i = 1; i < buf[0]; i++)
187*7d604fb5SMark Johnston	printf("%#jx\\n", (uintmax_t)buf[i]);
188*7d604fb5SMark Johnston.Ed
189*7d604fb5SMark JohnstonThe output of this program can be approximately mapped to line numbers
190*7d604fb5SMark Johnstonin kernel source code:
191*7d604fb5SMark Johnston.Bd -literal
192*7d604fb5SMark Johnston# ./kcov-test | sed 1d | addr2line -e /usr/lib/debug/boot/kernel/kernel.debug
193*7d604fb5SMark Johnston.Ed
194*7d604fb5SMark Johnston.Sh SEE ALSO
195*7d604fb5SMark Johnston.Xr ioctl 2 ,
196*7d604fb5SMark Johnston.Xr mmap 2
197*7d604fb5SMark Johnston.Sh HISTORY
198*7d604fb5SMark Johnston.Nm
199*7d604fb5SMark Johnstonfirst appeared in
200*7d604fb5SMark Johnston.Fx 13.0 .
201*7d604fb5SMark Johnston.Sh BUGS
202*7d604fb5SMark JohnstonThe
203*7d604fb5SMark Johnston.Fx
204*7d604fb5SMark Johnstonimplementation of
205*7d604fb5SMark Johnston.Nm
206*7d604fb5SMark Johnstondoes not yet support remote tracing.
207