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