xref: /linux/Documentation/dev-tools/gcov.rst (revision 9410645520e9b820069761f3450ef6661418e279)
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
78*3ade6ce1SVegard NossumModule specific configs
79*3ade6ce1SVegard Nossum-----------------------
80*3ade6ce1SVegard Nossum
81*3ade6ce1SVegard NossumGcov kernel configs for specific modules are described below:
82*3ade6ce1SVegard Nossum
83*3ade6ce1SVegard NossumCONFIG_GCOV_PROFILE_RDS:
84*3ade6ce1SVegard Nossum        Enables GCOV profiling on RDS for checking which functions or
85*3ade6ce1SVegard Nossum        lines are executed. This config is used by the rds selftest to
86*3ade6ce1SVegard Nossum        generate coverage reports. If left unset the report is omitted.
87*3ade6ce1SVegard Nossum
88*3ade6ce1SVegard Nossum
892584bab2SJonathan CorbetFiles
902584bab2SJonathan Corbet-----
912584bab2SJonathan Corbet
922584bab2SJonathan CorbetThe gcov kernel support creates the following files in debugfs:
932584bab2SJonathan Corbet
942584bab2SJonathan Corbet``/sys/kernel/debug/gcov``
952584bab2SJonathan Corbet	Parent directory for all gcov-related files.
962584bab2SJonathan Corbet
972584bab2SJonathan Corbet``/sys/kernel/debug/gcov/reset``
982584bab2SJonathan Corbet	Global reset file: resets all coverage data to zero when
992584bab2SJonathan Corbet        written to.
1002584bab2SJonathan Corbet
1012584bab2SJonathan Corbet``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
1022584bab2SJonathan Corbet	The actual gcov data file as understood by the gcov
1032584bab2SJonathan Corbet        tool. Resets file coverage data to zero when written to.
1042584bab2SJonathan Corbet
1052584bab2SJonathan Corbet``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
1062584bab2SJonathan Corbet	Symbolic link to a static data file required by the gcov
1072584bab2SJonathan Corbet        tool. This file is generated by gcc when compiling with
1082584bab2SJonathan Corbet        option ``-ftest-coverage``.
1092584bab2SJonathan Corbet
1102584bab2SJonathan Corbet
1112584bab2SJonathan CorbetModules
1122584bab2SJonathan Corbet-------
1132584bab2SJonathan Corbet
1142584bab2SJonathan CorbetKernel modules may contain cleanup code which is only run during
1152584bab2SJonathan Corbetmodule unload time. The gcov mechanism provides a means to collect
1162584bab2SJonathan Corbetcoverage data for such code by keeping a copy of the data associated
1172584bab2SJonathan Corbetwith the unloaded module. This data remains available through debugfs.
1182584bab2SJonathan CorbetOnce the module is loaded again, the associated coverage counters are
1192584bab2SJonathan Corbetinitialized with the data from its previous instantiation.
1202584bab2SJonathan Corbet
1212584bab2SJonathan CorbetThis behavior can be deactivated by specifying the gcov_persist kernel
1222584bab2SJonathan Corbetparameter::
1232584bab2SJonathan Corbet
1242584bab2SJonathan Corbet        gcov_persist=0
1252584bab2SJonathan Corbet
1262584bab2SJonathan CorbetAt run-time, a user can also choose to discard data for an unloaded
1272584bab2SJonathan Corbetmodule by writing to its data file or the global reset file.
1282584bab2SJonathan Corbet
1292584bab2SJonathan Corbet
1302584bab2SJonathan CorbetSeparated build and test machines
1312584bab2SJonathan Corbet---------------------------------
1322584bab2SJonathan Corbet
1332584bab2SJonathan CorbetThe gcov kernel profiling infrastructure is designed to work out-of-the
1342584bab2SJonathan Corbetbox for setups where kernels are built and run on the same machine. In
1352584bab2SJonathan Corbetcases where the kernel runs on a separate machine, special preparations
1362584bab2SJonathan Corbetmust be made, depending on where the gcov tool is used:
1372584bab2SJonathan Corbet
1381446e322SWu XiangCheng.. _gcov-test:
1391446e322SWu XiangCheng
1402584bab2SJonathan Corbeta) gcov is run on the TEST machine
1412584bab2SJonathan Corbet
1422584bab2SJonathan Corbet    The gcov tool version on the test machine must be compatible with the
1432584bab2SJonathan Corbet    gcc version used for kernel build. Also the following files need to be
1442584bab2SJonathan Corbet    copied from build to test machine:
1452584bab2SJonathan Corbet
1462584bab2SJonathan Corbet    from the source tree:
1472584bab2SJonathan Corbet      - all C source files + headers
1482584bab2SJonathan Corbet
1492584bab2SJonathan Corbet    from the build tree:
1502584bab2SJonathan Corbet      - all C source files + headers
1512584bab2SJonathan Corbet      - all .gcda and .gcno files
1522584bab2SJonathan Corbet      - all links to directories
1532584bab2SJonathan Corbet
1542584bab2SJonathan Corbet    It is important to note that these files need to be placed into the
1552584bab2SJonathan Corbet    exact same file system location on the test machine as on the build
1562584bab2SJonathan Corbet    machine. If any of the path components is symbolic link, the actual
1572584bab2SJonathan Corbet    directory needs to be used instead (due to make's CURDIR handling).
1582584bab2SJonathan Corbet
1591446e322SWu XiangCheng.. _gcov-build:
1601446e322SWu XiangCheng
1612584bab2SJonathan Corbetb) gcov is run on the BUILD machine
1622584bab2SJonathan Corbet
1632584bab2SJonathan Corbet    The following files need to be copied after each test case from test
1642584bab2SJonathan Corbet    to build machine:
1652584bab2SJonathan Corbet
1662584bab2SJonathan Corbet    from the gcov directory in sysfs:
1672584bab2SJonathan Corbet      - all .gcda files
1682584bab2SJonathan Corbet      - all links to .gcno files
1692584bab2SJonathan Corbet
1702584bab2SJonathan Corbet    These files can be copied to any location on the build machine. gcov
1712584bab2SJonathan Corbet    must then be called with the -o option pointing to that directory.
1722584bab2SJonathan Corbet
1732584bab2SJonathan Corbet    Example directory setup on the build machine::
1742584bab2SJonathan Corbet
1752584bab2SJonathan Corbet      /tmp/linux:    kernel source tree
1762584bab2SJonathan Corbet      /tmp/out:      kernel build directory as specified by make O=
1772584bab2SJonathan Corbet      /tmp/coverage: location of the files copied from the test machine
1782584bab2SJonathan Corbet
1792584bab2SJonathan Corbet      [user@build] cd /tmp/out
1802584bab2SJonathan Corbet      [user@build] gcov -o /tmp/coverage/tmp/out/init main.c
1812584bab2SJonathan Corbet
1822584bab2SJonathan Corbet
183aa069a23STri VoNote on compilers
184aa069a23STri Vo-----------------
185aa069a23STri Vo
186aa069a23STri VoGCC and LLVM gcov tools are not necessarily compatible. Use gcov_ to work with
187aa069a23STri VoGCC-generated .gcno and .gcda files, and use llvm-cov_ for Clang.
188aa069a23STri Vo
1894d8c1e05SAlexander A. Klimov.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html
190aa069a23STri Vo.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
191aa069a23STri Vo
192aa069a23STri VoBuild differences between GCC and Clang gcov are handled by Kconfig. It
193aa069a23STri Voautomatically selects the appropriate gcov format depending on the detected
194aa069a23STri Votoolchain.
195aa069a23STri Vo
196aa069a23STri Vo
1972584bab2SJonathan CorbetTroubleshooting
1982584bab2SJonathan Corbet---------------
1992584bab2SJonathan Corbet
2002584bab2SJonathan CorbetProblem
2012584bab2SJonathan Corbet    Compilation aborts during linker step.
2022584bab2SJonathan Corbet
2032584bab2SJonathan CorbetCause
2042584bab2SJonathan Corbet    Profiling flags are specified for source files which are not
2052584bab2SJonathan Corbet    linked to the main kernel or which are linked by a custom
2062584bab2SJonathan Corbet    linker procedure.
2072584bab2SJonathan Corbet
2082584bab2SJonathan CorbetSolution
2092584bab2SJonathan Corbet    Exclude affected source files from profiling by specifying
2102584bab2SJonathan Corbet    ``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the
2112584bab2SJonathan Corbet    corresponding Makefile.
2122584bab2SJonathan Corbet
2132584bab2SJonathan CorbetProblem
2142584bab2SJonathan Corbet    Files copied from sysfs appear empty or incomplete.
2152584bab2SJonathan Corbet
2162584bab2SJonathan CorbetCause
2172584bab2SJonathan Corbet    Due to the way seq_file works, some tools such as cp or tar
2182584bab2SJonathan Corbet    may not correctly copy files from sysfs.
2192584bab2SJonathan Corbet
2202584bab2SJonathan CorbetSolution
2210a464ea4SJonathan Neuschäfer    Use ``cat`` to read ``.gcda`` files and ``cp -d`` to copy links.
2222584bab2SJonathan Corbet    Alternatively use the mechanism shown in Appendix B.
2232584bab2SJonathan Corbet
2242584bab2SJonathan Corbet
2252584bab2SJonathan CorbetAppendix A: gather_on_build.sh
2262584bab2SJonathan Corbet------------------------------
2272584bab2SJonathan Corbet
2282584bab2SJonathan CorbetSample script to gather coverage meta files on the build machine
2291446e322SWu XiangCheng(see :ref:`Separated build and test machines a. <gcov-test>`):
23057131dd3SJani Nikula
23157131dd3SJani Nikula.. code-block:: sh
2322584bab2SJonathan Corbet
2332584bab2SJonathan Corbet    #!/bin/bash
2342584bab2SJonathan Corbet
2352584bab2SJonathan Corbet    KSRC=$1
2362584bab2SJonathan Corbet    KOBJ=$2
2372584bab2SJonathan Corbet    DEST=$3
2382584bab2SJonathan Corbet
2392584bab2SJonathan Corbet    if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
2402584bab2SJonathan Corbet      echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
2412584bab2SJonathan Corbet      exit 1
2422584bab2SJonathan Corbet    fi
2432584bab2SJonathan Corbet
2442584bab2SJonathan Corbet    KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2452584bab2SJonathan Corbet    KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
2462584bab2SJonathan Corbet
2472584bab2SJonathan Corbet    find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
2482584bab2SJonathan Corbet                     -perm /u+r,g+r | tar cfz $DEST -P -T -
2492584bab2SJonathan Corbet
2502584bab2SJonathan Corbet    if [ $? -eq 0 ] ; then
2512584bab2SJonathan Corbet      echo "$DEST successfully created, copy to test system and unpack with:"
2522584bab2SJonathan Corbet      echo "  tar xfz $DEST -P"
2532584bab2SJonathan Corbet    else
2542584bab2SJonathan Corbet      echo "Could not create file $DEST"
2552584bab2SJonathan Corbet    fi
2562584bab2SJonathan Corbet
2572584bab2SJonathan Corbet
2582584bab2SJonathan CorbetAppendix B: gather_on_test.sh
2592584bab2SJonathan Corbet-----------------------------
2602584bab2SJonathan Corbet
2612584bab2SJonathan CorbetSample script to gather coverage data files on the test machine
2621446e322SWu XiangCheng(see :ref:`Separated build and test machines b. <gcov-build>`):
26357131dd3SJani Nikula
26457131dd3SJani Nikula.. code-block:: sh
2652584bab2SJonathan Corbet
2662584bab2SJonathan Corbet    #!/bin/bash -e
2672584bab2SJonathan Corbet
2682584bab2SJonathan Corbet    DEST=$1
2692584bab2SJonathan Corbet    GCDA=/sys/kernel/debug/gcov
2702584bab2SJonathan Corbet
2712584bab2SJonathan Corbet    if [ -z "$DEST" ] ; then
2722584bab2SJonathan Corbet      echo "Usage: $0 <output.tar.gz>" >&2
2732584bab2SJonathan Corbet      exit 1
2742584bab2SJonathan Corbet    fi
2752584bab2SJonathan Corbet
2762584bab2SJonathan Corbet    TEMPDIR=$(mktemp -d)
2772584bab2SJonathan Corbet    echo Collecting data..
2782584bab2SJonathan Corbet    find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
2792584bab2SJonathan Corbet    find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
2802584bab2SJonathan Corbet    find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
2812584bab2SJonathan Corbet    tar czf $DEST -C $TEMPDIR sys
2822584bab2SJonathan Corbet    rm -rf $TEMPDIR
2832584bab2SJonathan Corbet
2842584bab2SJonathan Corbet    echo "$DEST successfully created, copy to build system and unpack with:"
2852584bab2SJonathan Corbet    echo "  tar xfz $DEST"
286