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