Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 1 | # Code Coverage in Chromium |
| 2 | |
Prakhar | e84bb3b | 2021-11-29 03:28:44 | [diff] [blame] | 3 | ### Coverage Dashboard: [link](https://analysis.chromium.org/coverage/p/chromium) |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 4 | |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 5 | Table of contents: |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 6 | |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 7 | - [Coverage Infrastructure](#coverage-infra) |
| 8 | * [Coverage Builders](#coverage-builders) |
| 9 | * [Coverage Service](#coverage-service) |
| 10 | * [Coverage Clients](#coverage-clients) |
Roberto Carrillo | bc1560e | 2019-01-30 20:08:58 | [diff] [blame] | 11 | - [Local Coverage Script](#local-coverage-script) |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 12 | * [Step 0 Download Tooling](#step-0-download-tooling) |
| 13 | * [Step 1 Build](#step-1-build) |
| 14 | * [Step 2 Create Raw Profiles](#step-2-create-raw-profiles) |
| 15 | * [Step 3 Create Indexed Profile](#step-3-create-indexed-profile) |
| 16 | * [Step 4 Create Coverage Reports](#step-4-create-coverage-reports) |
Arthur Wang | 3cae925 | 2024-08-27 19:47:23 | [diff] [blame] | 17 | - [Read The Artifact](#read-the-artifact) |
Arthur Wang | 7eb6a48 | 2024-08-27 20:10:09 | [diff] [blame] | 18 | * [HTML report](#html-report) |
| 19 | * [lcov report](#lcov-report) |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 20 | - [Contacts](#contacts) |
| 21 | - [FAQ](#faq) |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 22 | |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 23 | |
Arthur Wang | 3cae925 | 2024-08-27 19:47:23 | [diff] [blame] | 24 | This document is divided into two parts. |
Prakhar | f41864b0 | 2022-07-18 19:03:51 | [diff] [blame] | 25 | - The first part introduces the code coverage infrastructure that |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 26 | continuously generates code coverage information for the whole codebase and for |
| 27 | specific CLs in Gerrit. For the latter, refer to |
Roberto Carrillo | 5221fc1 | 2019-01-30 21:34:50 | [diff] [blame] | 28 | [code\_coverage\_in\_gerrit.md](code_coverage_in_gerrit.md). |
Prakhar | f41864b0 | 2022-07-18 19:03:51 | [diff] [blame] | 29 | - The second part talks about how to generate code coverage locally for Clang-compiled languages like C++. Refer to [android code coverage instructions] for instructions for java code. |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 30 | |
| 31 | ## Coverage Infrastructure |
| 32 | |
| 33 | ![coverage infra diagram] |
| 34 | |
| 35 | There are 3 layers in the system: |
| 36 | |
| 37 | ### Coverage Builders |
| 38 | |
| 39 | The first layer is the LUCI builders that |
| 40 | - build instrumented targets, |
| 41 | - run the instrumented tests, |
| 42 | - merge the results into single streams, |
| 43 | - upload data to cloud storage. |
| 44 | |
| 45 | There are two types of builder: |
| 46 | |
| 47 | CI Builder |
| 48 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 49 | The code coverage CI Builders periodically build all the test targets and fuzzer |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 50 | targets for a given platform and instrument all available source files. Then |
| 51 | save the coverage data to a dedicated storage bucket. |
| 52 | |
| 53 | CQ Builder |
| 54 | |
| 55 | The code coverage CQ builders instrument only the files changed for a given CL. |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 56 | More information about per-cl coverage info in [this |
Roberto Carrillo | 5221fc1 | 2019-01-30 21:34:50 | [diff] [blame] | 57 | doc](code_coverage_in_gerrit.md). |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 58 | |
| 59 | ### Coverage Service |
| 60 | |
| 61 | The second layer in the system consists of an AppEngine application that |
| 62 | consumes the coverage data from the builders above, structures it and stores it |
| 63 | in cloud datastore. It then serves the information to the clients below. |
| 64 | |
| 65 | ### Coverage Clients |
| 66 | |
| 67 | In the last layer we currently have two clients that consume the service: |
| 68 | |
| 69 | #### Coverage Dashboard |
| 70 | |
| 71 | The [coverage dashboard] front end is hosted in the same application as the |
| 72 | service above. |
| 73 | It shows the full-code coverage reports with links to the builds that generated |
| 74 | them, as well as per-directory and per-component aggregation, and can be drilled |
| 75 | down to the single line of code level of detail. |
| 76 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 77 | Refer to the following screenshots: |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 78 | |
| 79 | ##### Directory View |
| 80 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 81 | See coverage breakdown by directories (default landing page). |
| 82 | |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 83 | ![coverage dashboard directory view] |
| 84 | |
| 85 | ##### Component View |
| 86 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 87 | Use the view dropdown menu to switch between directory and component. |
| 88 | |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 89 | ![coverage dashboard component view] |
| 90 | |
| 91 | ##### Source View |
| 92 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 93 | Click on a particular source file in one of the views above to see line-by-line |
| 94 | coverage breakdown, and it's useful to identify: |
| 95 | - Uncovered lines and code blocks that lack test coverage. |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 96 | - Potentially dead code. See [dead code example]. |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 97 | - Hot spots in your code. |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 98 | |
| 99 | ![coverage dashboard file view] |
| 100 | |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 101 | ##### Project View |
| 102 | |
| 103 | Click on "Previous Reports" to check out the coverage history of the project. |
| 104 | |
| 105 | ![coverage dashboard link to previous reports] |
| 106 | |
| 107 | List of historical coverage reports are in reverse chronological order. |
| 108 | |
| 109 | ![coverage dashboard previous reports] |
| 110 | |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 111 | #### Gerrit Coverage View |
| 112 | |
| 113 | The other client supported at the moment is the gerrit plugin for code coverage. |
| 114 | |
| 115 | ![gerrit coverage view] |
| 116 | |
| 117 | See [this doc](code_coverage_in_gerrit.md) for information about the feature |
| 118 | that allows gerrit to display code coverage information generated for a given CL |
| 119 | by CQ bot. Or see this |
Roberto Carrillo | 5221fc1 | 2019-01-30 21:34:50 | [diff] [blame] | 120 | [15-second video tutorial](https://www.youtube.com/watch?v=cxXlYcSgIPE). |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 121 | |
Roberto Carrillo | bc1560e | 2019-01-30 20:08:58 | [diff] [blame] | 122 | ## Local Coverage Script |
Prakhar | f41864b0 | 2022-07-18 19:03:51 | [diff] [blame] | 123 | This [documentation] explains how to use Clang’s source-based coverage |
| 124 | features in general. The [coverage script] automates the process described below and provides a |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 125 | one-stop service to generate code coverage reports locally in just one command. |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 126 | |
Ben Joyce | 8828236 | 2021-01-29 23:53:31 | [diff] [blame] | 127 | This script is currently supported on Android, Linux, Mac, iOS and ChromeOS |
| 128 | platforms. |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 129 | |
| 130 | Here is an example usage: |
| 131 | |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 132 | ``` |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 133 | $ gn gen out/coverage \ |
Bryce Thomas | c9137cf | 2020-03-31 19:47:17 | [diff] [blame] | 134 | --args="use_clang_coverage=true is_component_build=false |
| 135 | dcheck_always_on=true is_debug=false" |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 136 | $ python tools/code_coverage/coverage.py \ |
| 137 | crypto_unittests url_unittests \ |
| 138 | -b out/coverage -o out/report \ |
| 139 | -c 'out/coverage/crypto_unittests' \ |
| 140 | -c 'out/coverage/url_unittests --gtest_filter=URLParser.PathURL' \ |
| 141 | -f url/ -f crypto/ |
| 142 | ``` |
| 143 | The command above builds `crypto_unittests` and `url_unittests` targets and then |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 144 | runs them individually with their commands and arguments specified by the `-c` flag. |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 145 | For `url_unittests`, it only runs the test `URLParser.PathURL`. The coverage report |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 146 | is filtered to include only files and sub-directories under `url/` and `crypto/` |
| 147 | directories. |
| 148 | |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 149 | Aside from automating the process, this script provides visualization features to |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 150 | view code coverage breakdown by directories and by components, similar to the |
| 151 | views in the [coverage dashboard](#coverage-dashboard) above. |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 152 | |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 153 | ## Workflow |
| 154 | This section presents the workflow of generating code coverage reports using two |
| 155 | unit test targets in Chromium repo as an example: `crypto_unittests` and |
| 156 | `url_unittests`, and the following diagram shows a step-by-step overview of the |
| 157 | process. |
| 158 | |
| 159 |  |
| 160 | |
| 161 | ### Step 0 Download Tooling |
| 162 | Generating code coverage reports requires llvm-profdata and llvm-cov tools. |
Arthur Wang | 3cae925 | 2024-08-27 19:47:23 | [diff] [blame] | 163 | You can get them by adding `"checkout_clang_coverage_tools": True,` to |
Zequan Wu | 6d00cccd | 2021-03-15 22:40:44 | [diff] [blame] | 164 | `custom_vars` in the `.gclient` config and run `gclient runhooks`. You can also |
| 165 | download the tools manually ([tools link]) |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 166 | |
| 167 | ### Step 1 Build |
| 168 | In Chromium, to compile code with coverage enabled, one needs to add |
Yuke Liao | 8c0868fe6 | 2019-10-22 21:02:33 | [diff] [blame] | 169 | `use_clang_coverage=true`, `is_component_build=false` and `is_debug=false` GN |
| 170 | flags to the args.gn file in the build output directory. Under the hood, they |
| 171 | ensure `-fprofile-instr-generate` and `-fcoverage-mapping` flags are passed to |
| 172 | the compiler. |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 173 | |
| 174 | ``` |
| 175 | $ gn gen out/coverage \ |
Yuke Liao | 8c0868fe6 | 2019-10-22 21:02:33 | [diff] [blame] | 176 | --args='use_clang_coverage=true is_component_build=false is_debug=false' |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 177 | $ gclient runhooks |
Max Moroz | f5b31fcd | 2018-08-10 21:55:48 | [diff] [blame] | 178 | $ autoninja -C out/coverage crypto_unittests url_unittests |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 179 | ``` |
| 180 | |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 181 | ### Step 2 Create Raw Profiles |
Yuke Liao | bc35726b | 2018-10-31 22:16:21 | [diff] [blame] | 182 | The next step is to run the instrumented binaries. When the program exits, it |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 183 | writes a raw profile for each process. Because Chromium runs tests in |
| 184 | multiple processes, the number of processes spawned can be as many as a few |
| 185 | hundred, resulting in the generation of a few hundred gigabytes’ raw |
| 186 | profiles. To limit the number of raw profiles, `%Nm` pattern in |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 187 | `LLVM_PROFILE_FILE` environment variable is used to run tests in multi-process |
| 188 | mode, where `N` is the number of raw profiles. With `N = 4`, the total size of |
Ben Joyce | 8828236 | 2021-01-29 23:53:31 | [diff] [blame] | 189 | the raw profiles are limited to a few gigabytes. (If working on Android, the |
| 190 | .profraw files will be located in ./out/coverage/coverage by default.) |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 191 | |
Alan Zhao | f8fa3130 | 2024-01-11 03:35:39 | [diff] [blame] | 192 | Additionally, we also recommend enabling the continuous mode by adding the `%c` |
| 193 | pattern to `LLVM_PROFILE_FILE`. The continuous mode updates counters in real |
| 194 | time instead of flushing to disk at process exit. This recovers coverage data |
| 195 | from tests that exit abnormally (e.g. death tests). Furthermore, the continuous |
| 196 | mode is required to recover coverage data for tests that run in sandboxed |
| 197 | processes. For more information, see crbug.com/1468343. |
| 198 | |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 199 | ``` |
Alan Zhao | f8fa3130 | 2024-01-11 03:35:39 | [diff] [blame] | 200 | $ export LLVM_PROFILE_FILE="out/report/crypto_unittests.%4m%c.profraw" |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 201 | $ ./out/coverage/crypto_unittests |
| 202 | $ ls out/report/ |
| 203 | crypto_unittests.3657994905831792357_0.profraw |
| 204 | ... |
| 205 | crypto_unittests.3657994905831792357_3.profraw |
| 206 | ``` |
| 207 | |
| 208 | ### Step 3 Create Indexed Profile |
| 209 | Raw profiles must be indexed before generating code coverage reports, and this |
| 210 | is done using the `merge` command of `llvm-profdata` tool, which merges multiple |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 211 | raw profiles (.profraw) and indexes them to create a single profile (.profdata). |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 212 | |
| 213 | At this point, all the raw profiles can be thrown away because their information |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 214 | is already contained in the indexed profile. |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 215 | |
| 216 | ``` |
| 217 | $ llvm-profdata merge -o out/report/coverage.profdata \ |
| 218 | out/report/crypto_unittests.3657994905831792357_0.profraw |
| 219 | ... |
| 220 | out/report/crypto_unittests.3657994905831792357_3.profraw |
| 221 | out/report/url_unittests.714228855822523802_0.profraw |
| 222 | ... |
| 223 | out/report/url_unittests.714228855822523802_3.profraw |
| 224 | $ ls out/report/coverage.profdata |
| 225 | out/report/coverage.profdata |
| 226 | ``` |
| 227 | |
| 228 | ### Step 4 Create Coverage Reports |
| 229 | Finally, `llvm-cov` is used to render code coverage reports. There are different |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 230 | report generation modes, and all of them require the following as input: |
| 231 | - Indexed profile |
| 232 | - All built target binaries |
Roberto Carrillo | 5221fc1 | 2019-01-30 21:34:50 | [diff] [blame] | 233 | - All exercised source files |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 234 | |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 235 | For example, the following command can be used to generate per-file line-by-line |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 236 | code coverage report: |
| 237 | |
| 238 | ``` |
| 239 | $ llvm-cov show -output-dir=out/report -format=html \ |
| 240 | -instr-profile=out/report/coverage.profdata \ |
Choongwoo Han | 5675252 | 2021-06-10 17:38:34 | [diff] [blame] | 241 | -compilation-dir=out/coverage \ |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 242 | -object=out/coverage/url_unittests \ |
| 243 | out/coverage/crypto_unittests |
| 244 | ``` |
| 245 | |
Ben Joyce | 8828236 | 2021-01-29 23:53:31 | [diff] [blame] | 246 | If creating a report for Android, the -object arg would be the lib.unstripped |
| 247 | file, ie out/coverage/lib.unstripped/libcrypto_unittests__library.so |
| 248 | |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 249 | For more information on how to use llvm-cov, please refer to the [guide]. |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 250 | |
Arthur Wang | 3cae925 | 2024-08-27 19:47:23 | [diff] [blame] | 251 | ## Read The Artifact |
| 252 | |
| 253 | The code coverage tool generates some artifacts, and it is good to |
| 254 | understand the data format to be used by automation tools. |
| 255 | |
| 256 | ### HTML Report |
| 257 | |
| 258 | If the argument `--format=html` is used in the `llvm-cov export` command, it |
| 259 | generates a report in html format. In this html report, it shows the source |
| 260 | files, lists the functions and coverage metadata on whether the functions are |
| 261 | executed or not. |
| 262 | |
| 263 | Reading a html report is straightforward: Just open up this html page with a |
| 264 | Chrome browser. |
| 265 | |
| 266 | ### lcov Report |
| 267 | |
| 268 | If the argument `--format=lcov` is used in the `llvm-cov export` command, it |
| 269 | generates a report in lcov format. |
| 270 | |
| 271 | In the lcov file, the meaning of these keywords are listed below. |
| 272 | |
| 273 | * `SF`: source file name (typically beginning of one record) |
| 274 | * `FN`: mangled function symbol |
| 275 | * `FNDA`: functions execution |
| 276 | * `FNF`: functions found |
| 277 | * `FNH`: functions hit |
| 278 | * `DA`: lines executed |
| 279 | * `BRH`: branches hit |
| 280 | * `BRF`: branches found |
| 281 | * `LH`: lines hit |
| 282 | * `LF`: lines found |
| 283 | * `end_of_record` end of one record |
| 284 | |
| 285 | The number right after `FN` indicates the starting line number of this function. |
| 286 | The number right after `FNDA` indicates the total number of execution of this |
| 287 | function. |
| 288 | |
| 289 | In the following example record, it means that function `_ZN4apps18AppLifetimeMonitorC2EPN7content14BrowserContextE` is defined at line |
| 290 | 21 in file `app_lifetime_monitor.cc` and it is executed once. |
| 291 | |
| 292 | ``` |
| 293 | SF:../../chromium/src/apps/app_lifetime_monitor.cc |
| 294 | FN:21,_ZN4apps18AppLifetimeMonitorC2EPN7content14BrowserContextE |
| 295 | FN:32,_ZN4apps18AppLifetimeMonitorD2Ev |
| 296 | FNDA:1,_ZN4apps18AppLifetimeMonitorC2EPN7content14BrowserContextE |
| 297 | FNF:7 |
| 298 | FNH:1 |
| 299 | DA:34,0 |
| 300 | BRF:0 |
| 301 | BRH:0 |
| 302 | LF:5 |
| 303 | LH:1 |
| 304 | end_of_record |
| 305 | ``` |
| 306 | |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 307 | ## Contacts |
| 308 | |
| 309 | ### Reporting problems |
Yuke Liao | d3b4627 | 2018-03-14 18:25:14 | [diff] [blame] | 310 | For any breakage report and feature requests, please [file a bug]. |
| 311 | |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 312 | ### Mailing list |
Yuke Liao | bc35726b | 2018-10-31 22:16:21 | [diff] [blame] | 313 | For questions and general discussions, please join [code-coverage group]. |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 314 | |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 315 | ## FAQ |
| 316 | |
| 317 | ### Can I use `is_component_build=true` for code coverage build? |
| 318 | |
| 319 | Yes, code coverage instrumentation works with both component and non-component |
| 320 | builds. Component build is usually faster to compile, but can be up to several |
| 321 | times slower to run with code coverage instrumentation. For more information, |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 322 | see [crbug.com/831939]. |
| 323 | |
| 324 | ### I am getting some warnings while using the script, is that fine? |
| 325 | |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 326 | Usually this is not a critical issue, but in general we tend not to have any |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 327 | warnings. Please check the list of [known issues], and if there is a similar |
| 328 | bug, leave a comment with the command you run, the output you get, and Chromium |
Yuke Liao | 03c64407 | 2019-07-30 18:33:40 | [diff] [blame] | 329 | revision you use. Otherwise, please [file a bug] providing the same information. |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 330 | |
| 331 | ### How do crashes affect code coverage? |
| 332 | |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 333 | If a crash of any type occurs (e.g. Segmentation Fault or ASan error), the |
| 334 | crashing process might not dump coverage information necessary to generate |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 335 | code coverage report. For single-process applications (e.g. fuzz targets), that |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 336 | means no coverage might be reported at all. For multi-process applications, the |
| 337 | report might be incomplete. It is important to fix the crash first. If this is |
Abhishek Arya | af9811f2 | 2018-05-11 22:17:48 | [diff] [blame] | 338 | happening only in the coverage instrumented build, please [file a bug]. |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 339 | |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 340 | ### How do assertions affect code coverage? |
| 341 | |
| 342 | If a crash is caused by CHECK or DCHECK, the coverage dump will still be written |
| 343 | on the disk ([crrev.com/c/1172932]). However, if a crashing process calls the |
| 344 | standard [assert] directly or through a custom wrapper, the dump will not be |
| 345 | written (see [How do crashes affect code coverage?]). |
| 346 | |
Max Moroz | 63cd04d | 2018-05-02 16:40:23 | [diff] [blame] | 347 | ### Is it possible to obtain code coverage from a full Chromium build? |
| 348 | |
| 349 | Yes, with some important caveats. It is possible to build `chrome` target with |
| 350 | code coverage instrumentation enabled. However, there are some inconveniences |
| 351 | involved: |
| 352 | |
Kai Ninomiya | 6f537eb | 2023-01-04 23:43:47 | [diff] [blame] | 353 | * Linking may take a while, especially if you use a non-component build. |
| 354 | * The binary is huge (2-4GB). |
| 355 | * The browser may be noticeably slow and laggy. |
Max Moroz | 63cd04d | 2018-05-02 16:40:23 | [diff] [blame] | 356 | |
| 357 | For more information, please see [crbug.com/834781]. |
| 358 | |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 359 | ### Why do we see significantly different coverage reported on different revisions? |
| 360 | |
| 361 | There can be two possible scenarios: |
| 362 | |
| 363 | * It can be a one time flakiness due to a broken build or failing tests. |
| 364 | * It can be caused by extension of the test suite used for generating code |
| 365 | coverage reports. When we add new tests to the suite, the aggregate coverage |
| 366 | reported usually grows after that. |
| 367 | |
| 368 | ### How can I improve [coverage dashboard]? |
| 369 | |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 370 | The code for the service and dashboard currently lives along with findit at |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 371 | [this location](https://chromium.googlesource.com/infra/infra/+/main/appengine/findit/) |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 372 | because of significant shared logic. |
| 373 | |
| 374 | The code used by the bots that generate the coverage data lives (among other |
| 375 | places) in the |
John Palmer | 046f987 | 2021-05-24 01:24:56 | [diff] [blame] | 376 | [code coverage recipe module](https://chromium.googlesource.com/chromium/tools/build/+/main/scripts/slave/recipe_modules/code_coverage/). |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 377 | |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 378 | ### Why is coverage for X not reported or unreasonably low, even though there is a test for X? |
| 379 | |
| 380 | There are several reasons why coverage reports can be incomplete or incorrect: |
| 381 | |
| 382 | * A particular test is not used for code coverage report generation. Please |
Roberto Carrillo | 5221fc1 | 2019-01-30 21:34:50 | [diff] [blame] | 383 | [file a bug]. |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 384 | * A test may have a build failure or a runtime crash. Please check the build |
| 385 | for that particular report (rightmost column on the [coverage dashboard]). |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 386 | If there is any failure, please upload a CL with the fix. If you can't fix it, |
| 387 | feel free to [file a bug]. |
| 388 | * A particular test may not be available on a particular platform. As of now, |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 389 | only reports generated on Linux and CrOS are available on the |
| 390 | [coverage dashboard]. |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 391 | |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 392 | ### Is coverage reported for the code executed inside the sandbox? |
| 393 | |
Yuke Liao | 8c0868fe6 | 2019-10-22 21:02:33 | [diff] [blame] | 394 | Yes! |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 395 | |
Max Moroz | d73e45f | 2018-04-24 18:32:47 | [diff] [blame] | 396 | |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 397 | [assert]: http://man7.org/linux/man-pages/man3/assert.3.html |
Yuke Liao | bc35726b | 2018-10-31 22:16:21 | [diff] [blame] | 398 | [code-coverage group]: https://groups.google.com/a/chromium.org/forum/#!forum/code-coverage |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 399 | [code-coverage repository]: https://chrome-internal.googlesource.com/chrome/tools/code-coverage |
Prakhar | 74514ba | 2022-05-19 17:14:04 | [diff] [blame] | 400 | [coverage dashboard]: https://analysis.chromium.org/coverage/p/chromium |
Yuke Liao | 1ffc8cb6 | 2018-04-06 19:09:07 | [diff] [blame] | 401 | [coverage script]: https://cs.chromium.org/chromium/src/tools/code_coverage/coverage.py |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 402 | [coverage infra diagram]: images/code_coverage_infra_diagram.png |
| 403 | [coverage dashboard file view]: images/code_coverage_dashboard_file_view.png |
| 404 | [coverage dashboard component view]: images/code_coverage_dashboard_component_view.png |
| 405 | [coverage dashboard directory view]: images/code_coverage_dashboard_directory_view.png |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 406 | [coverage dashboard link to previous reports]: images/code_coverage_dashboard_link_to_previous_reports.png |
| 407 | [coverage dashboard previous reports]: images/code_coverage_dashboard_previous_reports.png |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 408 | [crbug.com/821617]: https://crbug.com/821617 |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 409 | [crbug.com/831939]: https://crbug.com/831939 |
Max Moroz | 63cd04d | 2018-05-02 16:40:23 | [diff] [blame] | 410 | [crbug.com/834781]: https://crbug.com/834781 |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 411 | [crrev.com/c/1172932]: https://crrev.com/c/1172932 |
Max Moroz | 3a92890 | 2018-05-15 14:39:50 | [diff] [blame] | 412 | [clang roll]: https://crbug.com/841908 |
Abhishek Arya | b23b1a7 | 2018-05-17 20:11:09 | [diff] [blame] | 413 | [dead code example]: https://chromium.googlesource.com/chromium/src/+/ac6e09311fcc7e734be2ef21a9ccbbe04c4c4706 |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 414 | [documentation]: https://clang.llvm.org/docs/SourceBasedCodeCoverage.html |
Yuke Liao | 03c64407 | 2019-07-30 18:33:40 | [diff] [blame] | 415 | [file a bug]: https://bugs.chromium.org/p/chromium/issues/entry?components=Infra%3ETest%3ECodeCoverage |
Yuke Liao | 43bbbcd5 | 2019-06-21 19:34:50 | [diff] [blame] | 416 | [gerrit coverage view]: images/code_coverage_annotations.png |
Max Moroz | c5e364a | 2018-04-25 23:19:49 | [diff] [blame] | 417 | [guide]: http://llvm.org/docs/CommandGuide/llvm-cov.html |
Max Moroz | a5a9527 | 2018-08-31 16:20:55 | [diff] [blame] | 418 | [How do crashes affect code coverage?]: #how-do-crashes-affect-code-coverage |
Yuke Liao | 03c64407 | 2019-07-30 18:33:40 | [diff] [blame] | 419 | [known issues]: https://bugs.chromium.org/p/chromium/issues/list?q=component:Infra%3ETest%3ECodeCoverage |
Roberto Carrillo | 3b56786 | 2019-01-30 19:01:25 | [diff] [blame] | 420 | [tools link]: https://storage.googleapis.com/chromium-browser-clang-staging/ |
Prakhar | f41864b0 | 2022-07-18 19:03:51 | [diff] [blame] | 421 | [android code coverage instructions]: https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/coverage.md |