1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
|
-------------------------------------------------
- README file for the LTP GCOV extension (LCOV) -
- Last changes: 2024-12-25
-------------------------------------------------
Description
-----------
LCOV is a tool to manipulate and display information about what parts of a
program are actually executed (i.e. "covered") while running a particular test
case or set of testcases. LCOV consists of a set of Perl scripts which build on
the text output of various coverage tools - e.g., gcov, llvm-cov, Coverage.py,
Cobertura, Devel::Cover, Jacoco, etc. - to implement the following enhanced
functionality:
* HTML based output: coverage rates are indicated using bar
graphs and specific colors in a hyperlinked coverage report, intended
to enable the user to quickly diagnose and address coverage issues.
* Support for large projects: overview pages allow quick browsing of
coverage data by providing a hierarchical directory structure
view, a flat list of all source files in the project, or a three-level
detail view: directory, file and source code view.
* Support for multiple languages - including C/C++, Perl, and Python.
LCOV was initially designed to support Linux kernel coverage measurements,
but works as well for coverage measurements on standard user space
applications.
LCOV supports differential coverage, as well as date- and owner-binning.
See:
https://arxiv.org/abs/2008.07947
or
https://ieeexplore.ieee.org/document/9438597
for a detailed explanation of the concepts and several possible use models.
A video presentation of the basic ideas can be found at
http://doi.org/10.5281/zenodo.4653252
In addition, several other features and capabilities are available. See
section 6, below, for a brief description - and also see the man pages and
the test cases.
Further README contents
-----------------------
1. Included files
2. Installing LCOV
3. Dependencies
4. An example of how to access kernel coverage data
5. An example of how to access coverage data for a user space program
6. LCOV features
7. Questions and Comments
8. Filing a new issue
1. Important files
------------------
README - This README file
CHANGES - List of changes between releases
bin/lcov - Tool for capturing LCOV coverage data
bin/genhtml - Tool for creating HTML output from LCOV data
bin/gendesc - Tool for creating description files as used by genhtml
bin/perl2lcov - Tool to translate Perl Devel::Cover data to lcov format
bin/llvm2lcov - Tool to translate LLVM 'llvm-cov' JSON data to LCOV format
bin/py2lcov - Tool to translate Python Coverage.py to lcov format
bin/xml2lcov - Tool to translate Cobertura-like XML coverage data
to lcov format
bin/geninfo - Internal tool (creates LCOV data files)
bin/genpng - Internal tool (creates png overviews of source files)
lcovrc - LCOV configuration file
man - Directory containing man pages for included tools
example - Directory containing an example to demonstrate LCOV
tests - Directory containing lcov regression tests
Makefile - Makefile providing 'install' and 'uninstall' targets
2. Installing LCOV
------------------
The LCOV package is available as either RPM or tarball from:
https://github.com/linux-test-project/lcov/releases
To install the tarball, unpack it to a directory and run:
make install
Use Git for the most recent (but possibly unstable) version:
git clone https://github.com/linux-test-project/lcov.git
Change to the resulting lcov directory and type:
make install
The default install location is /usr/local. Note that you may need to
have superuser permissions to write into system directories.
To install in a different location - for example, your home directory, run:
make PREFIX=$HOME/my_lcov install
your PREFIX should be an absolute path.
To run the LCOV regression test suite on your installation:
$ cp -r $LCOV_HOME/share/test path/to/myTestDir
$ cd path/to/myTestDir
$ make [COVERAGE=1]
If desired, you can collect coverage data for the LCOV module by setting
the COVERAGE makefile variable.
Note that the Devel::Cover package must be installed if COVERAGE is enabled
or if you want to use the perl2lcov utility.
To view the collected coverage information, point your browser to
.../lcov_coverage/index.html after running the tests.
Note that the testcases are primarily intended to test LCOV functionality
and not to be easily readable tutorial examples.
3. Dependencies:
----------------
The lcov module is implemented primarily in Perl - and requires both a
moderately up-to-date Perl installation and multiple Perl packages.
These perl packages include:
- Capture::Tiny
- DateTime
- Devel::Cover
- Digest::MD5
- File::Spec
- at least one flavor of JSON module.
In order of performance/preference:
- JSON::XS
- Cpanel::JSON::XS
- JSON::PP
- JSON
- Memory::Process
- Module::Load::Conditional
- Scalar::Util
- Time::HiRes
- TimeDate
If your system is missing any of these, then you may be able to install them
via:
$ perl -MCPAN -e 'install(<packageName>)'
You will very likely need superuser access to be able to install Perl
modules.
Some of the applications provided with the lcov module are written
in Python - and may require additional Python packages.
In particular, 'xlsxwriter' is required in order to generate any
of the spreadsheet reports.
To measure Python code coverage, users will need Python packages:
- Coverage.py
In addition, contributors will need:
- perltidy
Your platform may support other mechanisms to install and/or update
required packages.
4. An example of how to access Linux kernel coverage data
---------------------------------------------------------
Requirements: Follow the Linux kernel coverage setup instructions at:
https://docs.kernel.org/dev-tools/gcov.html
As root, do the following:
a) Resetting counters
lcov --zerocounters
b) Capturing the current coverage state to a file
lcov --capture --output-file kernel.info
c) Getting HTML output
genhtml kernel.info
Point the web browser of your choice to the resulting index.html file.
5. An example of how to access coverage data for a user space program
---------------------------------------------------------------------
a) Capture current coverage state to a file:
i) C/C++ code:
Compile your program using the '--coverage' GCC or LLVM
option. During linking, make sure to specify '--coverage':
$ gcc -o myTest --coverage simple.c
OR
$ gcc -c file1.c file2.c ... --coverage
$ gcc -o myOtherTest --coverage file1.o file2.o ....
Alternately, LLVM users can use the 'profdata path' (rather than the
'gcov path') to collect coverage data from their C/C++ code. See
https://github.com/linux-test-project/lcov/discussions/234 for more
information.
Run your testcase at least once:
$ path/to/my/testcase/myTest
Capture the current coverage state to a file:
$ lcov --directory path/to/my/testcase --capture --output-file app.info
(LLVM users using the 'profdata path' will use a somewhat different
command for this step - see the discussion referenced above.)
If you want to collect Modified Condition / Decision Coverage (MD/DC)
date, then:
- you must use gcc/14.2 (or newer), or LLVM/18 (or newer)
- your GCC compile- and link command line must include flag
'-fcondition-coverage'.
- LLVM users must use the 'profdata path' for coverage data collection,
and your compile command line must include
'-fprofile-inst-generate -fcoverage-mapping -fcoverage-mcdc'.
See the above referenced discussion for details.
- your lcov and genhtml command line must include flag
'--mcdc-coverage'
See the '--mcdc-coverage' section in the genhtml and geninfo man pages.
Note that runtime coverage data exists only after the application has
been started and stopped at least once. Otherwise, no data will be found
and lcov will abort with an error mentioning that there are no
data/.gcda files.
The coverage runtime emits data (the .gcda files) in an atexit
callback. If your application exits abnormally or crashes before
the callback is executed, then no coverage data will be available.
For further information on the gcc profiling mechanism, please
consult the gcov man page.
See 'man lcov' for more information - especially if your build/test
environment is not trivial.
ii) Python code:
- install the Coverage.py module
- execute your testcase to produce python coverage data:
$ COVERAGE_FILE=./pycov.dat coverage run --append --branch \
myPythonScript [my script args]
- translate Python coverage data to LCOV format:
$ py2lcov -o pycov.info [py2lcov_options] pycov.dat [x.dat]+
See 'py2lcov --help' and the Coverage.py documentation for more
information.
iii) Perl code:
- install the Devel::Cover module
- execute your testcase to produce perl coverage data:
$ perl -MDevel::Cover=-db,perlcov_db,-coverage,statement,branch,condition,subroutine,-silent,1 myPerlTest.pl [my script args]
- translate Perl coverage data to LCOV format:
$ perl2lcov --output perlcov.info perlcov_db [perl2lcov options]
See 'perl2lcov --help' and the Devel::Cover documentation for more
information.
iv) XML data (for example, generated by Cobertura):
- translate XM coverage data to LCOV format:
$ xml2lcov --output myData.info coverage.xml [xml2lcov options]
See 'xml2lcov --help' and the Cobertura documentation for more
information.
b) Generate an HTML coverage report:
Generate an HTML report, combining all of your LCOV data files:
$ genhtml -o html_report app.info pycov.info perlcov.info
Point the web browser of your choice to the resulting file:
html_report/index.html.
See 'man genhtml' for more details.
c) Generate a differential coverage report:
See the example in .../example (run "make test_differential")
as well as the examples in .../tests/gendiffcov.
6. LCOV Features:
-----------------
LCOV features and capabilities fall into 7 major categories:
a) Categorization
This refers primarily to differential coverage categorization as
well as date- and owner-binning. See https://arxiv.org/abs/2008.07947
or https://ieeexplore.ieee.org/document/9438597 for a detailed
description of the concepts.
Differential categorization and binning are orthogonal in the sense
that you can generate differential report without binning as well
as 'vanilla' coverage reports with binning. See the above papers
and the genhtml man page for details.
Related options:
--baseline-file, --diff-file, --annotate-script, --select-script
--date-bins, --date-labels --new-file-as-baseline,
--elide-path-mismatch
b) Error handling
A generic - but very simple - error handler has been added to the
lcov tool suite. The error handler is used to report exceptions,
and provides a mechanism for the user to ignore the particular
message if desired. Note that ignoring certain errors can cause
subsequent errors and/or can result in inconsistent or confusing
coverage reports.
See the genhtml/lcov/geninfo man pages for details.
Note that some errors are unrecoverable - and cannot be suppressed or
ignored.
Related options:
--ignore-error, --expect-message-count, --keep-going, --msg-log
c) Navigation and display:
Navigation aids such as hyperlinks to the first uncovered region,
to the next uncovered region, etc. have been implemented. Similarly,
new tables, new columns, and new links between tables enable the
user to identify the author of particular code (covered or not
covered), as well as the time period when the code was written.
Collectively, these features help the user to quickly identify the
cause of code coverage issues, and to then decide what to do.
An option to generate a 'hierarchical' coverage report (which follows
the source code directory structure) or 'flat' (all files in top level
of two-level report) as well as various other small features (tooltip
popups, user-specified HTML header, footer, and table labels, etc.) are
also available.
See the genhtml man page for some details, as well as the
'gendiffcov/simple' testcases for some examples.
Related options:
--baseline-title, --baseline-date, --current-date,
--flat, --hierarchical,
--show-owners, --show-noncode, --show-navigation, --show-proportion,
--suppress-aliases
d) Data manipulation
Filters are used to suppress or remove certain coverage artifacts -
for example, branches generated by the compiler (e.g., for exception
handling). These artifacts can overwhelm the user code and obscure
coverage features that are interesting to the user.
Other options are used to focus on or to exclude certain sections
of code, as well as to do regexp replacement of file names - possibly
using case-insensitive comparison.
(Path munging is useful primarily when the build structure does
not exactly match the layout in your revision control system; this
is common in large projects with reusable components.)
During coverage data capture, the --build-directory option can be used
to specify a search path, to find the .gcno (compile-time coverage data)
file corresponding to a particular .gcda (runtime coverage data) file.
Similarly, the --source-directory option can be used to specify a
search path for source files.
See the lcov/geninfo/genhtml man pages for a detailed description of
the available filters and manipulation features.
Related options:
--include, --exclude, --erase-functions, --omit-lines,
--substitute, --filter
--build-directory --source-directory
e) Callbacks/customization
The user can supply callbacks which are used to:
i) interface with the revision control system
Sample scripts:
- Perforce: see 'p4diff', 'p4annotate.pm', 'p4annotate'
- Git: see 'gitdiff', 'gitblame.pm', 'gitblame'
ii) verify that source code versions are compatible, and
Sample scripts: see 'get_signature', 'P4version.pm', 'getp4version',
'gitversion', 'gitversion.pm', and 'batchGitVersion.pm'
iii) enforce a desired code coverage criteria
Sample script: criteria.pm/criteria
iv) find source files in more complicated environments - where
simple substitutions become complicated or unweildy.
v) select a subset of coverage data to display - e.g., to
use in a code review which wants to concentrate on only
the changes caused by a particular commit or range of commits,
or to review changes in a particular release.
Sample script: select.pm
vi) keep track of environment and other settings - to aid
infrastructure debugging in more complicated use cases.
The callback may be any desired script or executable - but there
may be performance advantages if it is written as a Perl module.
See the genhtml/lcov/geninfo man pages for details.
Note that the various sample scripts are found in the source code
'scripts' directory, but are installed in the
$LCOV_HOME/share/lcov/support-scripts directory of the release.
Related options:
--annotate-script, --criteria-script, --version-script
--resolve-script, --select-script, --context-script
f) Performance
lcov/genhtml/geninfo have been refactored to parallelize computation
across multiple cores, if requested.
In general, this provides speedup that is nearly linear in the number
of cores.
There is also an option to throttle parallelism to not exceed peak
memory consumption constraints, as well as options to enable simple
profile data collection - so you can see where time is going and
thus to hint at potential optimizations. The 'spreadsheet.py'
script can be used to view generated profile data.
There are several configuration file options which can be used to
tweak certain parallelization parameters to optimize performance
for your environment in cases that the default behaviour is suboptimal.
See the lcovrc man page for more information.
See the genhtml/lcov/geninfo man pages for details
Related options: --parallel, --memory, --profile
g) Language/tool support
Added 'llvm2lcov', 'py2lcov', 'perl2lcov' and 'xml2lcov' scripts.
- llvm2lcov:
translates JSON coverage data generated by 'llvm-cov export -format=text ...'
to lcov format.
See "llvm2lcov --help" for brief instruction on how to use the
translator. Note that llvm2lcov uses a similar set of command line
and configuration file options as lcov, genhtml, and geninfo.
- py2lcov:
translates python Coverage.py XML data to lcov format.
See the Coverage.py documentation at https://coverage.readthedocs.io,
as well as ".../py2lcov --help"
- perl2lcov
translates Perl Devel::Cover data to lcov format.
See the Devel::Cover documentation at
https://metacpan.org/pod/Devel::Cover
to find out how to generate coverage data for Perl code.
See "perl2lcov --help" for brief instructions on how to
use the translator.
Note that perl2lcov uses a similar set of command line and
config file options as lcov, genhtml, and geninfo.
- xml2lcov
translates XML coverage data to lcov format.
The XML data may come from Cobertura or similar tools.
See "xml2lcov --help" for brief instructions on how to use
the translator.
See the Coburtura documentation for directions on how to
generate XML data.
Other languages can be integrated using a similar approach.
In general, the new features and options are implemented uniformly in lcov,
genhtml, and geninfo. Most of the features can be enabled/disabled
using either command line options or by setting defaults in your 'lcovrc'
file. See the lcovrc man page for details.
7. Questions and comments
-------------------------
See the included man pages for more information on how to use the LCOV tools.
In case of further questions, feel free to open a new issue or discussion using
the issue tracker on the LCOV code repository site at:
https://github.com/linux-test-project/lcov
8. Filing a new issue
---------------------
Before filing a new issue - and if you are using an LCOV release (as opposed
to using a clone of the github repo) - please verify whether the issue is
still present in the LCOV master version. See section 2, above for
directions on how to clone and install the most up-to-date LCOV version.
If possible, please include a testcase which illustrates the problem
when you file an issue.
Please describe your environment (platform, compiler, perl, and python
versions, etc.). Please include a detailed description of the issue:
what you were trying to do (your goal - not the mechanics of your
procedure), what you did (the mechanics of your procedure), the result
you wanted to see vs. what actually happened.
Depending on the issue, your testcase may need to include source code and
compile/link command lines, directions for how to run your example, the
command lines used to capture and generate your lcov reports, etc.
In other cases, the captured '.info' files may be sufficient to reproduce
the issue.
When in doubt: more is better than less.
If you cannot include a testcase - e.g., because you feel that it is
senstitive or proprietary - then your detailed description is even more
important.
Note that, without an example, it may be difficult or impossible to
diagnose or fix the problem.
Bear in mind that you are asking for help from volunteers. Your
priority might not be their priority. Civility, consideration and politeness
go a long way.
Please check back and to verify the fix and close the issue once it has
been addressed.
Again: remember that you are asking for help from volunteers.
Make sure that you are doing your part.
|