xref: /linux/Documentation/dev-tools/gcov.rst (revision aa069a23a220e9ab00d6837b76917952d0fb587e)
12584bab2SJonathan CorbetUsing gcov with the Linux kernel
22584bab2SJonathan Corbet================================
32584bab2SJonathan Corbet
42584bab2SJonathan Corbetgcov profiling kernel support enables the use of GCC's coverage testing
52584bab2SJonathan Corbettool gcov_ with the Linux kernel. Coverage data of a running kernel
62584bab2SJonathan Corbetis exported in gcov-compatible format via the "gcov" debugfs directory.
72584bab2SJonathan CorbetTo get coverage data for a specific file, change to the kernel build
82584bab2SJonathan Corbetdirectory and use gcov with the ``-o`` option as follows (requires root)::
92584bab2SJonathan Corbet
102584bab2SJonathan Corbet    # cd /tmp/linux-out
112584bab2SJonathan Corbet    # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
122584bab2SJonathan Corbet
132584bab2SJonathan CorbetThis will create source code files annotated with execution counts
142584bab2SJonathan Corbetin the current directory. In addition, graphical gcov front-ends such
152584bab2SJonathan Corbetas lcov_ can be used to automate the process of collecting data
162584bab2SJonathan Corbetfor the entire kernel and provide coverage overviews in HTML format.
172584bab2SJonathan Corbet
182584bab2SJonathan CorbetPossible uses:
192584bab2SJonathan Corbet
202584bab2SJonathan Corbet* debugging (has this line been reached at all?)
212584bab2SJonathan Corbet* test improvement (how do I change my test to cover these lines?)
222584bab2SJonathan Corbet* minimizing kernel configurations (do I need this option if the
232584bab2SJonathan Corbet  associated code is never run?)
242584bab2SJonathan Corbet
252584bab2SJonathan Corbet.. _gcov: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
262584bab2SJonathan Corbet.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
272584bab2SJonathan Corbet
282584bab2SJonathan Corbet
292584bab2SJonathan CorbetPreparation
302584bab2SJonathan Corbet-----------
312584bab2SJonathan Corbet
322584bab2SJonathan CorbetConfigure the kernel with::
332584bab2SJonathan Corbet
342584bab2SJonathan Corbet        CONFIG_DEBUG_FS=y
352584bab2SJonathan Corbet        CONFIG_GCOV_KERNEL=y
362584bab2SJonathan Corbet
372584bab2SJonathan Corbetand to get coverage data for the entire kernel::
382584bab2SJonathan Corbet
392584bab2SJonathan Corbet        CONFIG_GCOV_PROFILE_ALL=y
402584bab2SJonathan Corbet
412584bab2SJonathan CorbetNote that kernels compiled with profiling flags will be significantly
422584bab2SJonathan Corbetlarger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
432584bab2SJonathan Corbeton all architectures.
442584bab2SJonathan Corbet
452584bab2SJonathan CorbetProfiling data will only become accessible once debugfs has been
462584bab2SJonathan Corbetmounted::
472584bab2SJonathan Corbet
482584bab2SJonathan Corbet        mount -t debugfs none /sys/kernel/debug
492584bab2SJonathan Corbet
502584bab2SJonathan Corbet
512584bab2SJonathan CorbetCustomization
522584bab2SJonathan Corbet-------------
532584bab2SJonathan Corbet
542584bab2SJonathan CorbetTo enable profiling for specific files or directories, add a line
552584bab2SJonathan Corbetsimilar to the following to the respective kernel Makefile:
562584bab2SJonathan Corbet
572584bab2SJonathan Corbet- For a single file (e.g. main.o)::
582584bab2SJonathan Corbet
592584bab2SJonathan Corbet	GCOV_PROFILE_main.o := y
602584bab2SJonathan Corbet
612584bab2SJonathan Corbet- For all files in one directory::
622584bab2SJonathan Corbet
632584bab2SJonathan Corbet	GCOV_PROFILE := y
642584bab2SJonathan Corbet
652584bab2SJonathan CorbetTo exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL
662584bab2SJonathan Corbetis specified, use::
672584bab2SJonathan Corbet
682584bab2SJonathan Corbet	GCOV_PROFILE_main.o := n
692584bab2SJonathan Corbet
702584bab2SJonathan Corbetand::
712584bab2SJonathan Corbet
722584bab2SJonathan Corbet	GCOV_PROFILE := n
732584bab2SJonathan Corbet
742584bab2SJonathan CorbetOnly files which are linked to the main kernel image or are compiled as
752584bab2SJonathan Corbetkernel modules are supported by this mechanism.
762584bab2SJonathan Corbet
772584bab2SJonathan Corbet
782584bab2SJonathan CorbetFiles
792584bab2SJonathan Corbet-----
802584bab2SJonathan Corbet
812584bab2SJonathan CorbetThe gcov kernel support creates the following files in debugfs:
822584bab2SJonathan Corbet
832584bab2SJonathan Corbet``/sys/kernel/debug/gcov``
842584bab2SJonathan Corbet	Parent directory for all gcov-related files.
852584bab2SJonathan Corbet
862584bab2SJonathan Corbet``/sys/kernel/debug/gcov/reset``
872584bab2SJonathan Corbet	Global reset file: resets all coverage data to zero when
882584bab2SJonathan Corbet        written to.
892584bab2SJonathan Corbet
902584bab2SJonathan Corbet``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
912584bab2SJonathan Corbet	The actual gcov data file as understood by the gcov
922584bab2SJonathan Corbet        tool. Resets file coverage data to zero when written to.
932584bab2SJonathan Corbet
942584bab2SJonathan Corbet``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
952584bab2SJonathan Corbet	Symbolic link to a static data file required by the gcov
962584bab2SJonathan Corbet        tool. This file is generated by gcc when compiling with
972584bab2SJonathan Corbet        option ``-ftest-coverage``.
982584bab2SJonathan Corbet
992584bab2SJonathan Corbet
1002584bab2SJonathan CorbetModules
1012584bab2SJonathan Corbet-------
1022584bab2SJonathan Corbet
1032584bab2SJonathan CorbetKernel modules may contain cleanup code which is only run during
1042584bab2SJonathan Corbetmodule unload time. The gcov mechanism provides a means to collect
1052584bab2SJonathan Corbetcoverage data for such code by keeping a copy of the data associated
1062584bab2SJonathan Corbetwith the unloaded module. This data remains available through debugfs.
1072584bab2SJonathan CorbetOnce the module is loaded again, the associated coverage counters are
1082584bab2SJonathan Corbetinitialized with the data from its previous instantiation.
1092584bab2SJonathan Corbet
1102584bab2SJonathan CorbetThis behavior can be deactivated by specifying the gcov_persist kernel
1112584bab2SJonathan Corbetparameter::
1122584bab2SJonathan Corbet
1132584bab2SJonathan Corbet        gcov_persist=0
1142584bab2SJonathan Corbet
1152584bab2SJonathan CorbetAt run-time, a user can also choose to discard data for an unloaded
1162584bab2SJonathan Corbetmodule by writing to its data file or the global reset file.
1172584bab2SJonathan Corbet
1182584bab2SJonathan Corbet
1192584bab2SJonathan CorbetSeparated build and test machines
1202584bab2SJonathan Corbet---------------------------------
1212584bab2SJonathan Corbet
1222584bab2SJonathan CorbetThe gcov kernel profiling infrastructure is designed to work out-of-the
1232584bab2SJonathan Corbetbox for setups where kernels are built and run on the same machine. In
1242584bab2SJonathan Corbetcases where the kernel runs on a separate machine, special preparations
1252584bab2SJonathan Corbetmust be made, depending on where the gcov tool is used:
1262584bab2SJonathan Corbet
1272584bab2SJonathan Corbeta) gcov is run on the TEST machine
1282584bab2SJonathan Corbet
1292584bab2SJonathan Corbet    The gcov tool version on the test machine must be compatible with the
1302584bab2SJonathan Corbet    gcc version used for kernel build. Also the following files need to be
1312584bab2SJonathan Corbet    copied from build to test machine:
1322584bab2SJonathan Corbet
1332584bab2SJonathan Corbet    from the source tree:
1342584bab2SJonathan Corbet      - all C source files + headers
1352584bab2SJonathan Corbet
1362584bab2SJonathan Corbet    from the build tree:
1372584bab2SJonathan Corbet      - all C source files + headers
1382584bab2SJonathan Corbet      - all .gcda and .gcno files
1392584bab2SJonathan Corbet      - all links to directories
1402584bab2SJonathan Corbet
1412584bab2SJonathan Corbet    It is important to note that these files need to be placed into the
1422584bab2SJonathan Corbet    exact same file system location on the test machine as on the build
1432584bab2SJonathan Corbet    machine. If any of the path components is symbolic link, the actual
1442584bab2SJonathan Corbet    directory needs to be used instead (due to make's CURDIR handling).
1452584bab2SJonathan Corbet
1462584bab2SJonathan Corbetb) gcov is run on the BUILD machine
1472584bab2SJonathan Corbet
1482584bab2SJonathan Corbet    The following files need to be copied after each test case from test
1492584bab2SJonathan Corbet    to build machine:
1502584bab2SJonathan Corbet
1512584bab2SJonathan Corbet    from the gcov directory in sysfs:
1522584bab2SJonathan Corbet      - all .gcda files
1532584bab2SJonathan Corbet      - all links to .gcno files
1542584bab2SJonathan Corbet
1552584bab2SJonathan Corbet    These files can be copied to any location on the build machine. gcov
1562584bab2SJonathan Corbet    must then be called with the -o option pointing to that directory.
1572584bab2SJonathan Corbet
1582584bab2SJonathan Corbet    Example directory setup on the build machine::
1592584bab2SJonathan Corbet
1602584bab2SJonathan Corbet      /tmp/linux:    kernel source tree
1612584bab2SJonathan Corbet      /tmp/out:      kernel build directory as specified by make O=
1622584bab2SJonathan Corbet      /tmp/coverage: location of the files copied from the test machine
1632584bab2SJonathan Corbet
1642584bab2SJonathan Corbet      [user@build] cd /tmp/out
1652584bab2SJonathan Corbet      [user@build] gcov -o /tmp/coverage/tmp/out/init main.c
1662584bab2SJonathan Corbet
1672584bab2SJonathan Corbet
168*aa069a23STri VoNote on compilers
169*aa069a23STri Vo-----------------
170*aa069a23STri Vo
171*aa069a23STri VoGCC and LLVM gcov tools are not necessarily compatible. Use gcov_ to work with
172*aa069a23STri VoGCC-generated .gcno and .gcda files, and use llvm-cov_ for Clang.
173*aa069a23STri Vo
174*aa069a23STri Vo.. _gcov: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
175*aa069a23STri Vo.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
176*aa069a23STri Vo
177*aa069a23STri VoBuild differences between GCC and Clang gcov are handled by Kconfig. It
178*aa069a23STri Voautomatically selects the appropriate gcov format depending on the detected
179*aa069a23STri Votoolchain.
180*aa069a23STri Vo
181*aa069a23STri Vo
1822584bab2SJonathan CorbetTroubleshooting
1832584bab2SJonathan Corbet---------------
1842584bab2SJonathan Corbet
1852584bab2SJonathan CorbetProblem
1862584bab2SJonathan Corbet    Compilation aborts during linker step.
1872584bab2SJonathan Corbet
1882584bab2SJonathan CorbetCause
1892584bab2SJonathan Corbet    Profiling flags are specified for source files which are not
1902584bab2SJonathan Corbet    linked to the main kernel or which are linked by a custom
1912584bab2SJonathan Corbet    linker procedure.
1922584bab2SJonathan Corbet
1932584bab2SJonathan CorbetSolution
1942584bab2SJonathan Corbet    Exclude affected source files from profiling by specifying
1952584bab2SJonathan Corbet    ``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the
1962584bab2SJonathan Corbet    corresponding Makefile.
1972584bab2SJonathan Corbet
1982584bab2SJonathan CorbetProblem
1992584bab2SJonathan Corbet    Files copied from sysfs appear empty or incomplete.
2002584bab2SJonathan Corbet
2012584bab2SJonathan CorbetCause
2022584bab2SJonathan Corbet    Due to the way seq_file works, some tools such as cp or tar
2032584bab2SJonathan Corbet    may not correctly copy files from sysfs.
2042584bab2SJonathan Corbet
2052584bab2SJonathan CorbetSolution
2062584bab2SJonathan Corbet    Use ``cat``' to read ``.gcda`` files and ``cp -d`` to copy links.
2072584bab2SJonathan Corbet    Alternatively use the mechanism shown in Appendix B.
2082584bab2SJonathan Corbet
2092584bab2SJonathan Corbet
2102584bab2SJonathan CorbetAppendix A: gather_on_build.sh
2112584bab2SJonathan Corbet------------------------------
2122584bab2SJonathan Corbet
2132584bab2SJonathan CorbetSample script to gather coverage meta files on the build machine
21457131dd3SJani Nikula(see 6a):
21557131dd3SJani Nikula
21657131dd3SJani Nikula.. code-block:: sh
2172584bab2SJonathan Corbet
2182584bab2SJonathan Corbet    #!/bin/bash
2192584bab2SJonathan Corbet
2202584bab2SJonathan Corbet    KSRC=$1
2212584bab2SJonathan Corbet    KOBJ=$2
2222584bab2SJonathan Corbet    DEST=$3
2232584bab2SJonathan Corbet
2242584bab2SJonathan Corbet    if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
2252584bab2SJonathan Corbet      echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
2262584bab2SJonathan Corbet      exit 1
2272584bab2SJonathan Corbet    fi
2282584bab2SJonathan Corbet
2292584bab2SJonathan Corbet    KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2302584bab2SJonathan Corbet    KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2312584bab2SJonathan Corbet
2322584bab2SJonathan Corbet    find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
2332584bab2SJonathan Corbet                     -perm /u+r,g+r | tar cfz $DEST -P -T -
2342584bab2SJonathan Corbet
2352584bab2SJonathan Corbet    if [ $? -eq 0 ] ; then
2362584bab2SJonathan Corbet      echo "$DEST successfully created, copy to test system and unpack with:"
2372584bab2SJonathan Corbet      echo "  tar xfz $DEST -P"
2382584bab2SJonathan Corbet    else
2392584bab2SJonathan Corbet      echo "Could not create file $DEST"
2402584bab2SJonathan Corbet    fi
2412584bab2SJonathan Corbet
2422584bab2SJonathan Corbet
2432584bab2SJonathan CorbetAppendix B: gather_on_test.sh
2442584bab2SJonathan Corbet-----------------------------
2452584bab2SJonathan Corbet
2462584bab2SJonathan CorbetSample script to gather coverage data files on the test machine
24757131dd3SJani Nikula(see 6b):
24857131dd3SJani Nikula
24957131dd3SJani Nikula.. code-block:: sh
2502584bab2SJonathan Corbet
2512584bab2SJonathan Corbet    #!/bin/bash -e
2522584bab2SJonathan Corbet
2532584bab2SJonathan Corbet    DEST=$1
2542584bab2SJonathan Corbet    GCDA=/sys/kernel/debug/gcov
2552584bab2SJonathan Corbet
2562584bab2SJonathan Corbet    if [ -z "$DEST" ] ; then
2572584bab2SJonathan Corbet      echo "Usage: $0 <output.tar.gz>" >&2
2582584bab2SJonathan Corbet      exit 1
2592584bab2SJonathan Corbet    fi
2602584bab2SJonathan Corbet
2612584bab2SJonathan Corbet    TEMPDIR=$(mktemp -d)
2622584bab2SJonathan Corbet    echo Collecting data..
2632584bab2SJonathan Corbet    find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
2642584bab2SJonathan Corbet    find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
2652584bab2SJonathan Corbet    find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
2662584bab2SJonathan Corbet    tar czf $DEST -C $TEMPDIR sys
2672584bab2SJonathan Corbet    rm -rf $TEMPDIR
2682584bab2SJonathan Corbet
2692584bab2SJonathan Corbet    echo "$DEST successfully created, copy to build system and unpack with:"
2702584bab2SJonathan Corbet    echo "  tar xfz $DEST"
271