brintos

brintos / linux-shallow public Read only

0
0
Text · 8.3 KiB · dbd26b0 Raw
286 lines · plain
1Using gcov with the Linux kernel2================================3 4gcov profiling kernel support enables the use of GCC's coverage testing5tool gcov_ with the Linux kernel. Coverage data of a running kernel6is exported in gcov-compatible format via the "gcov" debugfs directory.7To get coverage data for a specific file, change to the kernel build8directory and use gcov with the ``-o`` option as follows (requires root)::9 10    # cd /tmp/linux-out11    # gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c12 13This will create source code files annotated with execution counts14in the current directory. In addition, graphical gcov front-ends such15as lcov_ can be used to automate the process of collecting data16for 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 the23  associated code is never run?)24 25.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html26.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php27 28 29Preparation30-----------31 32Configure the kernel with::33 34        CONFIG_DEBUG_FS=y35        CONFIG_GCOV_KERNEL=y36 37and to get coverage data for the entire kernel::38 39        CONFIG_GCOV_PROFILE_ALL=y40 41Note that kernels compiled with profiling flags will be significantly42larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported43on all architectures.44 45Profiling data will only become accessible once debugfs has been46mounted::47 48        mount -t debugfs none /sys/kernel/debug49 50 51Customization52-------------53 54To enable profiling for specific files or directories, add a line55similar to the following to the respective kernel Makefile:56 57- For a single file (e.g. main.o)::58 59	GCOV_PROFILE_main.o := y60 61- For all files in one directory::62 63	GCOV_PROFILE := y64 65To exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL66is specified, use::67 68	GCOV_PROFILE_main.o := n69 70and::71 72	GCOV_PROFILE := n73 74Only files which are linked to the main kernel image or are compiled as75kernel modules are supported by this mechanism.76 77 78Module specific configs79-----------------------80 81Gcov kernel configs for specific modules are described below:82 83CONFIG_GCOV_PROFILE_RDS:84        Enables GCOV profiling on RDS for checking which functions or85        lines are executed. This config is used by the rds selftest to86        generate coverage reports. If left unset the report is omitted.87 88 89Files90-----91 92The gcov kernel support creates the following files in debugfs:93 94``/sys/kernel/debug/gcov``95	Parent directory for all gcov-related files.96 97``/sys/kernel/debug/gcov/reset``98	Global reset file: resets all coverage data to zero when99        written to.100 101``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``102	The actual gcov data file as understood by the gcov103        tool. Resets file coverage data to zero when written to.104 105``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``106	Symbolic link to a static data file required by the gcov107        tool. This file is generated by gcc when compiling with108        option ``-ftest-coverage``.109 110 111Modules112-------113 114Kernel modules may contain cleanup code which is only run during115module unload time. The gcov mechanism provides a means to collect116coverage data for such code by keeping a copy of the data associated117with the unloaded module. This data remains available through debugfs.118Once the module is loaded again, the associated coverage counters are119initialized with the data from its previous instantiation.120 121This behavior can be deactivated by specifying the gcov_persist kernel122parameter::123 124        gcov_persist=0125 126At run-time, a user can also choose to discard data for an unloaded127module by writing to its data file or the global reset file.128 129 130Separated build and test machines131---------------------------------132 133The gcov kernel profiling infrastructure is designed to work out-of-the134box for setups where kernels are built and run on the same machine. In135cases where the kernel runs on a separate machine, special preparations136must be made, depending on where the gcov tool is used:137 138.. _gcov-test:139 140a) gcov is run on the TEST machine141 142    The gcov tool version on the test machine must be compatible with the143    gcc version used for kernel build. Also the following files need to be144    copied from build to test machine:145 146    from the source tree:147      - all C source files + headers148 149    from the build tree:150      - all C source files + headers151      - all .gcda and .gcno files152      - all links to directories153 154    It is important to note that these files need to be placed into the155    exact same file system location on the test machine as on the build156    machine. If any of the path components is symbolic link, the actual157    directory needs to be used instead (due to make's CURDIR handling).158 159.. _gcov-build:160 161b) gcov is run on the BUILD machine162 163    The following files need to be copied after each test case from test164    to build machine:165 166    from the gcov directory in sysfs:167      - all .gcda files168      - all links to .gcno files169 170    These files can be copied to any location on the build machine. gcov171    must then be called with the -o option pointing to that directory.172 173    Example directory setup on the build machine::174 175      /tmp/linux:    kernel source tree176      /tmp/out:      kernel build directory as specified by make O=177      /tmp/coverage: location of the files copied from the test machine178 179      [user@build] cd /tmp/out180      [user@build] gcov -o /tmp/coverage/tmp/out/init main.c181 182 183Note on compilers184-----------------185 186GCC and LLVM gcov tools are not necessarily compatible. Use gcov_ to work with187GCC-generated .gcno and .gcda files, and use llvm-cov_ for Clang.188 189.. _gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html190.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html191 192Build differences between GCC and Clang gcov are handled by Kconfig. It193automatically selects the appropriate gcov format depending on the detected194toolchain.195 196 197Troubleshooting198---------------199 200Problem201    Compilation aborts during linker step.202 203Cause204    Profiling flags are specified for source files which are not205    linked to the main kernel or which are linked by a custom206    linker procedure.207 208Solution209    Exclude affected source files from profiling by specifying210    ``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the211    corresponding Makefile.212 213Problem214    Files copied from sysfs appear empty or incomplete.215 216Cause217    Due to the way seq_file works, some tools such as cp or tar218    may not correctly copy files from sysfs.219 220Solution221    Use ``cat`` to read ``.gcda`` files and ``cp -d`` to copy links.222    Alternatively use the mechanism shown in Appendix B.223 224 225Appendix A: gather_on_build.sh226------------------------------227 228Sample script to gather coverage meta files on the build machine229(see :ref:`Separated build and test machines a. <gcov-test>`):230 231.. code-block:: sh232 233    #!/bin/bash234 235    KSRC=$1236    KOBJ=$2237    DEST=$3238 239    if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then240      echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2241      exit 1242    fi243 244    KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)245    KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)246 247    find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \248                     -perm /u+r,g+r | tar cfz $DEST -P -T -249 250    if [ $? -eq 0 ] ; then251      echo "$DEST successfully created, copy to test system and unpack with:"252      echo "  tar xfz $DEST -P"253    else254      echo "Could not create file $DEST"255    fi256 257 258Appendix B: gather_on_test.sh259-----------------------------260 261Sample script to gather coverage data files on the test machine262(see :ref:`Separated build and test machines b. <gcov-build>`):263 264.. code-block:: sh265 266    #!/bin/bash -e267 268    DEST=$1269    GCDA=/sys/kernel/debug/gcov270 271    if [ -z "$DEST" ] ; then272      echo "Usage: $0 <output.tar.gz>" >&2273      exit 1274    fi275 276    TEMPDIR=$(mktemp -d)277    echo Collecting data..278    find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;279    find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;280    find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;281    tar czf $DEST -C $TEMPDIR sys282    rm -rf $TEMPDIR283 284    echo "$DEST successfully created, copy to build system and unpack with:"285    echo "  tar xfz $DEST"286