OpenBSD manual page server

Manual Page Search Parameters

KCOV(4) Device Drivers Manual KCOV(4)

kcovkernel code coverage tracing

pseudo-device kcov 1


#include <sys/kcov.h>

The kcov driver implements collection of code coverage inside the kernel. It can be enabled on a per thread basis from userland, 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:

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.
void
Enable code coverage tracing for the current thread.
void
Disable code coverage tracing for the current thread.

/dev/kcov
Default device node.

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;

	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");

	if (ioctl(fd, KIOENABLE) == -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;
}

files.conf(5)

The kcov driver first appeared in OpenBSD 6.4.

The kcov driver was written by Anton Lindqvist <anton@openbsd.org>.

The kcov driver is limited to architectures using clang(1) as their default compiler.

September 30, 2018 OpenBSD-6.4