Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
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 userland, allowing the ker-
     nel program counter to be collected during	syscalls triggered by the same
     thread.  The collected coverage can be accessed by	mapping	the device us-
     ing 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 al-
		ways true for switch statements.  The remaining	bits repre-
		sents 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	oper-
		and 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 num-
	   ber 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	mutu-
	   ally	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	trans-
     late 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 <anton@openbsd.org>.

CAVEATS
     The kcov driver is	limited	to architectures using clang(1)	as their de-
     fault compiler.

FreeBSD	13.0		       December	8, 2020			  FreeBSD 13.0

NAME | SYNOPSIS | DESCRIPTION | FILES | EXAMPLES | SEE ALSO | HISTORY | AUTHORS | CAVEATS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=kcov&sektion=4&manpath=OpenBSD+6.9>

home | help