GENINFO(1)
Okay bestie, this is geninfo(1) from the LCOV universe, and it's literally the manual page for geninfo. Buckle up, because this one is long and we are keeping every single detail. ๐
๐ NAME ๐
Yes, the page really has two NAME blocks, so here they both are, no cap:
geninfoโ geninfo documentationgeninfoโ Generate tracefiles from GCOV coverage data files
โจ SYNOPSIS โจ
geninfo
[-h | --help]
[--version]
[-q | --quiet]
[-v | --verbose]
[--debug]
[--comment *comment-string*]
[-i | --initial]
[--all]
[-t | --test-name *test-name*]
[-o | --output-filename *filename*]
[-f | --follow]
[-b | --base-directory *directory*]
[--build-directory *directory*]
[--branch-coverage]
[--mcdc-coverage]
[--checksum]
[--no-checksum]
[--compat-libtool]
[--no-compat-libtool]
[--gcov-tool *tool*]
[--parallel | -j [*integer*]]
[--large-file *regexp*]
[--memory *integer_num_Mb*]
[--msg-log [*log_file_name*]]
[--ignore-errors *errors*]
[--expect-message-count *message_type* = *expr* [,*message_type* = *expr* ..]]
[--keep-going]
[--preserve]
[--filter *type*]
[--demangle-cpp [param]]
[--no-recursion]
[--external]
[--no-external]
[--sort-input]
[--config-file *config-file*]
[--no-markers]
[--profile [*profile-file*]]
[--history-script *callback*]
[--compat *mode* = on|off|auto]
[--rc *keyword* = *value*]
[--include *glob_pattern*]
[--exclude *glob_pattern*]
[--erase-functions *regexp_pattern*]
[--substitute *regexp_pattern*]
[--omit-lines *regexp_pattern*]
[--fail-under-branches *percentage*]
[--fail-under-lines *percentage*]
[--forget-test-names]
[--context-script *script_file*]
[--criteria-script *script_file*]
[--resolve-script *script_file*]
[--version-script *script_file*]
[--unreachable-script *module_file*]
[--tempdir *dirname*]
*directory*
๐ฆ DESCRIPTION ๐ฆ
Use geninfo to create LCOV tracefiles from GCC and LLVM/Clang coverage data files. Heads up: see --gcov-tool for the considerations when you're working with LLVM. You can use genhtml to create an HTML report from a tracefile. ๐
Note that geninfo is called by lcov --capture, so there is typically no need to call it directly. Like, it's giving "middle management energy" โ it's doing important work behind the scenes. ๐
Unless the --output-filename option is specified, geninfo writes its output to one file with .info filename extension per input file.
Also note: the current user needs write access to both directory as well as to the original source code location. This is necessary because some temporary files have to be created there during the conversion process. So yeah, permissions check first, bestie. ๐
By default, geninfo collects line and function coverage data. Neither branch nor MC/DC data is collected by default; you can use the --branch-coverage and --mcdc-coverage command line options to enable them, or you can permanently enable them by adding branch_coverage = 1 and/or mcdc_coverage = 1 to your personal, group, or site lcov configuration file. See lcovrc(5) for details. โจ
๐ธ File types ๐ธ
A tracefile is a coverage data file in the format used by all LCOV tools such as geninfo, lcov, and genhtml. By convention, tracefiles have a .info filename extension. See โTracefile formatโ below for a description of the file format. ๐ฆ
A .gcda file is a compiler-specific file containing run-time coverage data. It is created and updated when a program compiled with GCC/LLVMโs --coverage option is run to completion. geninfo reads .gcda files in its default mode of operation. Note: earlier compiler versions used the .da filename extension for this file type. โญ
A .gcno file is a compiler-specific file containing static, compile-time coverage data. It is created when source code is compiled with GCC/LLVMโs --coverage option. geninfo reads .gcno files when option --initial is specified. Note: earlier compiler versions used .bb and .bbg filename extensions for this file type. ๐
A .gcov file is a textual or JSON representation of the data found in .gcda and .gcno files. It is created by the gcov tools that is part of GCC (see --gcov-tool for LLVM considerations). There are multiple gcov file format versions, including textual, intermediate, and JSON format. geninfo internally uses gcov to extract coverage data from .gcda and .gcno files using the best supported gcov file format. ๐
See the gcov man page for more information on .gcda, .gcno, and .gcov output formats.
๐ Exclusion markers ๐
To exclude specific lines of code from a tracefile, you can add exclusion markers to the source code. Similarly, you can mark specific regions of code as โunreachableโ. An โunreachableโ error message is generated if any coverpoints in unreachable regions are executed (i.e., have non-zero hit counts). See the retain_unreachable_coverpoints_if_executed section in lcovrc(1) for a description of the actions taken in this case. ๐ซถ
Additionally, you can exclude specific branches or MC/DC expressions without excluding the involved lines from line and function coverage.
Exclusion markers are keywords which can for example be added in the form of a comment. See lcovrc(5) for how to override the exclusion keywords (e.g., to reuse markers inserted for other tools or to generate reports with different sets of excluded regions). ๐
The following markers are recognized by geninfo:
LCOV_EXCL_LINEโ Lines containing this marker will be excluded.LCOV_EXCL_STARTโ Marks the beginning of an excluded section. The current line is part of this section.LCOV_EXCL_STOPโ Marks the end of an excluded section. The current line not part of this section.LCOV_UNREACHABLE_LINEโ If the marked line is โhitโ, then generate an error: we believe the marked code is unreachable and so there is a bug in the code, the placement of the directive, or both. Lines containing this marker will be excluded from reporting. Apart from error reporting, this directive is equivalent toLCOV_EXCL_LINE.LCOV_UNREACHABLE_STARTโ Marks the beginning of an unreachable section of code. The current line in part of this region. As described in theLCOV_UNREACHABLE_LINEsection, above: an error is generated if any code in the region is hit, but the code is excluded from reporting.LCOV_UNREACHABLE_STOPโ Marks the end of the region of unreachable code. The current line not part of this section.LCOV_EXCL_BR_LINEโ Lines containing this marker will be excluded from branch coverage.LCOV_EXCL_BR_STARTโ Marks the beginning of a section which is excluded from branch coverage. The current line is part of this section.LCOV_EXCL_BR_STOPโ Marks the end of a section which is excluded from branch coverage. The current line not part of this section.LCOV_EXCL_EXCEPTION_BR_LINEโ Lines containing this marker will be excluded from exception branch coverage: Exception branches will be ignored, but non-exception branches will not be affected.LCOV_EXCL_EXCEPTION_BR_STARTโ Marks the beginning of a section which is excluded from exception branch coverage. The current line is part of this section.LCOV_EXCL_EXCEPTION_BR_STOPโ Marks the end of a section which is excluded from exception branch coverage. The current line not part of this section.
In addition, geninfo also supports the --unreachable-script option. This provides a mechanism to exclude particular branch expressions and/or MC/DC conditions from coverage reports. A simple sample callback can be found in:
bin/unreach.pm
This sample callback adds support for branch-specific and condition-specific exclusion, specified by end-of-line annotations in the source code:
LCOV_EXCLUDE_BRANCH (expressionId[,blockId])+โ One or more space-separated branch exclusions may be specified.- expressionId: decimal integer which specifies which branch to exclude. An error is generated if the index is invalid.
- blockId: decimal integer which specifies the block index which contains the excluded expression. An error is generated if the block index is invalid. If there is only one branch block at this location, then the block ID does not need to be specified.
LCOV_UNREACHABLE_COND ([groupSize,]conditionId(t|f))+โ One or more space-separated MC/DC exclusions may be specified.- groupSize: decimal integer which specifies the group which contains the excluded condition. An error is generated if the groupSize is invalid. If there is only one MC/DC group at this location, then the groupSize does not need to be specified.
- conditionId: decimal integer which specifies which condition to exclude. An error is generated if the index is invalid.
- sense: โtโ or โfโ: the value of the condition which is unreachable.
For example, the line:
code // LCOV_EXCLUDE_BRANCH 0,1 3 LCOV_EXCLUDE_CONDITION 0f
will exclude branch expressions 1 and 3 from block 0 (or generate an error if there is more than one branch block on this line), and the โfalseโ sense of condition 0 (or generate an error if there is more than one MC/DC group on this line). ๐ญ๐ฅ
One way to determine the branch and/or condition ID in order to exclude them is to generate an HTML report without exclusions, then hover the mouse over the colorized branch/condition region and read the IDs from the tooltip popup. Another way is to simply read the BRDA/MCDC entries in coverage data file. ๐
See the comment at the top of the sample script for more details.
๐ฅ OPTIONS ๐ฅ
In general, (almost) all geninfo options can also be specified in your personal, group, project, or site configuration file โ see the --config-file section, below, and lcovrc(5) for details. โจ
-b,--base-directorydirectory โ bestie, this tells geninfo to use directory as the base directory for relative paths. ๐
Use this one to specify the base directory of a build-environment when geninfo starts screaming error messages like:
ERROR: could not read source file /home/user/project/subdir1/subdir2/subdir1/subdir2/file.c
In that example you'd use /home/user/project as the base directory. Iconic, honestly.
This option is required when you're using geninfo on projects built with libtool or similar build environments that work with a base directory โ meaning environments where the current working directory when invoking the compiler is not the same directory in which the source code file lives. ๐ซถ
Heads up though: this option will not work in environments where multiple base directories are used. In that case use the configuration file settinggeninfo_auto_base=1(seelcovrc(5)). No cap.
--build-directorybuild_dir โ search for.gcnodata files from build_dir instead of finding them only adjacent to the corresponding.oand/or.gcdafile. ๐
By default, geninfo expects to find the .gcno and .gcda files (compile- and run-time data, respectively) in the same directory.
When this option is used:
geninfo path1 --build-directory path2 ...
then geninfo will look for the .gcno file
path2/relative/path/to/da_base.gcno
when it finds the .gcda file
path1/relative/path/to/da_base.gcda.
Use this option when you've used the GCOV_PREFIX environment variable to direct the gcc or llvm runtime environment to write coverage data files to somewhere other than the directory where the code was originally compiled. See gcc(1) and/or search for GCOV_PREFIX and GCOV_PREFIX_STRIP. โจ
This option can be used several times to specify multiple alternate directories to look for .gcno files. Super useful if your application uses code compiled in many separate locations โ like common libraries shared between teams. ๐
--source-directorydirname โ adds dirname to the list of places to look for source files. ๐
For relative source file paths found in the gcov data โ possibly after substitutions have been applied โ geninfo will first look for the path from cwd (where genhtml was invoked) and then from each alternate directory name in the order specified. The first matching location is the one that gets used.
This option can be specified multiple times to add more directories to the source search path. Slay.
--branch-coverageโ collect and retain branch coverage data. ๐ฟ
This is equivalent to using the option --rc branch_coverage=1; the option was added to better match the genhtml interface.
--mcdc-coverageโ collect and retain MC/DC data. ๐ฅ
This is equivalent to using the option --rc mcdc_coverage=1. MC/DC coverage capture is supported for GCC versions 14.2 and higher, or LLVM versions 18.1 and higher.
See llvm2lcov --help for details on MC/DC data capture in LLVM.
See the MC/DC section of genhtml(1) for more details. ๐
--checksum,--no-checksumโ specify whether to generate checksum data when writing tracefiles. ๐งพ
Use --checksum to enable checksum generation or --no-checksum to disable it. Checksum generation is disabled by default.
When checksum generation is enabled, a checksum will be generated for each source code line and stored along with the coverage data. This checksum will be used to prevent attempts to combine coverage data from different source code versions.
If you don't work with different source code versions, disable this option to speed up coverage data processing and to reduce the size of tracefiles. Speed = self care, honestly. ๐
Note that this option is somewhat subsumed by the --version-script option โ which does something similar, but at the whole file level.
--compatmode = value [,mode = value,โฆ] โ set compatibility mode. ๐ ๏ธ
Use --compat to specify that geninfo should enable one or more compatibility modes when capturing coverage data. You can provide a comma-separated list of mode=value pairs to specify the values for multiple modes.
Valid values are:
onโ enable compatibility mode.offโ disable compatibility mode.autoโ apply auto-detection to determine if compatibility mode is required. Note that auto-detection is not available for all compatibility modes.
If no value is specified, on is assumed as the default value.
Valid modes are:
libtoolโ enable this mode if you're capturing coverage data for a project that was built using the libtool mechanism. See also--compat-libtool. The default value for this setting ison.hammerโ enable this mode if you're capturing coverage data for a project that was built using a version of GCC 3.3 that contains a modification (hammer patch) of later GCC versions. You can identify a modified GCC 3.3 by checking the build directory of your project for files ending in the extension.bbg. Unmodified versions of GCC 3.3 name these files.bb. The default value for this setting isauto.split_crcโ enable this mode if you're capturing coverage data for a project that was built using a version of GCC 4.6 that contains a modification (split function checksums) of later GCC versions. Typical error messages when running geninfo on coverage data produced by such GCC versions areout of memoryandreached unexpected end of file. The default value for this setting isauto.
--compat-libtool,--no-compat-libtoolโ specify whether to enable libtool compatibility mode. ๐งฐ
Use --compat-libtool to enable libtool compatibility mode or --no-compat-libtool to disable it. The libtool compatibility mode is enabled by default.
When libtool compatibility mode is enabled, geninfo will assume that the source code relating to a .gcda file located in a directory named .libs can be found in its parent directory.
If you have directories named .libs in your build environment but don't use libtool, disable this option to prevent problems when capturing coverage data. ๐
--config-fileconfig-file โ specify a configuration file to use. Seelcovrc(5)for details of the file format and options. Also see theconfig_fileentry in the same man page for details on how to include one config file into another. ๐
When this option is specified, neither the system-wide configuration file /etc/lcovrc, nor the per-user configuration file ~/.lcovrc is read.
This option may be useful when there's a need to run several instances of geninfo with different configuration file options in parallel.
Note that this option must be specified in full โ abbreviations are not supported. No shortcuts, bestie.
--profile[profile-data-file] โ tell the tool to keep track of performance and other configuration data. ๐ If the optional profile-data-file is not specified, then the profile data is written to a file named with the same basename as the--output-filename, with suffix.jsonappended.
Profile data is useful if you're trying to optimize the geninfo implementation (see $LCOV_ROOT/share/lcov/support-scripts/spreadsheet.py), and can also enable faster geninfo --parallel execution (see the --history-script section of this man page).
--history-scriptcallback โ tell the tool to use performance data from a prior job to predict resource usage by the current job. ๐ฎ This may allow better segmentation to enable more balanced workloads between parallel threads โ thus improving wall clock execution time.
A common source for the performance history is the previous-profile-data-file generated by the --profile argument.
See a sample callback implementation in $LCOV_ROOT/share/lcov/support-scripts/history.pm and its use in $LCOV_ROOT/share/lcov/example in the installed release (or .../example and .../scripts/history.pm in the source repository).
See genhtml(1) for more details. ๐ฆ
--external,--no-externalโ specify whether to capture coverage data for external source files. ๐
External source files are files which are not located in one of the directories specified by --directory or --base-directory. Use --external to include coverpoints in external source files while capturing coverage data or --no-external to exclude them. If your --directory or --base-directory path contains a soft link, then the actual target directory is not considered to be internal unless the --follow option is used.
The --no-external option is somewhat of a blunt instrument; the --exclude and --include options provide finer grained control over which coverage data is and is not included if your project structure is complex and/or --no-external doesn't do what you want.
Data for external source files is included by default. ๐
-f,--followโ follow links when searching.gcdafiles, as well as to decide whether a particular (symbolically linked) source directory is internal to the project or not โ see the--no-externaloption above for more info. ๐ The--followcommand line option is equivalent to thegeninfo_follow_symlinksconfig file option. Seelcovrc(5)for more information.--sort-inputโ bestie, this one controls whether file names get sorted before capture and/or aggregation. Why do we care? Because sorting reduces certain types of processing-order-dependent output differences โจ. See thesort_inputsection inlcovrc(5)<file://../man/lcovrc.5.html> for the deets.--gcov-tool toolโ tells geninfo where yourgcovtool lives ๐.
Okay so this one has lore. If you use --gcov-tool multiple times, the arguments get concatenated when the callback is executed โ kind of like how the gcc -Xlinker parameter works. It's a possibly easier way to pass arguments to your tool without needing a whole wrapper script. In that case, your callback gets executed as: tool-0 โtool-1; โฆ โfilenameโโ. Note that the second and subsequent arguments are quoted when passed to the shell, so parameters containing spaces are handled ๐ซถ.
The --gcov-tool argument may also be a split_char-separated string โ see man(4) lcovrc.
A common use for this option is to enable LLVM:
geninfo --gcov-tool llvm-cov --gcov-tool gcov ...
geninfo --gcov-tool llvm-cov,gcov ...
Note: โllvm-cov gcov da_file_nameโ will generate output in gcov-compatible format as required by lcov ๐
.
If you don't specify it, โgcovโ is used by default.
-h,--helpโ prints a short help text, then dips out. That's it, that's the whole vibe ๐.--include patternโ include source files matching pattern.
Use this switch when you want coverage data for only a particular set of source files matching any of the given patterns. Multiple patterns? Just use multiple --include command line switches, easy. The patterns are interpreted as shell wildcard patterns (and heads up: you may need to escape them accordingly so your shell doesn't expand them first ๐).
See the lcov man page for details.
--exclude patternโ exclude source files matching pattern.
Use this switch when you want to keep coverage data away from a particular set of source files matching any of the given patterns. Multiple patterns work the same way โ multiple --exclude command line switches. Same deal with shell wildcard patterns (escape accordingly to stop the shell expanding them first). Note: the pattern must be specified to match the absolute path of each source file โ ๏ธ.
Can be combined with the --include command line switch. But if a given file matches both the include pattern and the exclude pattern, the exclude pattern takes precedence โ exclude always wins, periodt.
See the lcov man page for details.
--erase-functions regexpโ exclude coverage data from lines which fall within a function whose name matches the supplied regexp. Note that this is a mangled or demangled name, depending on whether theโdemangle-cppoption is used or not ๐.
Note that this option requires that you use a gcc version which is new enough to support function begin/end line reports, or that you configure the tool to derive the required data โ see the derive_function_end_line discussion in the lcovrc man page.
--substitute regexp_patternโ applies the Perl regexp regexp_pattern to source file names found during processing. Super useful when the path name reported bygcovdoesn't match your source layout and the file is not found ๐ญ. See thelcovman page for more details.--omit-lines regexpโ exclude coverage data from lines whose content matches regexp.
Use this switch if you want to exclude line, branch, and MC/DC coverage data for some particular constructs in your code (e.g., some complicated macro). See the lcov man page for details.
--forget-test-namesโ if non-zero, ignore testcase names in the tracefile โ i.e., treat all coverage data as if it came from the same testcase. This may improve performance and reduce memory consumption if you don't need per-testcase coverage summary in your coverage reports ๐ง โจ.
This option can also be configured permanently using the configuration file option forget_testcase_names.
--msg-log [log_file_name]โ specify a location to store error and warning messages (in addition to writing toSTDERR). If log_file_name is not specified, then the default location is used ๐.--ignore-errors errorsโ specify a list of errors after which to continue processing.
Use this option to specify a list of one or more classes of errors after which geninfo should keep processing instead of aborting. Note that the tool will generate a warning (rather than a fatal error) unless you ignore the error two (or more) times:
geninfo ... --ignore-errors unused,unused
errors can be a comma-separated list of the following keywords:
branchโ branch ID (2nd field in the.infofileBRDAentry) does not follow expected integer sequence.callbackโ version script error.childโ child process returned non-zero exit code duringโparallelexecution. This typically indicates that the child encountered an error: see the log file immediately above this message. In contrast: theparallelerror indicates an unexpected/unhandled exception in the child process โ not atypicallcov error.corruptโ corrupt/unreadable file found.countโ an excessive number of messages of some class have been reported โ subsequent messages of that type will be suppressed. The limit can be controlled by theโmax_message_countโvariable. See thelcovrcman page.deprecatedโ you are using a deprecated option. This option will be removed in an upcoming release โ so you should change your scripts now โ ๏ธ.emptyโ the.infodata file is empty (e.g., because all the code wasโremovedโor excluded.excessiveโ your coverage data contains a suspiciously largeโhitโcount which is unlikely to be correct โ possibly indicating a bug in your toolchain. See theexcessive_count_thresholdsection inlcovrc(5)<file://../man/lcovrc.5.html> for details.forkโ unable to create child process duringโparallelexecution. If the message is ignored (โignore-errors fork), thengenhtmlwill wait a brief period and then retry the failed execution. If you see continued errors, either turn off or reduce parallelism, set a memory limit, or find a larger server to run the task ๐ฎโ๐จ.formatโ unexpected syntax or value found in.infofile โ for example, negative number or zero line number encountered.
A count field which is not a legal integer (for example โnanโ or โinfโ) is likewise treated as zero if this message is ignored; a count which is a number but not an integer is truncated toward zero, and one too large to store is clamped at 9223372036854775807. Numbers, babes ๐ข.
gcovโ thegcovtool returned with a non-zero return code.graphโ the graph file could not be found or is corrupted.inconsistentโ your coverage data is internally inconsistent: it makes two or more mutually exclusive claims. For example, some expression is marked as both an exception branch and not an exception branch. (Seegenhtml(1)<file://../man/genhtml.1.html> for more details.internalโ internal tool issue detected. Please report this bug along with a testcase ๐.mismatchโ incorrect information found in coverage data and/or source code โ for example, the source code contains overlapping exclusion directives.missingโ file does not exist or is not readable.negativeโ negativeโhitโcount found.
A negative count is not a legal value for any cover type, so if this message is ignored, the count is treated as zero.
Note that negative counts may be caused by a known GCC bug โ see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68080
and try compiling with โ-fprofile-update=atomicโ. You will need to recompile, re-run your tests, and re-capture coverage data ๐.
packageโ a required perl package is not installed on your system. In some cases, it is possible to ignore this message and continue โ however, certain features will be disabled in that case.parallelโ various types of errors related to parallelism โ i.e., a child process died due to an error. The corresponding error message appears in the log file immediately before the parallel error.
If you see an error related to parallel execution that seems invalid, it may be a good idea to remove the โparallel flag and try again. If removing the flag leads to a different result, please report the issue (along with a testcase) so that the tool can be fixed ๐ ๏ธ.
parentโ the parent process exited while child was active duringโparallelexecution. This happens when the parent has encountered a fatal error โ e.g. an error in some other child which was not ignored. This child cannot continue working without its parent โ and so will exit ๐.pathโ some file paths were not resolved โ e.g.,.gcnofile corresponding to some.gcdawas not found; seeโbuild-directoryoption for additional information.rangeโ coverage data refers to a line number which is larger than the number of lines in the source file. This can be caused by a version mismatch or by an issue in the gcov data.sourceโ the source code file for a data set could not be found.
unreachableโ a coverpoint (line, branch, function, or MC/DC) that lives inside an โunreachableโ region actually got executed (hit). Which means either the code is wrong, the directive placement is wrong, or honestly both ๐. If you tell it to ignore this error, then whether the offending coverpoint gets retained (not excluded) or not depends on the value of theretain_unreachable_coverpoints_if_executedconfiguration parameter. Seelcovrc(5)and the โExclusion markersโ section up above, bestie.unsupportedโ the feature you're asking for just isn't supported for this tool configuration ๐ญ. Example: function begin/end line range exclusions use some GCOV features that older GCC releases simply do not have. No cap.unusedโ theinclude/exclude/erase/omit/substitutepattern didn't match any file pathnames. It's giving "we dressed up but nobody came" ๐.usageโ unsupported usage detected โ like, an unsupported option combination. You combined things that do not combine, queen.utilityโ a tool called during processing returned an error code (e.g.,findencountered an unreadable directory).versionโ revision control IDs of the file which we are trying to merge are not the same โ so line numbering and other information may be incorrect. Big yikes.
Also see the --ignore-errors section in genhtml(1). The description over there may be more complete and/or more fully explained. Go read it, it's a whole thing ๐ซถ.
See lcovrc(5) for a discussion of the max_message_count parameter which can be used to control the number of warnings which are emitted before all subsequent messages are suppressed. This can be used to reduce log file volume โ very much a "quiet the group chat" move ๐.
--expect-message-countmessage_type=expr[,message_type=expr]โ givegeninfoa constraint on the number of messages of one or more types which are expected to be produced during execution. If the constraint is not true, then generate an error of typecount` (see above). It's literally a vibe check for your messages โจ.
See genhtml(1) for more details about the flag, as well as the expect_message_count section in lcovrc(5) for a description of the equivalent configuration file option.
--keep-goingโ do not stop if error occurs: attempt to generate a result, however flawed ๐ . It's giving "we ball, even if we ball badly."
This command line option corresponds to the stop_on_error [0|1] lcovrc option. See lcovrc(5) for more details.
--fail-under-linespercentage โ use this option to tellgeninfoto exit with a status of1if the total line coverage is less than percentage. Seelcov(1)for more details. Basically a "you must be at least this tall to ride" gate ๐ข.--preserveโ preserve intermediate data files (e.g., for debugging). By default, intermediate files are deleted. So without this, they're gone, poof, ghosted ๐ฆ.--filterfilters โ specify a list of coverpoint filters to apply to input data. See thegenhtmlman page for details.--demangle-cpp[param] โ demangle C++ method and function names in captured output. See thegenhtmlman page for details.-i,--initialโ capture initial zero coverage data. Rungeninfowith this option on the directories containing.bb,.bbgor.gcnofiles before running any test case. The result is a โbaselineโ coverage data file that contains zero coverage for every instrumented line and function. Combine this data file (usinglcov -a) with coverage data files captured after a test run to ensure that the percentage of total lines covered is correct even when not all object code files were loaded during the test. Also see the--allflag, below ๐.
Note: the --initial option is not supported for gcc versions less than 6, and does not generate branch coverage information for gcc versions less than 8. Old gcc? Old news, no baseline for you ๐ญ.
--allโ capture coverage data from both compile time (.gcno) data files which do not have corresponding runtime (.gcda) data files, as well as from those that do have corresponding runtime data. There will be no runtime data unless some executable which links the corresponding object file has run to completion.
Note that the execution count of coverpoints found only in files which do not have any runtime data will be zero.
This flag is ignored if the --initial flag is set.
Using the --all flag is equivalent to executing both geninfo --initial โฆ and geninfo โฆ and merging the result.
Also see the geninfo_capture_all entry in man(5) lcovrc. It's literally the "get everybody, even the ones who didn't show up" flag ๐.
--no-markersโ unless the--no-markersoption is used,geninfowill apply bothregionandbranch_regionfilters to the captured coverage data. Use this option if you want to get coverage data without regard to exclusion markers in the source code file.
If any --filter options are applied, then the default region filters are not used.
--no-markersshould not be specified along with--filter. Do not do it. I'm serious. ๐
--no-recursionโ use this option if you want to get coverage data for the specified directory only without processing subdirectories. Just the one level, no rabbit hole ๐.-o,--output-filenameoutput-filename โ write all data to output-filename. If you want to have all data written to a single file (for easier handling), use this option to specify the respective filename. By default, one tracefile will be created for each processed.gcdafile. One file to rule them all vs. a whole pile โ your call ๐ .--context-scriptscript โ use script to collect additional tool execution context information โ to aid in infrastructure debugging and/or tracking.
See the genhtml man page for more details on the context script.
--criteria-scriptscript โ use script to test for coverage acceptance criteria.
See the genhtml man page for more details on the criteria script. Note that geninfo does not keep track of date and owner information (see the --annotate-script entry in the genhtml man page) โ so this information is not passed to the geninfo callback. F in the chat for the missing metadata ๐ญ.
--resolve-scriptscript โ use script to find the file path for some source or GCNO file which appears in an input data file if the file is not found after applying--substitutepatterns and searching the--source-directoryor--build-directorylist. It's the "have you tried asking a script where your file is" option ๐ต๏ธโโ๏ธ.
This option is equivalent to the resolve_script config file option. In addition, the geninfo_follow_path_links config file option can be used to resolve source paths to their actual target.
See lcovrc(5) for details.
--version-scriptscript โ use script to get a source file's version ID from revision control when extracting data. The ID is used for error checking when merging.infofiles.
See the genhtml man page for more details on the version script.
--unreachable-scriptmodule โ use module to decide whether particular branch expressions and/or MC/DC conditions should be removed from the coverage report. This option is equivalent to theunreachable_scriptconfig file option. Seelcovrc(5)for details.
Note that โmoduleโ is required to be a Perl module ๐ง โ not a script, not vibes, a module.
See the genhtml man page and the โExclusion markersโ section, above, for more information.
-v,--verboseโ increment informational message verbosity. This is mainly used for script and/or flow debugging โ e.g., to figure out which data file are found, where. Also see the--quietflag. It's the "tell me everything" mode, main character energy ๐
Messages are sent to stdout unless there is no output file (i.e., if the coverage data is written to stdout rather than to a file) and to stderr otherwise. Little routing detail, but lowkey important.
-q,--quietโ decrement informational message verbosity. Decreased verbosity will suppress โprogressโ messages for example โ while error and warning messages will continue to be printed. So it gets quieter, but the important mess stays loud ๐ฅ.--debugโ increment โdebug messagesโ verbosity. This is useful primarily to developers who want to enhance thelcovtool suite. Devs only, bestie ๐ซถ.--commentcomment_string โ append comment_string to list of comments emitted into output result file. This option may be specified multiple times. Comments are printed at the top of the file, in the order they were specified.
Comments can be useful to document the conditions under which the trace file was generated: host, date, environment, etc. Basically a little diary entry at the top of your file ๐๐.
--parallel[integer],-j[integer] โ specify parallelism to use during processing (maximum number of forked child processes). If the optional integer parallelism parameter is zero or is missing, then use to use up the number of cores on the machine. Default is to use a single process (no parallelism). Haters will say it's slow. It's not ๐
The --large-file option described below may be necessary to enable parallelism to succeed in the presence of data files which consume excessive memory in gcov.
Note that geninfo writes coverage data (.info) files rather than reading them, so the parallel .info file read controlled by the parallel_parse_min_lines and parallel_parse_chunks_per_worker entries in lcovrc(5) does not apply here; see the --parallel sections of lcov(1) and genhtml(1). Yeah, ikyk ๐
Also see the memory, memory_percentage, max_fork_fails, fork_fail_timeout, geninfo_chunk_size, geninfo_dedicate_segment_size, dedicate_segment_threshold, dedicate_segment_line_estimate and geninfo_interval_update entries in lcovrc(5) for the tea on some options that can help with parameter tuning and performance optimization. Specifically, geninfo_dedicate_segment_size (and, when --history-script data is available, dedicate_segment_threshold) arranges for a large compilation unit to get its own child process and be scheduled first, so it doesn't serialize the tail of the run. A previously generated execution profile can help enable better utilization and faster parallel execution โ see the --profile and --history-script sections of this man page. ๐
--large-fileregexp โ GCDA files whose name matches a--large-fileregexp are processed serially โ not in parallel with other files โ so that their gcov process can use all available system memory. ๐ซถ
Use this option if you see errors related to memory allocation from gcov. (real "oh no" energy, bestie)
This feature is exactly as if you had moved the matching GCDA files to another location and processed them serially, then processed the remaining GDCA files in parallel and merged the results. Yes, GDCA. That's what it says. Copying it exactly. ๐
Note that this is a memory-safety control, distinct from the latency-oriented geninfo_dedicate_segment_size: a --large-file match runs serially in the parent process, whereas a file that only exceeds geninfo_dedicate_segment_size is still forked (in its own dedicated child) and processed in parallel. A file matched by --large-file is never also given a dedicated child.
This option may be used multiple times to specify more than one regexp. โจ
--memoryinteger โ specify the maximum amount of memory to use during parallel processing, in Mb. Effectively, the process will notfork()if this limit would be exceeded. Default is0(zero) โ which means there is no limit. ๐
This option may be useful if the compute farm environment imposes strict limits on resource utilization such that the job will be killed if it tries to use too many parallel children โ but the user does not know a priori what the permissible maximum is. This option enables the tool to use maximum parallelism, up to the limit imposed by the memory restriction. Big "work smarter not harder" energy.
The configuration file memory_percentage option provides another way to set the maximum memory consumption. See lcovrc(5) for details.
--rckeyword = value โ override a configuration directive. ๐
Use this option to specify a keyword = value statement which overrides the corresponding configuration statement in the lcovrc configuration file. You can specify this option more than once to override multiple configuration statements. See lcovrc(5) for a list of available keywords and their meaning.
-t,--test-nametestname โ use test case name testname for the resulting data. Valid test case names can consist of letters, decimal digits and the underscore character (_). ๐
This proves useful when data from several test cases is merged (i.e. by simply concatenating the respective tracefiles), in which case a test name can be used to differentiate between data from each test case. Lowkey such a glow-up for your tracefiles.
--versionโ print version number, then exit. That's it. That's the whole vibe check. โญ--tempdirdirname โ write temporary and intermediate data under the indicated directory. Default is the platform temporary directory:$TMPDIR,$TEMPor$TMPif one of them names a writeable directory, otherwise/tmpon Unix orC:\tempon Windows. ๐ฆ
A uniquely named subdirectory of dirname is created for the run, and the data is written there โ so several runs can share one dirname without colliding. dirname itself is created if it does not exist.
Unless --preserve is specified, the generated subdirectory and its contents are removed when geninfo exits. ๐งน
This option can also be configured permanently using the configuration file option lcov_tmp_dir.
๐ TRACEFILE FORMAT ๐
Following is a quick description of the tracefile format as used by genhtml, geninfo and lcov.
A tracefile is made up of several human-readable lines of text, divided into sections. Human-readable!! Take notes, every other binary format ever.
Where a record appears is part of the format, and not merely a convention:
tracefile := ( comment | blank )* section*
section := 'TN:'? 'SF:' ( coverpoint | 'VER:' | comment | blank )*
'end_of_record'
That is: ๐
- A section begins with an
SF:record (KF:is accepted as a synonym) and ends with anend_of_recordrecord. - An optional
TN:record precedes theSF:record of the section whose data it names.TN:identifies the testcase which the section's data belongs to, so it cannot appear after the data it applies to. (order matters, bestie โ no take-backs) - The
VER:record and all coverpoint records (FNL:,FNA:,FNDA:,BRDA:,MCDC:,DA:and the corresponding*F:/*H:summary records) appear within a section, in any order. They mean nothing outside one. - A comment record or a blank line may appear anywhere โ inside a section or outside one. ๐
Anything else โ a coverpoint record outside any section, a TN: record inside one, a second SF: with no intervening end_of_record, an end_of_record with no section open, or end of file with a section still open โ is reported as an ERROR_FORMAT. See the --ignore-errors format discussion in lcov(1). If that error is ignored, the reader recovers by discarding the misplaced record (or, in the unterminated-section cases, by closing the section that is open) and keeping the data which was in the right place. Graceful recovery. We love a bounce-back.
Records of a cover type which is turned off are discarded as soon as they are recognized, and their contents are not examined: with branch coverage disabled, for example, a malformed BRDA: record is dropped in silence rather than reported as an ERROR_FORMAT. The check is what costs the time, and the data would be thrown away in either case. So whether a malformed coverpoint record is diagnosed depends on whether its cover type is enabled โ see branch_coverage, mcdc_coverage and function_coverage in lcovrc(5). Where a record appears is still checked in every case: a BRDA: record outside any section is an ERROR_FORMAT whether or not branch coverage is enabled. ๐
A comment record is:
#comment_string
There is no space before or after the # character. Comment records are ignored when a tracefile is read: they are not coverage data, so nothing is retained and nothing is written back out. If the --comment comment_string option is supplied, then a comment record appears at the top of the tracefile which the tool writes. โจ
If available, a tracefile begins with the testname, which is stored in the following format:
TN:<test name>
For each source file referenced in the .gcda file, there is a section containing filename and coverage data:
SF:<path to the source file>
An optional source code version ID follows:
VER:<version ID>
If present, the version ID is compared before file entries are merged (see lcov --add-tracefile), and before the 'source detail' view is generated by genhtml. See the --version-script callback_script documentation and the sample usage in the lcov regression test examples. ๐
Function coverage data follows. Note that the format of the function coverage data has changed from LCOV 2.2 onward. The tool continues to be able to read the old format but now writes only the new format. This change was made so that function filter outcome is persistent in the generated tracefile. (iconic behaviour, honestly)
Functions and their aliases are recorded contiguously:
First, the leader:
FNL:<index>,<line number of function start>[,line number of function end>]
Then the aliases of the function; there will be at least one alias. All aliases of a particular function share the same index.
FNA:<index>,<execution count>,<name>
The now-obsolete function data format is:
FN:<line number of function start>,[<line number of function end>,]<function name>
The 'end' line number is optional, and is generated only if the compiler/toolchain version is recent enough to generate the data (e.g., gcc 9 or newer). This data is used to support the --erase-functions and --show-proportions options. If the function end line data is not available, then these features will not work. No end line, no features. That's the deal.
Next, there is a list of execution counts for each instrumented function:
FNDA:<execution count>,<function name>
This list is followed by two lines containing the number of functions found and hit:
FNF:<number of functions found>
FNH:<number of function hit>
Note that, as of LCOV 2.2, these numbers count function groups โ not the individual aliases. ๐
Branch coverage information is stored one line per branch:
BRDA:<line_number>,[<exception>][<fallthrough][<unreachable>]<block>,<branch>,<taken>
(yes, we're copying that bracket situation exactly as written โ not our business, not our problem ๐ )
<line_number>
is the line number where the branch is found โ and is expected to be a non-zero integer.
<block> and <branch>
serve to uniquely define a particular edge in the expression tree of a particular conditional found on the associated line.
Within a particular line, <block> is an integer numbered from zero with no gaps. For some languages and some coding styles, there will only be one block (index value zero) on any particular line. ๐ฆ
<branch> is a string which serves to uniquely identify a particular edge. For some languages and tools โ e.g., C/C++ code compiled with gcc or llvm โ <branch> is an ordered integer index related to expression tree traversal order of the associated conditional. For others, it may be a meaningful string โ see below. <branch> appears in the 'tooltip' popup of the associated branch in the genhtml output โ so human-readable values are helpful to users who are trying to understand coverage results โ for example, in order to develop additional regression tests, to improve coverage. Be nice to your future self and name things well โจ
<taken>โ either-if the corresponding expression was never evaluated (like, the basic block containing the branch never ran at all ๐ด) or a number telling you how often that branch was taken.<exception>โ it'se(yes, just one character) if this is a branch related to exception handling, and it's simply not there if the branch has nothing to do with exceptions. Heads up tho: identifying exception branches requires compiler support, sogeninfocan only spot them if your toolchain version is new enough to actually support the feature. iykyk.<fallthrough>โ it'sf(again, one character) if this branch is marked as โfallthroughโ (like in thegcovoutput), and it's absent if the branch isn't marked. Same deal as above: fallthrough branch identification requires compiler support, andgeninfowill only pick them up if your toolchain version is new enough to support the feature. Also, a branch can be marked as โ<exception>โ or โ<fallthoughโ โ but not both, bestie, pick a lane ๐ .<unreachable>โ it'sU(single character) if this branch is associated with an โunreachable directive, and it just isn't present if the branch is reachable. The whole point of unreachability is to mark branch expressions that should not show up in coverage reports โ so you can ignore uncovered branches that could never be covered anyway and actually focus on the parts of the report that matter. ๐ธ
Peep the โโunreachable-scriptโ discussion in genhtml(1) <file://../man/genhtml.1.html> and the โignore_unreachable_flagโ discussion in lcovrc(5) <file://../man/lcovrc.5.html> for the full tea on how branch exclusion markers get set and used.
So these next ones are example branch records where the <branch> expression values are human-readable strings:
BRDA:10,0,enable,1
BRDA:10,0,!enable,0
In this case the corresponding code from line 10 is very likely similar to:
if (enable) {
...
}
such that the associated testcase entered the block (โenableโ evaluated to โtrueโ). Slay. โจ
Arbitrarily complicated branch expressions are supported โ including branch expressions that contain commas (like, say, an expression with a function call in it). No cap.
โ ๏ธ Note that particular tools may or may not suppress expressions which are statically true or statically false โ e.g., expressions using template parameters. Which makes it potentially complicated to compare coverage data generated by two different tools. Fr fr, watch out for that one. ๐ญ
a note on branch identification, matching, and merging ๐ซถ
As we said before: lcov merely presents coverage data that gets identified by other tools such as gcov. Unfortunately, gcov (and other tools) do not produce sufficient information to uniquely identify branch expressions โ so lcov is forced to use a heuristic solution based on the order of appearance plus the number and type of individual branch elements โ say, in the gcov output.
lcov computes a โsignatureโ for each โ<block>โ. If the block ID and signature found while capturing data from multiple files (or while merging coverage data) match โ then the block is considered identical and the corresponding expression counts get combined. ๐
Within a particular line, there may be one or more blocks with the same signature โ for example, corresponding to independent branch expressions in function call arguments on that line, or to different macro or template expansion. lcov keeps track of the order that branch blocks were found (say, in the gcov output or in an lcov .info file).
When merging branch data on a particular line:
- Blocks which have different signatures are considered to be distinct.
- Blocks which have identical signatures are matched in order: the zeroth block with signature
s1in coverage DB A is merged with the zeroth block with signatures1in coverage DB B โ and so on. - If one or the other DB does not contain some signature, or one DB contains more blocks with the same signature: then those non-matching blocks are simply copied to the merged output.
๐ This heuristic can cause ambiguity in the generated report โ especially for cases where a particular line expands in different ways in different compilation units (e.g., due to template or macro expansion). In such cases it may just not be possible for lcov to know that some block whose signature and order appear to match is not actually the same block. Lowkey you can sometimes refactor the code slightly to introduce explicit temporaries (on their own line) to resolve the ambiguity. ๐ง
Branch coverage summaries are stored in two lines:
BRF:<number of branches found>
Note that this count does not include โexcludedโ branches. (Excluded branches do still appear as BRDA records, tho. ๐)
BRH:<number of branches hit>
Note that this count does not include โexcludedโ branches. Excluded branches do appear as BRDA records.
MC/DC information is stored one line per expression:
MCDC:<line_number>,[<unreachable>]<groupSize>,<sense>,<taken>,<index>,<expression>
where:
<line_number>โ is the line number where the condition is found โ and is expected to be a non-zero integer.<groupSize>and<index>โ these two serve to uniquely define a particular element in the expression tree of a particular conditional found on the associated line.
Within a particular line and group:
<index>โ is an integer numbered from zero to<groupSize>- 1 with no gaps. For some languages and some coding styles, there will only be one group on any particular line.<sense>โ is either โfโ or โtโ, indicating whether the condition is sensitive to the indicated change โ that is, does the condition outcome change if the corresponding changes from โfalseโ to โtrueโ or from โtrue to false, respectively.<taken>โ is a count: 0 (zero) if the expression was not sensitized, non-zero if it was sensitized. Note that some tools may treat<taken>as the number of times the expression was sensitized where others may treat it as a boolean โ1:sensitized or0: not sensitized.<expression>โ is an arbitrary string, intended to be a meaningful string which will help the user understand the condition context โ see below.<expression>appears in the โtooltipโ popup of the associated MC/DC condition in thegenhtmloutput โ so human-readable values are genuinely helpful to users trying to understand coverage results โ for example, in order to develop additional regression tests, to improve coverage. ๐
For a given <groupSize> and <index>, the <expression> should be identical for both โtโ and โfโ senses.
<unreachable>โ isU(single character) if this condition is associated with an โunreachable directive, and it's not present if the condition is reachable. Unreachability is intended to mark conditions which should not appear in coverage reports โ enabling users to ignore uncovered conditions which can never be covered, so they can concentrate on other areas of the coverage report.
See the โโunreachable-scriptโ discussion in genhtml(1) <file://../man/genhtml.1.html> and the โignore_unreachable_flagโ discussion in lcovrc(5) <file://../man/lcovrc.5.html> for more information on how branch exclusion markers are set and used.
The following are example MC/DC records whose <expression> values are human-readable strings:
MCDC:10,2,f,0,0,enable
MCDC:10,2,t,1,0,enable
...
In this case, the corresponding code from line 10 is very likely similar to:
if (enable ...) {
...
}
such that the associated testcase was sensitive to a change of โenableโ from true to false (but not the converse). Iconic behavior honestly. ๐ฆ
Arbitrarily complicated expressions are supported โ including expressions which contain commas (e.g., in an expression containing a function call).
โ ๏ธ Note that particular tools may or may not suppress expressions which are statically true or statically false โ e.g., expressions using template parameters. This makes it potentially complicated to compare coverage data generated by two different tools. Yeah, it's giving "good luck comparing" ๐ญ
MCDC coverage summaries are stored in two lines:
MCF:<number of conditions found>
Note that this count does not include โexcludedโ conditions. Excluded branches do appear as MCDC records.
MCH:<number of condition hit>
Note that this count does not include โexcludedโ conditions. Excluded branches do appear as MCDC records.
Then there's a list of execution counts for each instrumented line (i.e. a line which resulted in executable code):
DA:<line number>,<execution count>[,<checksum>]
Note that there may be an optional checksum present for each instrumented line. The current geninfo implementation uses an MD5 hash as checksumming algorithm. ๐ฅ
At the end of a section, there's a summary about how many lines were found and how many were actually instrumented:
LH:<number of lines with a non-zero execution count>
LF:<number of instrumented lines>
Each section ends with:
end_of_record
In addition to the main source code file, there are sections for all #included files which also contain executable code. Periodt. ๐
๐ Note that the absolute path of a source file is generated by interpreting the contents of the respective.gcnofile (seegcov(1)<file://../man/gcov.1.html> for more information on this file type). Relative filenames are prefixed with the directory in which the.gcnofile is found.
๐ Note also that symbolic links to the.gcnofile will be resolved so that the actual file path is used instead of the path to a link. This approach is necessary for the mechanism to work with the/proc/gcovfiles. Lowkey crucial, ngl.
๐ FILES ๐
/etc/lcovrcโ the system-wide configuration file. ๐~/.lcovrcโ the per-user configuration file. ๐bin/getp4versionโ sample script for use with--version-scriptthat obtains version IDs via Perforce.bin/get_signatureโ sample script for use with--version-scriptthat usesmd5hashas version IDs. โจ
๐ AUTHOR ๐
- Peter Oberparleiter <<Peter.Oberparleiter@de.ibm.com>>
- Henry Cox <<henry.cox@mediatek.com>>
- Filtering, error management, parallel execution sections. ๐ซถ
โจ SEE ALSO โจ
okay so when you're done here and you're like "wait, what about the rest of the toolchain??" โ bestie, there's a whole squad ๐
genhtml(1)โ gotta turn that data into pretty HTML? she does thatlcov(1)โ the main character of the whole operation fr frlcovrc(5)โ all the config file lore, iykykgcov(1)โ the OG, the blueprint, the source of the numbersllvm2lcov(1)โ for the LLVM girlies ๐ฆ
and if you wanna vibe with the repo itself:
https://github.com/linux-test-project/lcov
like, go star it or whatever โญ
๐ Copyright ๐
2024-2026, LCOV Project โ protect the project besties ๐ญ๐
this page is from lcov version 2.6, dated 2026-10-03 โ that's the GENINFO(1) manual, and that's the whole thing, no cap ๐โจ๐ซถ
๐ฆ where this page comes from
- arch rolling: lcov 2.6-1 ยท GPL
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms