Commit c512ac01 authored by Victor Chibotaru's avatar Victor Chibotaru Committed by Linus Torvalds
Browse files

kcov: update documentation

The updated documentation describes new KCOV mode for collecting
comparison operands.


Signed-off-by: default avatarVictor Chibotaru <>
Signed-off-by: default avatarAlexander Potapenko <>
Cc: Dmitry Vyukov <>
Cc: Andrey Konovalov <>
Cc: Mark Rutland <>
Cc: Alexander Popov <>
Cc: Andrey Ryabinin <>
Cc: Kees Cook <>
Cc: Vegard Nossum <>
Cc: Quentin Casasnovas <>
Cc: <>
Signed-off-by: default avatarAndrew Morton <>
Signed-off-by: default avatarLinus Torvalds <>
parent d677a4d6
......@@ -12,19 +12,30 @@ To achieve this goal it does not collect coverage in soft/hard interrupts
and instrumentation of some inherently non-deterministic parts of kernel is
disabled (e.g. scheduler, locking).
kcov is also able to collect comparison operands from the instrumented code
(this feature currently requires that the kernel is compiled with clang).
Configure the kernel with::
CONFIG_KCOV requires gcc built on revision 231296 or later.
If the comparison operands need to be collected, set::
Profiling data will only become accessible once debugfs has been mounted::
mount -t debugfs none /sys/kernel/debug
The following program demonstrates kcov usage from within a test program:
Coverage collection
The following program demonstrates coverage collection from within a test
program using kcov:
.. code-block:: c
......@@ -44,6 +55,9 @@ The following program demonstrates kcov usage from within a test program:
#define KCOV_DISABLE _IO('c', 101)
#define COVER_SIZE (64<<10)
#define KCOV_TRACE_PC 0
#define KCOV_TRACE_CMP 1
int main(int argc, char **argv)
int fd;
......@@ -64,7 +78,7 @@ The following program demonstrates kcov usage from within a test program:
if ((void*)cover == MAP_FAILED)
perror("mmap"), exit(1);
/* Enable coverage collection on the current thread. */
if (ioctl(fd, KCOV_ENABLE, 0))
if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_PC))
perror("ioctl"), exit(1);
/* Reset coverage from the tail of the ioctl() call. */
__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
......@@ -111,3 +125,80 @@ The interface is fine-grained to allow efficient forking of test processes.
That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode,
mmaps coverage buffer and then forks child processes in a loop. Child processes
only need to enable coverage (disable happens automatically on thread end).
Comparison operands collection
Comparison operands collection is similar to coverage collection:
.. code-block:: c
/* Same includes and defines as above. */
/* Number of 64-bit words per record. */
* The format for the types of collected comparisons.
* Bit 0 shows whether one of the arguments is a compile-time constant.
* Bits 1 & 2 contain log2 of the argument size, up to 8 bytes.
#define KCOV_CMP_CONST (1 << 0)
#define KCOV_CMP_SIZE(n) ((n) << 1)
int main(int argc, char **argv)
int fd;
uint64_t *cover, type, arg1, arg2, is_const, size;
unsigned long n, i;
fd = open("/sys/kernel/debug/kcov", O_RDWR);
if (fd == -1)
perror("open"), exit(1);
perror("ioctl"), exit(1);
* Note that the buffer pointer is of type uint64_t*, because all
* the comparison operands are promoted to uint64_t.
cover = (uint64_t *)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
if ((void*)cover == MAP_FAILED)
perror("mmap"), exit(1);
/* Note KCOV_TRACE_CMP instead of KCOV_TRACE_PC. */
perror("ioctl"), exit(1);
__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
read(-1, NULL, 0);
/* Read number of comparisons collected. */
n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
for (i = 0; i < n; i++) {
type = cover[i * KCOV_WORDS_PER_CMP + 1];
/* arg1 and arg2 - operands of the comparison. */
arg1 = cover[i * KCOV_WORDS_PER_CMP + 2];
arg2 = cover[i * KCOV_WORDS_PER_CMP + 3];
/* ip - caller address. */
ip = cover[i * KCOV_WORDS_PER_CMP + 4];
/* size of the operands. */
size = 1 << ((type & KCOV_CMP_MASK) >> 1);
/* is_const - true if either operand is a compile-time constant.*/
is_const = type & KCOV_CMP_CONST;
printf("ip: 0x%lx type: 0x%lx, arg1: 0x%lx, arg2: 0x%lx, "
"size: %lu, %s\n",
ip, type, arg1, arg2, size,
is_const ? "const" : "non-const");
if (ioctl(fd, KCOV_DISABLE, 0))
perror("ioctl"), exit(1);
/* Free resources. */
if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
perror("munmap"), exit(1);
if (close(fd))
perror("close"), exit(1);
return 0;
Note that the kcov modes (coverage collection or comparison operands) are
mutually exclusive.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment