xref: /linux/Documentation/dev-tools/gcov.rst (revision 1446e32235b127b29bceb61fb196d02ca7327f1e)
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
254d8c1e05SAlexander A. Klimov.. _gcov: https://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
127*1446e322SWu XiangCheng.. _gcov-test:
128*1446e322SWu XiangCheng
1292584bab2SJonathan Corbeta) gcov is run on the TEST machine
1302584bab2SJonathan Corbet
1312584bab2SJonathan Corbet    The gcov tool version on the test machine must be compatible with the
1322584bab2SJonathan Corbet    gcc version used for kernel build. Also the following files need to be
1332584bab2SJonathan Corbet    copied from build to test machine:
1342584bab2SJonathan Corbet
1352584bab2SJonathan Corbet    from the source tree:
1362584bab2SJonathan Corbet      - all C source files + headers
1372584bab2SJonathan Corbet
1382584bab2SJonathan Corbet    from the build tree:
1392584bab2SJonathan Corbet      - all C source files + headers
1402584bab2SJonathan Corbet      - all .gcda and .gcno files
1412584bab2SJonathan Corbet      - all links to directories
1422584bab2SJonathan Corbet
1432584bab2SJonathan Corbet    It is important to note that these files need to be placed into the
1442584bab2SJonathan Corbet    exact same file system location on the test machine as on the build
1452584bab2SJonathan Corbet    machine. If any of the path components is symbolic link, the actual
1462584bab2SJonathan Corbet    directory needs to be used instead (due to make's CURDIR handling).
1472584bab2SJonathan Corbet
148*1446e322SWu XiangCheng.. _gcov-build:
149*1446e322SWu XiangCheng
1502584bab2SJonathan Corbetb) gcov is run on the BUILD machine
1512584bab2SJonathan Corbet
1522584bab2SJonathan Corbet    The following files need to be copied after each test case from test
1532584bab2SJonathan Corbet    to build machine:
1542584bab2SJonathan Corbet
1552584bab2SJonathan Corbet    from the gcov directory in sysfs:
1562584bab2SJonathan Corbet      - all .gcda files
1572584bab2SJonathan Corbet      - all links to .gcno files
1582584bab2SJonathan Corbet
1592584bab2SJonathan Corbet    These files can be copied to any location on the build machine. gcov
1602584bab2SJonathan Corbet    must then be called with the -o option pointing to that directory.
1612584bab2SJonathan Corbet
1622584bab2SJonathan Corbet    Example directory setup on the build machine::
1632584bab2SJonathan Corbet
1642584bab2SJonathan Corbet      /tmp/linux:    kernel source tree
1652584bab2SJonathan Corbet      /tmp/out:      kernel build directory as specified by make O=
1662584bab2SJonathan Corbet      /tmp/coverage: location of the files copied from the test machine
1672584bab2SJonathan Corbet
1682584bab2SJonathan Corbet      [user@build] cd /tmp/out
1692584bab2SJonathan Corbet      [user@build] gcov -o /tmp/coverage/tmp/out/init main.c
1702584bab2SJonathan Corbet
1712584bab2SJonathan Corbet
172aa069a23STri VoNote on compilers
173aa069a23STri Vo-----------------
174aa069a23STri Vo
175aa069a23STri VoGCC and LLVM gcov tools are not necessarily compatible. Use gcov_ to work with
176aa069a23STri VoGCC-generated .gcno and .gcda files, and use llvm-cov_ for Clang.
177aa069a23STri Vo
1784d8c1e05SAlexander A. Klimov.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
179aa069a23STri Vo.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
180aa069a23STri Vo
181aa069a23STri VoBuild differences between GCC and Clang gcov are handled by Kconfig. It
182aa069a23STri Voautomatically selects the appropriate gcov format depending on the detected
183aa069a23STri Votoolchain.
184aa069a23STri Vo
185aa069a23STri Vo
1862584bab2SJonathan CorbetTroubleshooting
1872584bab2SJonathan Corbet---------------
1882584bab2SJonathan Corbet
1892584bab2SJonathan CorbetProblem
1902584bab2SJonathan Corbet    Compilation aborts during linker step.
1912584bab2SJonathan Corbet
1922584bab2SJonathan CorbetCause
1932584bab2SJonathan Corbet    Profiling flags are specified for source files which are not
1942584bab2SJonathan Corbet    linked to the main kernel or which are linked by a custom
1952584bab2SJonathan Corbet    linker procedure.
1962584bab2SJonathan Corbet
1972584bab2SJonathan CorbetSolution
1982584bab2SJonathan Corbet    Exclude affected source files from profiling by specifying
1992584bab2SJonathan Corbet    ``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the
2002584bab2SJonathan Corbet    corresponding Makefile.
2012584bab2SJonathan Corbet
2022584bab2SJonathan CorbetProblem
2032584bab2SJonathan Corbet    Files copied from sysfs appear empty or incomplete.
2042584bab2SJonathan Corbet
2052584bab2SJonathan CorbetCause
2062584bab2SJonathan Corbet    Due to the way seq_file works, some tools such as cp or tar
2072584bab2SJonathan Corbet    may not correctly copy files from sysfs.
2082584bab2SJonathan Corbet
2092584bab2SJonathan CorbetSolution
2100a464ea4SJonathan Neuschäfer    Use ``cat`` to read ``.gcda`` files and ``cp -d`` to copy links.
2112584bab2SJonathan Corbet    Alternatively use the mechanism shown in Appendix B.
2122584bab2SJonathan Corbet
2132584bab2SJonathan Corbet
2142584bab2SJonathan CorbetAppendix A: gather_on_build.sh
2152584bab2SJonathan Corbet------------------------------
2162584bab2SJonathan Corbet
2172584bab2SJonathan CorbetSample script to gather coverage meta files on the build machine
218*1446e322SWu XiangCheng(see :ref:`Separated build and test machines a. <gcov-test>`):
21957131dd3SJani Nikula
22057131dd3SJani Nikula.. code-block:: sh
2212584bab2SJonathan Corbet
2222584bab2SJonathan Corbet    #!/bin/bash
2232584bab2SJonathan Corbet
2242584bab2SJonathan Corbet    KSRC=$1
2252584bab2SJonathan Corbet    KOBJ=$2
2262584bab2SJonathan Corbet    DEST=$3
2272584bab2SJonathan Corbet
2282584bab2SJonathan Corbet    if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
2292584bab2SJonathan Corbet      echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
2302584bab2SJonathan Corbet      exit 1
2312584bab2SJonathan Corbet    fi
2322584bab2SJonathan Corbet
2332584bab2SJonathan Corbet    KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2342584bab2SJonathan Corbet    KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2352584bab2SJonathan Corbet
2362584bab2SJonathan Corbet    find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
2372584bab2SJonathan Corbet                     -perm /u+r,g+r | tar cfz $DEST -P -T -
2382584bab2SJonathan Corbet
2392584bab2SJonathan Corbet    if [ $? -eq 0 ] ; then
2402584bab2SJonathan Corbet      echo "$DEST successfully created, copy to test system and unpack with:"
2412584bab2SJonathan Corbet      echo "  tar xfz $DEST -P"
2422584bab2SJonathan Corbet    else
2432584bab2SJonathan Corbet      echo "Could not create file $DEST"
2442584bab2SJonathan Corbet    fi
2452584bab2SJonathan Corbet
2462584bab2SJonathan Corbet
2472584bab2SJonathan CorbetAppendix B: gather_on_test.sh
2482584bab2SJonathan Corbet-----------------------------
2492584bab2SJonathan Corbet
2502584bab2SJonathan CorbetSample script to gather coverage data files on the test machine
251*1446e322SWu XiangCheng(see :ref:`Separated build and test machines b. <gcov-build>`):
25257131dd3SJani Nikula
25357131dd3SJani Nikula.. code-block:: sh
2542584bab2SJonathan Corbet
2552584bab2SJonathan Corbet    #!/bin/bash -e
2562584bab2SJonathan Corbet
2572584bab2SJonathan Corbet    DEST=$1
2582584bab2SJonathan Corbet    GCDA=/sys/kernel/debug/gcov
2592584bab2SJonathan Corbet
2602584bab2SJonathan Corbet    if [ -z "$DEST" ] ; then
2612584bab2SJonathan Corbet      echo "Usage: $0 <output.tar.gz>" >&2
2622584bab2SJonathan Corbet      exit 1
2632584bab2SJonathan Corbet    fi
2642584bab2SJonathan Corbet
2652584bab2SJonathan Corbet    TEMPDIR=$(mktemp -d)
2662584bab2SJonathan Corbet    echo Collecting data..
2672584bab2SJonathan Corbet    find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
2682584bab2SJonathan Corbet    find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
2692584bab2SJonathan Corbet    find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
2702584bab2SJonathan Corbet    tar czf $DEST -C $TEMPDIR sys
2712584bab2SJonathan Corbet    rm -rf $TEMPDIR
2722584bab2SJonathan Corbet
2732584bab2SJonathan Corbet    echo "$DEST successfully created, copy to build system and unpack with:"
2742584bab2SJonathan Corbet    echo "  tar xfz $DEST"
275