xref: /aosp_15_r20/build/soong/docs/native_code_coverage.md (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker## Native Code Coverage for Android
2*333d2b36SAndroid Build Coastguard Worker
3*333d2b36SAndroid Build Coastguard Worker## Scope
4*333d2b36SAndroid Build Coastguard Worker
5*333d2b36SAndroid Build Coastguard WorkerThese instructions are for Android developers to collect and inspect code
6*333d2b36SAndroid Build Coastguard Workercoverage for C++ and Rust code on the Android platform.
7*333d2b36SAndroid Build Coastguard Worker
8*333d2b36SAndroid Build Coastguard Worker## Building with Native Code Coverage Instrumentation
9*333d2b36SAndroid Build Coastguard Worker
10*333d2b36SAndroid Build Coastguard WorkerIdentify the paths where native code-coverage instrumentation should be enabled
11*333d2b36SAndroid Build Coastguard Workerand set up the following environment variables.
12*333d2b36SAndroid Build Coastguard Worker
13*333d2b36SAndroid Build Coastguard Worker```
14*333d2b36SAndroid Build Coastguard Worker    export CLANG_COVERAGE=true
15*333d2b36SAndroid Build Coastguard Worker    export NATIVE_COVERAGE_PATHS="<paths-to-instrument-for-coverage>"
16*333d2b36SAndroid Build Coastguard Worker```
17*333d2b36SAndroid Build Coastguard Worker
18*333d2b36SAndroid Build Coastguard Worker`NATIVE_COVERAGE_PATHS` should be a list of paths. Any Android.bp module defined
19*333d2b36SAndroid Build Coastguard Workerunder these paths is instrumented for code-coverage. E.g:
20*333d2b36SAndroid Build Coastguard Worker
21*333d2b36SAndroid Build Coastguard Worker```
22*333d2b36SAndroid Build Coastguard Workerexport NATIVE_COVERAGE_PATHS="external/libcxx system/core/adb"
23*333d2b36SAndroid Build Coastguard Worker```
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker### Additional Notes
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker-   Native Code coverage is not supported for host modules or `Android.mk`
28*333d2b36SAndroid Build Coastguard Worker    modules.
29*333d2b36SAndroid Build Coastguard Worker-   `NATIVE_COVERAGE_PATHS="*"` enables coverage instrumentation for all paths.
30*333d2b36SAndroid Build Coastguard Worker-   Set `native_coverage: false` blueprint property to always disable code
31*333d2b36SAndroid Build Coastguard Worker    coverage instrumentation for a module. This is useful if this module has
32*333d2b36SAndroid Build Coastguard Worker    issues when building or running with coverage.
33*333d2b36SAndroid Build Coastguard Worker-   `NATIVE_COVERAGE_EXCLUDE_PATHS` can be set to exclude subdirs under
34*333d2b36SAndroid Build Coastguard Worker    `NATIVE_COVERAGE_PATHS` from coverage instrumentation. E.g.
35*333d2b36SAndroid Build Coastguard Worker    `NATIVE_COVERAGE_PATHS=frameworks/native
36*333d2b36SAndroid Build Coastguard Worker    NATIVE_COVERAGE_PATHS=frameworks/native/vulkan` will instrument all native
37*333d2b36SAndroid Build Coastguard Worker    code under `frameworks/native` except`frameworks/native/vulkan`.
38*333d2b36SAndroid Build Coastguard Worker
39*333d2b36SAndroid Build Coastguard Worker## Running Tests
40*333d2b36SAndroid Build Coastguard Worker
41*333d2b36SAndroid Build Coastguard Worker### Collecting Profiles
42*333d2b36SAndroid Build Coastguard Worker
43*333d2b36SAndroid Build Coastguard WorkerWhen an instrumented program is run, the profiles are stored to the path and
44*333d2b36SAndroid Build Coastguard Workername specified in the `LLVM_PROFILE_FILE` environment variable. On Android
45*333d2b36SAndroid Build Coastguard Workercoverage builds it is set to `/data/misc/trace/clang-%p-%20m.profraw`.
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker*   `%`p is replaced by the pid of the process
48*333d2b36SAndroid Build Coastguard Worker*   `%m` by the hash of the library/binary
49*333d2b36SAndroid Build Coastguard Worker*   The `20` in`%20m` creates a pool of 20 profraw files and "online" profile
50*333d2b36SAndroid Build Coastguard Worker    merging is used to merge coverage to profiles onto this pool.
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard WorkerReference:`LLVM_PROFILE_FILE` can include additional specifiers as described
53*333d2b36SAndroid Build Coastguard Worker[here](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program).
54*333d2b36SAndroid Build Coastguard Worker
55*333d2b36SAndroid Build Coastguard WorkerFor this and following steps, use the `acov-llvm.py` script:
56*333d2b36SAndroid Build Coastguard Worker`$ANDROID_BUILD_TOP/development/scripts/acov-llvm.py`.
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard WorkerThere may be profiles in `/data/misc/trace` collected before the test is run.
59*333d2b36SAndroid Build Coastguard WorkerClear this data before running the test.
60*333d2b36SAndroid Build Coastguard Worker
61*333d2b36SAndroid Build Coastguard Worker```
62*333d2b36SAndroid Build Coastguard Worker    # Clear any coverage that's already written to /data/misc/trace
63*333d2b36SAndroid Build Coastguard Worker    # and reset coverage for all daemons.
64*333d2b36SAndroid Build Coastguard Worker    <host>$ acov-llvm.py clean-device
65*333d2b36SAndroid Build Coastguard Worker
66*333d2b36SAndroid Build Coastguard Worker    # Run the test.  The exact command depends on the nature of the test.
67*333d2b36SAndroid Build Coastguard Worker    <device>$ /data/local/tmp/$MY_TEST
68*333d2b36SAndroid Build Coastguard Worker```
69*333d2b36SAndroid Build Coastguard Worker
70*333d2b36SAndroid Build Coastguard WorkerFor tests that exercise a daemon/service running in another process, write out
71*333d2b36SAndroid Build Coastguard Workerthe coverage for those processes as well.
72*333d2b36SAndroid Build Coastguard Worker
73*333d2b36SAndroid Build Coastguard Worker```
74*333d2b36SAndroid Build Coastguard Worker    # Flush coverage of all daemons/processes running on the device.
75*333d2b36SAndroid Build Coastguard Worker    <host>$ acov-llvm.py flush
76*333d2b36SAndroid Build Coastguard Worker
77*333d2b36SAndroid Build Coastguard Worker    # Flush coverage for a particular daemon, say adbd.
78*333d2b36SAndroid Build Coastguard Worker    <host>$ acov-llvm.py flush adbd
79*333d2b36SAndroid Build Coastguard Worker```
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker## Viewing Coverage Data (acov-llvm.py)
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard WorkerTo post-process and view coverage information we use the `acov-llvm.py report`
84*333d2b36SAndroid Build Coastguard Workercommand. It invokes two LLVM utilities `llvm-profdata` and `llvm-cov`. An
85*333d2b36SAndroid Build Coastguard Workeradvanced user can manually invoke these utilities for fine-grained control. This
86*333d2b36SAndroid Build Coastguard Workeris discussed [below](#viewing-coverage-data-manual).
87*333d2b36SAndroid Build Coastguard Worker
88*333d2b36SAndroid Build Coastguard WorkerTo generate coverage report need the following parameters. These are dependent
89*333d2b36SAndroid Build Coastguard Workeron the test/module:
90*333d2b36SAndroid Build Coastguard Worker
91*333d2b36SAndroid Build Coastguard Worker1.  One or more binaries and shared libraries from which coverage was collected.
92*333d2b36SAndroid Build Coastguard Worker    E.g.:
93*333d2b36SAndroid Build Coastguard Worker
94*333d2b36SAndroid Build Coastguard Worker    1.  ART mainline module contains a few libraries such as `libart.so`,
95*333d2b36SAndroid Build Coastguard Worker        `libart-compiler.so`.
96*333d2b36SAndroid Build Coastguard Worker    2.  Bionic tests exercise code in `libc.so` and `libm.so`.
97*333d2b36SAndroid Build Coastguard Worker
98*333d2b36SAndroid Build Coastguard Worker    We need the *unstripped* copies of these binaries. Source information
99*333d2b36SAndroid Build Coastguard Worker    included in the debuginfo is used to process the coverage data.
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Worker2.  One or more source directories under `$ANDROID_BUILD_TOP` for which coverage
102*333d2b36SAndroid Build Coastguard Worker    needs to be reported.
103*333d2b36SAndroid Build Coastguard Worker
104*333d2b36SAndroid Build Coastguard WorkerInvoke the report subcommand of acov-llvm.py to produce a html coverage summary:
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Worker```
107*333d2b36SAndroid Build Coastguard Worker    $ acov-llvm.py report \
108*333d2b36SAndroid Build Coastguard Worker        -s <one-or-more-source-paths-in-$ANDROID_BUILD_TOP \
109*333d2b36SAndroid Build Coastguard Worker        -b <one-or-more-(unstripped)-binaries-in-$OUT>
110*333d2b36SAndroid Build Coastguard Worker```
111*333d2b36SAndroid Build Coastguard Worker
112*333d2b36SAndroid Build Coastguard WorkerE.g.:
113*333d2b36SAndroid Build Coastguard Worker
114*333d2b36SAndroid Build Coastguard Worker```
115*333d2b36SAndroid Build Coastguard Worker    $ acov-llvm.py report \
116*333d2b36SAndroid Build Coastguard Worker        -s bionic \
117*333d2b36SAndroid Build Coastguard Worker        -b \
118*333d2b36SAndroid Build Coastguard Worker        $OUT/symbols/apex/com.android.runtime/lib/bionic/libc.so \
119*333d2b36SAndroid Build Coastguard Worker        $OUT/symbols/apex/com.android.runtime/lib/bionic/libm.so
120*333d2b36SAndroid Build Coastguard Worker```
121*333d2b36SAndroid Build Coastguard Worker
122*333d2b36SAndroid Build Coastguard WorkerThe script will produce a report in a temporary directory under
123*333d2b36SAndroid Build Coastguard Worker`$ANDROID_BUILD_TOP`. It'll produce a log as below:
124*333d2b36SAndroid Build Coastguard Worker
125*333d2b36SAndroid Build Coastguard Worker```
126*333d2b36SAndroid Build Coastguard Worker    generating coverage report in covreport-xxxxxx
127*333d2b36SAndroid Build Coastguard Worker```
128*333d2b36SAndroid Build Coastguard Worker
129*333d2b36SAndroid Build Coastguard WorkerA html report would be generated under `covreport-xxxxxx/html`.
130*333d2b36SAndroid Build Coastguard Worker
131*333d2b36SAndroid Build Coastguard Worker## Viewing Coverage Data (manual)
132*333d2b36SAndroid Build Coastguard Worker
133*333d2b36SAndroid Build Coastguard Worker`acov-llvm.py report` does a few operations under the hood which we can also
134*333d2b36SAndroid Build Coastguard Workermanually invoke for flexibility.
135*333d2b36SAndroid Build Coastguard Worker
136*333d2b36SAndroid Build Coastguard Worker### Post-processing Coverage Files
137*333d2b36SAndroid Build Coastguard Worker
138*333d2b36SAndroid Build Coastguard WorkerFetch coverage files from the device and post-process them to a `.profdata` file
139*333d2b36SAndroid Build Coastguard Workeras follows:
140*333d2b36SAndroid Build Coastguard Worker
141*333d2b36SAndroid Build Coastguard Worker```
142*333d2b36SAndroid Build Coastguard Worker    # Fetch the coverage data from the device.
143*333d2b36SAndroid Build Coastguard Worker    <host>$ cd coverage_data
144*333d2b36SAndroid Build Coastguard Worker    <host>$ adb pull /data/misc/trace/ $TRACE_DIR_HOST
145*333d2b36SAndroid Build Coastguard Worker
146*333d2b36SAndroid Build Coastguard Worker    # Convert from .profraw format to the .profdata format.
147*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-profdata merge --output=$MY_TEST.profdata \
148*333d2b36SAndroid Build Coastguard Worker    $TRACE_DIR_HOST/clang-*.profraw
149*333d2b36SAndroid Build Coastguard Worker```
150*333d2b36SAndroid Build Coastguard Worker
151*333d2b36SAndroid Build Coastguard WorkerFor added specificity, restrict the above command to just the <PID>s of the
152*333d2b36SAndroid Build Coastguard Workerdaemon or test processes of interest.
153*333d2b36SAndroid Build Coastguard Worker
154*333d2b36SAndroid Build Coastguard Worker```
155*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-profdata merge --output=$MY_TEST.profdata \
156*333d2b36SAndroid Build Coastguard Worker    $MY_TEST.profraw \
157*333d2b36SAndroid Build Coastguard Worker    trace/clang-<pid1>.profraw trace/clang-<pid2>.profraw ...
158*333d2b36SAndroid Build Coastguard Worker```
159*333d2b36SAndroid Build Coastguard Worker
160*333d2b36SAndroid Build Coastguard Worker### Generating Coverage report
161*333d2b36SAndroid Build Coastguard Worker
162*333d2b36SAndroid Build Coastguard WorkerDocumentation on Clang source-instrumentation-based coverage is available
163*333d2b36SAndroid Build Coastguard Worker[here](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#creating-coverage-reports).
164*333d2b36SAndroid Build Coastguard WorkerThe `llvm-cov` utility is used to show coverage from a `.profdata` file. The
165*333d2b36SAndroid Build Coastguard Workerdocumentation for commonly used `llvm-cov` command-line arguments is available
166*333d2b36SAndroid Build Coastguard Worker[here](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report). (Try
167*333d2b36SAndroid Build Coastguard Worker`llvm-cov show --help` for a complete list).
168*333d2b36SAndroid Build Coastguard Worker
169*333d2b36SAndroid Build Coastguard Worker#### `show` subcommand
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard WorkerThe `show` command displays the function and line coverage for each source file
172*333d2b36SAndroid Build Coastguard Workerin the binary.
173*333d2b36SAndroid Build Coastguard Worker
174*333d2b36SAndroid Build Coastguard Worker```
175*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-cov show \
176*333d2b36SAndroid Build Coastguard Worker        --show-region-summary=false
177*333d2b36SAndroid Build Coastguard Worker        --format=html --output-dir=coverage-html \
178*333d2b36SAndroid Build Coastguard Worker        --instr-profile=$MY_TEST.profdata \
179*333d2b36SAndroid Build Coastguard Worker        $MY_BIN \
180*333d2b36SAndroid Build Coastguard Worker```
181*333d2b36SAndroid Build Coastguard Worker
182*333d2b36SAndroid Build Coastguard Worker*   In the above command, `$MY_BIN` should be the unstripped binary (i.e. with
183*333d2b36SAndroid Build Coastguard Worker    debuginfo) since `llvm-cov` reads some debuginfo to process the coverage
184*333d2b36SAndroid Build Coastguard Worker    data.
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Worker    E.g.:
187*333d2b36SAndroid Build Coastguard Worker
188*333d2b36SAndroid Build Coastguard Worker    ~~~
189*333d2b36SAndroid Build Coastguard Worker    ```
190*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-cov report \
191*333d2b36SAndroid Build Coastguard Worker        --instr-profile=adbd.profdata \
192*333d2b36SAndroid Build Coastguard Worker        $LOCATION_OF_UNSTRIPPED_ADBD/adbd \
193*333d2b36SAndroid Build Coastguard Worker        --show-region-summary=false
194*333d2b36SAndroid Build Coastguard Worker    ```
195*333d2b36SAndroid Build Coastguard Worker    ~~~
196*333d2b36SAndroid Build Coastguard Worker
197*333d2b36SAndroid Build Coastguard Worker*   The `-ignore-filename-regex=<regex>` option can be used to ignore files that
198*333d2b36SAndroid Build Coastguard Worker    are not of interest. E.g: `-ignore-filename-regex="external/*"`
199*333d2b36SAndroid Build Coastguard Worker
200*333d2b36SAndroid Build Coastguard Worker*   Use the `--object=<BIN>` argument to specify additional binaries and shared
201*333d2b36SAndroid Build Coastguard Worker    libraries whose coverage is included in this profdata. See the earlier
202*333d2b36SAndroid Build Coastguard Worker    [section](#viewing-coverage-data-acov-llvm-py) for examples where more than
203*333d2b36SAndroid Build Coastguard Worker    one binary may need to be used.
204*333d2b36SAndroid Build Coastguard Worker
205*333d2b36SAndroid Build Coastguard Worker    E.g., the following command is used for `bionic-unit-tests`, which tests
206*333d2b36SAndroid Build Coastguard Worker    both `libc.so` and `libm.so`:
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Worker    ~~~
209*333d2b36SAndroid Build Coastguard Worker    ```
210*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-cov report \
211*333d2b36SAndroid Build Coastguard Worker        --instr-profile=bionic.profdata \
212*333d2b36SAndroid Build Coastguard Worker        $OUT/.../libc.so \
213*333d2b36SAndroid Build Coastguard Worker        --object=$OUT/.../libm.so
214*333d2b36SAndroid Build Coastguard Worker    ```
215*333d2b36SAndroid Build Coastguard Worker    ~~~
216*333d2b36SAndroid Build Coastguard Worker
217*333d2b36SAndroid Build Coastguard Worker*   `llvm-cov` also takes positional SOURCES argument to consider/display only
218*333d2b36SAndroid Build Coastguard Worker    particular paths of interest. E.g:
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Worker    ~~~
221*333d2b36SAndroid Build Coastguard Worker    ```
222*333d2b36SAndroid Build Coastguard Worker    <host>$ llvm-cov report \
223*333d2b36SAndroid Build Coastguard Worker        --instr-profile=adbd.profdata \
224*333d2b36SAndroid Build Coastguard Worker        $LOCATION_OF_ADBD/adbd \
225*333d2b36SAndroid Build Coastguard Worker        --show-region-summary=false \
226*333d2b36SAndroid Build Coastguard Worker        /proc/self/cwd/system/core/adb
227*333d2b36SAndroid Build Coastguard Worker    ```
228*333d2b36SAndroid Build Coastguard Worker    ~~~
229*333d2b36SAndroid Build Coastguard Worker
230*333d2b36SAndroid Build Coastguard WorkerNote that the paths for the sources need to be prepended with
231*333d2b36SAndroid Build Coastguard Worker'`/proc/self/cwd/`'. This is because Android C/C++ compilations run with
232*333d2b36SAndroid Build Coastguard Worker`PWD=/proc/self/cwd` and consequently the source names are recorded with that
233*333d2b36SAndroid Build Coastguard Workerprefix. Alternatively, the
234*333d2b36SAndroid Build Coastguard Worker[`--path-equivalence`](https://llvm.org/docs/CommandGuide/llvm-cov.html#cmdoption-llvm-cov-show-path-equivalence)
235*333d2b36SAndroid Build Coastguard Workeroption to `llvm-cov` can be used.
236*333d2b36SAndroid Build Coastguard Worker
237*333d2b36SAndroid Build Coastguard Worker#### `report` subcommand
238*333d2b36SAndroid Build Coastguard Worker
239*333d2b36SAndroid Build Coastguard WorkerThe [`report`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report)
240*333d2b36SAndroid Build Coastguard Workersubcommand summarizes the percentage of covered lines to the console. It takes
241*333d2b36SAndroid Build Coastguard Workeroptions similar to the `show` subcommand.
242