KCOV(4) FreeBSD Kernel Interfaces Manual KCOV(4)
NAME
kcov - kernel code coverage tracing
SYNOPSIS
pseudo-device kcov
#include <sys/kcov.h>
DESCRIPTION
The kcov driver implements collection of code coverage inside the kernel.
It can be enabled on a per thread basis from user space, allowing the
kernel program counter to be collected during syscalls triggered by the
same thread. The collected coverage can be accessed by mapping the
device using mmap(2).
By default, kcov is not enabled but instead requires the following line
to be present in the kernel configuration:
pseudo-device kcov 1
The following ioctl(2) calls are provided:
KIOSETBUFSIZE unsigned long *nentries
Allocate a coverage buffer with a capacity of nentries. The buffer
can be accessed using mmap(2), whereas the returned pointer must be
interpreted as an array of unsigned long entries. The first entry
contains the number of entries in the array, excluding the first
entry.
KIOENABLE int *mode
Enable code coverage tracing for the current thread or any remote
subsystem attached using KIOREMOTEATTACH. The mode must be one of
the following:
KCOV_MODE_TRACE_PC
Trace the kernel program counter.
KCOV_MODE_TRACE_CMP
Trace comparison instructions and switch statements. For switch
statements, the number of traced comparison instructions is equal
to the number of switch cases. Each traced comparison instruction
is represented by 4 entries in the coverage buffer:
1. A mask where the least significant bit is set if one of the
comparison operands is a compile-time constant, which is
always true for switch statements. The remaining bits
represents the log2 size of the operands, ranging from 0 to 3.
2. First comparison operand. For switch statements, this operand
corresponds to the case value.
3. Second comparison operand. For switch statements, this
operand corresponds to the value passed to switch.
4. Kernel program counter where the comparison instruction took
place.
In this mode, the first entry in the coverage buffer reflects the
number of traced comparison instructions. Thus, the effective
number of entries in the coverage buffer is given by multiplying
the first entry by 4.
KIODISABLE void
Disable code coverage tracing for the current thread.
KIOREMOTEATTACH struct kio_remote_attach *remote
Attach collection of remote coverage from other kernel threads,
identified by a subsystem. Collection of remote coverage is
mutually exclusive with coverage collection of the current thread.
The remote argument is a pointer to the following structure:
struct kio_remote_attach {
int subsystem;
int id;
};
The subsystem field must be one of the following:
KCOV_REMOTE_COMMON
Collect coverage from tasks and timeouts scheduled by the current
process, see task_add(9) and timeout(9). The id field is ignored.
FILES
/dev/kcov Default device node.
EXAMPLES
In the following example, the read(2) syscall is traced and the coverage
displayed, which in turn can be passed to addr2line(1) in order to
translate the kernel program counter into the file name and line number
it corresponds to.
#include <sys/ioctl.h>
#include <sys/kcov.h>
#include <sys/mman.h>
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(void)
{
unsigned long *cover, i;
unsigned long size = 1024;
int fd, mode;
fd = open("/dev/kcov", O_RDWR);
if (fd == -1)
err(1, "open");
if (ioctl(fd, KIOSETBUFSIZE, &size) == -1)
err(1, "ioctl: KIOSETBUFSIZE");
cover = mmap(NULL, size * sizeof(unsigned long),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (cover == MAP_FAILED)
err(1, "mmap");
mode = KCOV_MODE_TRACE_PC;
if (ioctl(fd, KIOENABLE, &mode) == -1)
err(1, "ioctl: KIOENABLE");
read(-1, NULL, 0);
if (ioctl(fd, KIODISABLE) == -1)
err(1, "ioctl: KIODISABLE");
for (i = 0; i < cover[0]; i++)
printf("%p\n", (void *)cover[i + 1]);
if (munmap(cover, size * sizeof(unsigned long)) == -1)
err(1, "munmap");
close(fd);
return 0;
}
SEE ALSO
files.conf(5), kcov_remote_register(9)
HISTORY
The kcov driver first appeared in OpenBSD 6.4.
AUTHORS
The kcov driver was written by Anton Lindqvist <
[email protected]>.
CAVEATS
The kcov driver is limited to architectures using clang(1) as their
default compiler.
FreeBSD 14.1-RELEASE-p8 December 30, 2021 FreeBSD 14.1-RELEASE-p8