• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1HOW TO COLLECT KERNEL CODE COVERAGE FROM A TEST RUN
2===================================================
3
4
5## 1. Build and use a kernel with GCOV profile enabled
6### Build and install with scripts
7Build and install a GCOV kernel on a Cuttlefish or physical device with one of
8the following commands:
9```
10$ kernel/tests/tools/launch_cvd.sh --gcov
11```
12```
13$ kernel/tests/tools/flash_device.sh --gcov
14```
15To view available options, run the scripts with `--help`.
16
17### Build on your own
18Build a kernel with
19[`--gcov`](https://android.googlesource.com/kernel/build/+/refs/heads/main/kleaf/docs/gcov.md)
20option. This will also trigger the build to save the required *.gcno files
21needed to viewing the collected count data.
22
23For example, build a Cuttlefish kernel with GCOV:
24```
25$ tools/bazel run --gcov //common-modules/virtual-device:virtual_device_x86_64_dist
26```
27
28## 2. Run tests with kernel coverage collection enabled
29### `run_test_only.sh`
30Collect test coverage data with `run_test_only.sh --gcov` and the required
31options. For example,
32
33```
34$ kernel/tests/tools/run_test_only.sh --gcov \
35    --serial 0.0.0.0:6520 --test='selftests kselftest_net_socket'
36```
37
38To view available options, run the script with `--help`.
39
40### `tradefed.sh`
41Adding the appropriate coverage flags to the tradefed call will trigger it to
42take care of mounting debugfs, reseting the gcov counts prior to test run, and
43collecting gcov data files from debugfs after test completion. These coverage
44arguments are:
45```
46--coverage --coverage-toolchain GCOV_KERNEL --auto-collect GCOV_KERNEL_COVERAGE
47```
48
49The following is a full example call running just the `kselftest_net_socket`
50test in the selftests test suite that exists under the `out/tests/testcases`
51directory. The artifact output has been redirected to `tf-logs` for easier
52reference needed in the next step.
53```
54$ prebuilts/tradefed/filegroups/tradefed/tradefed.sh run commandAndExit \
55    template/local_min --template:map test=suite/test_mapping_suite     \
56    --include-filter 'selftests kselftest_net_socket'                   \
57    --tests-dir=out/tests/testcases                                     \
58    --primary-abi-only --log-file-path tf-logs                          \
59    --coverage --coverage-toolchain GCOV_KERNEL                         \
60    --auto-collect GCOV_KERNEL_COVERAGE
61```
62
63## 3. Create an lcov tracefile out of the gcov tar artifact from test run
64The previously mentioned `run_test_only.sh` or `tradefed.sh` run will produce
65a tar file artifact in the log folder with a name like
66`<test>_kernel_coverage_*.tar.gz`. This tar file is an archive of all the gcov
67data files collected into debugfs from the profiled device. In order to make
68it easier to work with this data, it needs to be converted to a single lcov
69tracefile.
70
71The script `create-tracefile.py` facilitates this generation by handling the
72required unpacking, file path corrections and ultimate `lcov` call.
73`run_test_only.sh` calls `create-tracefile.py` automatically if it can locate
74the kernel source. Otherwise, it shows the arguments for you to run
75`create-tracefile.py` in the kernel source tree.
76
77If you use `tradefed.sh`, you need to issue the `create-tracefile.py` command.
78The following is an example where we generate a tracefile named `cov.info`
79only including results from `net/socket.c`. (If no source files are specified
80as included, then all source file data is used.)
81```
82$ kernel/tests/tools/create-tracefile.py -t tf-logs --include net/socket.c
83```
84
85## 4. Visualizing results
86With the created tracefile, there are a number of different ways to view
87coverage data from it. Check out `man lcov` for more options.
88### Summary
89```
90$ lcov --summary --rc lcov_branch_coverage=1 cov.info
91Reading tracefile cov.info_fix
92Summary coverage rate:
93  lines......: 6.0% (81646 of 1370811 lines)
94  functions..: 9.6% (10285 of 107304 functions)
95  branches...: 3.7% (28639 of 765538 branches)
96```
97### List
98```
99$ lcov --list --rc lcov_branch_coverage=1 cov.info
100Reading tracefile cov.info_fix
101                                               |Lines      |Functions|Branches
102Filename                                       |Rate    Num|Rate  Num|Rate   Num
103================================================================================
104[/usr/local/google/home/joefradley/dev/common-android-mainline-2/common/]
105arch/x86/crypto/aesni-intel_glue.c             |23.9%   623|22.2%  36|15.0%  240
106arch/x86/crypto/blake2s-glue.c                 |50.0%    28|50.0%   2|16.7%   30
107arch/x86/crypto/chacha_glue.c                  | 0.0%   157| 0.0%  10| 0.0%   80
108<truncated>
109virt/lib/irqbypass.c                           | 0.0%   137| 0.0%   6| 0.0%   88
110================================================================================
111                                         Total:| 6.0% 1369k| 9.6%  0M| 3.7% 764k
112```
113### HTML
114The `lcov` tool `genhtml` is used to generate html. To create html with the
115default settings:
116
117```
118$ genhtml --branch-coverage -o html cov.info
119```
120
121The page can be viewed at `html/index.html`.
122
123Options of interest:
124 * `--frame`: Creates a left hand macro view in a source file view.
125 * `--missed`: Helpful if you want to sort by what source is missing the most
126   as opposed to the default coverage percentages.
127