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