summaryrefslogtreecommitdiffstats
path: root/Documentation/dev-tools
diff options
context:
space:
mode:
authorVictor Chibotaru <tchibo@google.com>2017-11-17 18:30:53 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-17 19:10:04 -0500
commitc512ac01d8a841033da8ec538a83f80fb0b4d1fe (patch)
tree061061c976f2cb1de50170092710ced6a5ac6401 /Documentation/dev-tools
parentd677a4d6019385488e794cc47bd3d6f9c2aab874 (diff)
kcov: update documentation
The updated documentation describes new KCOV mode for collecting comparison operands. Link: http://lkml.kernel.org/r/20171011095459.70721-3-glider@google.com Signed-off-by: Victor Chibotaru <tchibo@google.com> Signed-off-by: Alexander Potapenko <glider@google.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Andrey Konovalov <andreyknvl@google.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Alexander Popov <alex.popov@linux.com> Cc: Andrey Ryabinin <aryabinin@virtuozzo.com> Cc: Kees Cook <keescook@chromium.org> Cc: Vegard Nossum <vegard.nossum@oracle.com> Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com> Cc: <syzkaller@googlegroups.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'Documentation/dev-tools')
-rw-r--r--Documentation/dev-tools/kcov.rst99
1 files changed, 95 insertions, 4 deletions
diff --git a/Documentation/dev-tools/kcov.rst b/Documentation/dev-tools/kcov.rst
index 44886c91e112..c2f6452e38ed 100644
--- a/Documentation/dev-tools/kcov.rst
+++ b/Documentation/dev-tools/kcov.rst
@@ -12,19 +12,30 @@ To achieve this goal it does not collect coverage in soft/hard interrupts
12and instrumentation of some inherently non-deterministic parts of kernel is 12and instrumentation of some inherently non-deterministic parts of kernel is
13disabled (e.g. scheduler, locking). 13disabled (e.g. scheduler, locking).
14 14
15Usage 15kcov is also able to collect comparison operands from the instrumented code
16----- 16(this feature currently requires that the kernel is compiled with clang).
17
18Prerequisites
19-------------
17 20
18Configure the kernel with:: 21Configure the kernel with::
19 22
20 CONFIG_KCOV=y 23 CONFIG_KCOV=y
21 24
22CONFIG_KCOV requires gcc built on revision 231296 or later. 25CONFIG_KCOV requires gcc built on revision 231296 or later.
26
27If the comparison operands need to be collected, set::
28
29 CONFIG_KCOV_ENABLE_COMPARISONS=y
30
23Profiling data will only become accessible once debugfs has been mounted:: 31Profiling data will only become accessible once debugfs has been mounted::
24 32
25 mount -t debugfs none /sys/kernel/debug 33 mount -t debugfs none /sys/kernel/debug
26 34
27The following program demonstrates kcov usage from within a test program: 35Coverage collection
36-------------------
37The following program demonstrates coverage collection from within a test
38program using kcov:
28 39
29.. code-block:: c 40.. code-block:: c
30 41
@@ -44,6 +55,9 @@ The following program demonstrates kcov usage from within a test program:
44 #define KCOV_DISABLE _IO('c', 101) 55 #define KCOV_DISABLE _IO('c', 101)
45 #define COVER_SIZE (64<<10) 56 #define COVER_SIZE (64<<10)
46 57
58 #define KCOV_TRACE_PC 0
59 #define KCOV_TRACE_CMP 1
60
47 int main(int argc, char **argv) 61 int main(int argc, char **argv)
48 { 62 {
49 int fd; 63 int fd;
@@ -64,7 +78,7 @@ The following program demonstrates kcov usage from within a test program:
64 if ((void*)cover == MAP_FAILED) 78 if ((void*)cover == MAP_FAILED)
65 perror("mmap"), exit(1); 79 perror("mmap"), exit(1);
66 /* Enable coverage collection on the current thread. */ 80 /* Enable coverage collection on the current thread. */
67 if (ioctl(fd, KCOV_ENABLE, 0)) 81 if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_PC))
68 perror("ioctl"), exit(1); 82 perror("ioctl"), exit(1);
69 /* Reset coverage from the tail of the ioctl() call. */ 83 /* Reset coverage from the tail of the ioctl() call. */
70 __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED); 84 __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
@@ -111,3 +125,80 @@ The interface is fine-grained to allow efficient forking of test processes.
111That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode, 125That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode,
112mmaps coverage buffer and then forks child processes in a loop. Child processes 126mmaps coverage buffer and then forks child processes in a loop. Child processes
113only need to enable coverage (disable happens automatically on thread end). 127only need to enable coverage (disable happens automatically on thread end).
128
129Comparison operands collection
130------------------------------
131Comparison operands collection is similar to coverage collection:
132
133.. code-block:: c
134
135 /* Same includes and defines as above. */
136
137 /* Number of 64-bit words per record. */
138 #define KCOV_WORDS_PER_CMP 4
139
140 /*
141 * The format for the types of collected comparisons.
142 *
143 * Bit 0 shows whether one of the arguments is a compile-time constant.
144 * Bits 1 & 2 contain log2 of the argument size, up to 8 bytes.
145 */
146
147 #define KCOV_CMP_CONST (1 << 0)
148 #define KCOV_CMP_SIZE(n) ((n) << 1)
149 #define KCOV_CMP_MASK KCOV_CMP_SIZE(3)
150
151 int main(int argc, char **argv)
152 {
153 int fd;
154 uint64_t *cover, type, arg1, arg2, is_const, size;
155 unsigned long n, i;
156
157 fd = open("/sys/kernel/debug/kcov", O_RDWR);
158 if (fd == -1)
159 perror("open"), exit(1);
160 if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
161 perror("ioctl"), exit(1);
162 /*
163 * Note that the buffer pointer is of type uint64_t*, because all
164 * the comparison operands are promoted to uint64_t.
165 */
166 cover = (uint64_t *)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
167 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
168 if ((void*)cover == MAP_FAILED)
169 perror("mmap"), exit(1);
170 /* Note KCOV_TRACE_CMP instead of KCOV_TRACE_PC. */
171 if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_CMP))
172 perror("ioctl"), exit(1);
173 __atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
174 read(-1, NULL, 0);
175 /* Read number of comparisons collected. */
176 n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
177 for (i = 0; i < n; i++) {
178 type = cover[i * KCOV_WORDS_PER_CMP + 1];
179 /* arg1 and arg2 - operands of the comparison. */
180 arg1 = cover[i * KCOV_WORDS_PER_CMP + 2];
181 arg2 = cover[i * KCOV_WORDS_PER_CMP + 3];
182 /* ip - caller address. */
183 ip = cover[i * KCOV_WORDS_PER_CMP + 4];
184 /* size of the operands. */
185 size = 1 << ((type & KCOV_CMP_MASK) >> 1);
186 /* is_const - true if either operand is a compile-time constant.*/
187 is_const = type & KCOV_CMP_CONST;
188 printf("ip: 0x%lx type: 0x%lx, arg1: 0x%lx, arg2: 0x%lx, "
189 "size: %lu, %s\n",
190 ip, type, arg1, arg2, size,
191 is_const ? "const" : "non-const");
192 }
193 if (ioctl(fd, KCOV_DISABLE, 0))
194 perror("ioctl"), exit(1);
195 /* Free resources. */
196 if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
197 perror("munmap"), exit(1);
198 if (close(fd))
199 perror("close"), exit(1);
200 return 0;
201 }
202
203Note that the kcov modes (coverage collection or comparison operands) are
204mutually exclusive.