Blame view

Documentation/gcov.txt 7.52 KB
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  Using gcov with the Linux kernel
  ================================
  
  1. Introduction
  2. Preparation
  3. Customization
  4. Files
  5. Modules
  6. Separated build and test machines
  7. Troubleshooting
  Appendix A: sample script: gather_on_build.sh
  Appendix B: sample script: gather_on_test.sh
  
  
  1. Introduction
  ===============
  
  gcov profiling kernel support enables the use of GCC's coverage testing
  tool gcov [1] with the Linux kernel. Coverage data of a running kernel
  is exported in gcov-compatible format via the "gcov" debugfs directory.
  To get coverage data for a specific file, change to the kernel build
  directory and use gcov with the -o option as follows (requires root):
  
  # cd /tmp/linux-out
  # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
  
  This will create source code files annotated with execution counts
  in the current directory. In addition, graphical gcov front-ends such
  as lcov [2] can be used to automate the process of collecting data
  for the entire kernel and provide coverage overviews in HTML format.
  
  Possible uses:
  
  * debugging (has this line been reached at all?)
  * test improvement (how do I change my test to cover these lines?)
  * minimizing kernel configurations (do I need this option if the
    associated code is never run?)
  
  --
  
  [1] http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
  [2] http://ltp.sourceforge.net/coverage/lcov.php
  
  
  2. Preparation
  ==============
  
  Configure the kernel with:
3c78f5d81   Marton Nemeth   trivial: fix typo...
49
          CONFIG_DEBUG_FS=y
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
          CONFIG_GCOV_KERNEL=y
  
  and to get coverage data for the entire kernel:
  
          CONFIG_GCOV_PROFILE_ALL=y
  
  Note that kernels compiled with profiling flags will be significantly
  larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
  on all architectures.
  
  Profiling data will only become accessible once debugfs has been
  mounted:
  
          mount -t debugfs none /sys/kernel/debug
  
  
  3. Customization
  ================
  
  To enable profiling for specific files or directories, add a line
  similar to the following to the respective kernel Makefile:
  
          For a single file (e.g. main.o):
                  GCOV_PROFILE_main.o := y
  
          For all files in one directory:
                  GCOV_PROFILE := y
  
  To exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL
  is specified, use:
  
                  GCOV_PROFILE_main.o := n
          and:
                  GCOV_PROFILE := n
  
  Only files which are linked to the main kernel image or are compiled as
  kernel modules are supported by this mechanism.
  
  
  4. Files
  ========
  
  The gcov kernel support creates the following files in debugfs:
  
          /sys/kernel/debug/gcov
                  Parent directory for all gcov-related files.
  
          /sys/kernel/debug/gcov/reset
                  Global reset file: resets all coverage data to zero when
                  written to.
  
          /sys/kernel/debug/gcov/path/to/compile/dir/file.gcda
                  The actual gcov data file as understood by the gcov
                  tool. Resets file coverage data to zero when written to.
  
          /sys/kernel/debug/gcov/path/to/compile/dir/file.gcno
                  Symbolic link to a static data file required by the gcov
                  tool. This file is generated by gcc when compiling with
                  option -ftest-coverage.
  
  
  5. Modules
  ==========
  
  Kernel modules may contain cleanup code which is only run during
  module unload time. The gcov mechanism provides a means to collect
  coverage data for such code by keeping a copy of the data associated
  with the unloaded module. This data remains available through debugfs.
  Once the module is loaded again, the associated coverage counters are
  initialized with the data from its previous instantiation.
  
  This behavior can be deactivated by specifying the gcov_persist kernel
  parameter:
  
          gcov_persist=0
  
  At run-time, a user can also choose to discard data for an unloaded
  module by writing to its data file or the global reset file.
  
  
  6. Separated build and test machines
  ====================================
  
  The gcov kernel profiling infrastructure is designed to work out-of-the
  box for setups where kernels are built and run on the same machine. In
  cases where the kernel runs on a separate machine, special preparations
  must be made, depending on where the gcov tool is used:
  
  a) gcov is run on the TEST machine
  
  The gcov tool version on the test machine must be compatible with the
  gcc version used for kernel build. Also the following files need to be
  copied from build to test machine:
  
  from the source tree:
    - all C source files + headers
  
  from the build tree:
    - all C source files + headers
    - all .gcda and .gcno files
    - all links to directories
  
  It is important to note that these files need to be placed into the
  exact same file system location on the test machine as on the build
  machine. If any of the path components is symbolic link, the actual
  directory needs to be used instead (due to make's CURDIR handling).
  
  b) gcov is run on the BUILD machine
  
  The following files need to be copied after each test case from test
  to build machine:
  
  from the gcov directory in sysfs:
    - all .gcda files
    - all links to .gcno files
  
  These files can be copied to any location on the build machine. gcov
  must then be called with the -o option pointing to that directory.
  
  Example directory setup on the build machine:
  
    /tmp/linux:    kernel source tree
    /tmp/out:      kernel build directory as specified by make O=
    /tmp/coverage: location of the files copied from the test machine
  
    [user@build] cd /tmp/out
    [user@build] gcov -o /tmp/coverage/tmp/out/init main.c
  
  
  7. Troubleshooting
  ==================
  
  Problem:  Compilation aborts during linker step.
  Cause:    Profiling flags are specified for source files which are not
            linked to the main kernel or which are linked by a custom
            linker procedure.
  Solution: Exclude affected source files from profiling by specifying
            GCOV_PROFILE := n or GCOV_PROFILE_basename.o := n in the
            corresponding Makefile.
972c71a31   Peter Oberparleiter   gcov: fix documen...
189
190
191
192
193
  Problem:  Files copied from sysfs appear empty or incomplete.
  Cause:    Due to the way seq_file works, some tools such as cp or tar
            may not correctly copy files from sysfs.
  Solution: Use 'cat' to read .gcda files and 'cp -d' to copy links.
            Alternatively use the mechanism shown in Appendix B.
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
194
195
196
197
198
199
  
  Appendix A: gather_on_build.sh
  ==============================
  
  Sample script to gather coverage meta files on the build machine
  (see 6a):
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  #!/bin/bash
  
  KSRC=$1
  KOBJ=$2
  DEST=$3
  
  if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
    echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
    exit 1
  fi
  
  KSRC=$(cd $KSRC; printf "all:
  \t@echo \${CURDIR}
  " | make -f -)
  KOBJ=$(cd $KOBJ; printf "all:
  \t@echo \${CURDIR}
  " | make -f -)
  
  find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
                   -perm /u+r,g+r | tar cfz $DEST -P -T -
  
  if [ $? -eq 0 ] ; then
    echo "$DEST successfully created, copy to test system and unpack with:"
    echo "  tar xfz $DEST -P"
  else
    echo "Could not create file $DEST"
  fi
  
  
  Appendix B: gather_on_test.sh
  =============================
  
  Sample script to gather coverage data files on the test machine
  (see 6b):
972c71a31   Peter Oberparleiter   gcov: fix documen...
234
  #!/bin/bash -e
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
235
236
237
238
239
240
241
242
  
  DEST=$1
  GCDA=/sys/kernel/debug/gcov
  
  if [ -z "$DEST" ] ; then
    echo "Usage: $0 <output.tar.gz>" >&2
    exit 1
  fi
972c71a31   Peter Oberparleiter   gcov: fix documen...
243
244
245
246
247
248
249
  TEMPDIR=$(mktemp -d)
  echo Collecting data..
  find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
  find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
  find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
  tar czf $DEST -C $TEMPDIR sys
  rm -rf $TEMPDIR
2521f2c22   Peter Oberparleiter   gcov: add gcov pr...
250

972c71a31   Peter Oberparleiter   gcov: fix documen...
251
252
  echo "$DEST successfully created, copy to build system and unpack with:"
  echo "  tar xfz $DEST"