Reading a tracefile with an uncalled gcc lambda aborts with an `inconsistent` error (or, with `--ignore-errors inconsistent`, marks the lambda called): `isLambda` matches only the demangled `{lambda(`, and geninfo writes mangled names by default
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- perl
- Domain
- testing-qa, tooling
Research direction
Start by reading isLambda, _checkConsistency, and the geninfo name-writing path in lib/lcovutil.pm and bin/geninfo; the issue identifies the relevant line ranges and reproductions. Compare how mangled and demangled lambda names are handled, then run the five-line tracefile reproduction with and without --ignore-errors inconsistent. Done means reading the mangled tracefile preserves the uncalled count and emits no inconsistency error.
Written by the indexing model from the issue text.
Description
Versions
-
lcov 2.6, from the release tarball, and master at
a4ba8b3. Also lcov 2.5. -
The minimal reproduction needs no compiler.
-
Reproduced on:
- macOS: the floor with 2.6 and master; the compiled example with gcc 16.2.0 and 2.6.
- Ubuntu 24.04: the floor with 2.5 and an earlier master; the compiled example with gcc 15 and 2.5.
Seen on real data from both, with 2.5.
Minimal reproduction
A five-line tracefile: one lambda that gcov says was never called, and a hit on its first line. That line runs when the closure is constructed. The two files differ only in how the name is spelled.
mangled.info:
SF:/nonexistent/m.cpp
FNL:0,5,5
FNA:0,0,_ZZ4mainENKUlvE_clEv
DA:5,1
end_of_record
demangled.info: the same, with FNA:0,0,main::{lambda()#1}::operator()() const.
Output abridged to the relevant lines:
$ lcov -a mangled.info -o out.info
lcov: ERROR: (corrupt) unable to read trace file 'mangled.info': lcov: ERROR: (inconsistent) "/nonexistent/m.cpp":5: function '_ZZ4mainENKUlvE_clEv' is not hit but line 5 is.
$ echo $?
1
$ lcov -a mangled.info -o out.info --ignore-errors inconsistent
lcov: WARNING: (inconsistent) "/nonexistent/m.cpp":5: function '_ZZ4mainENKUlvE_clEv' is not hit but line 5 is: function marked 'hit'.
$ grep FNA out.info
FNA:0,1,_ZZ4mainENKUlvE_clEv
$ lcov -a demangled.info -o out.info
$ grep FNA out.info
FNA:0,0,main::{lambda()#1}::operator()() const
lcov --summary, lcov --remove and genhtml read a tracefile the same way, and each behaves as lcov -a does.
How the data arises
template<class F> int call_if(bool b, F f) { return b ? f() : 0; }
int main(int argc, char**)
{
return argc > 1 ? 2 : call_if(false, [] { return 1; });
}
With gcc 15 and its own gcov (the same with gcc 16, and with lcov 2.6):
g++-15 --coverage -O0 m.cpp -o m && ./m
lcov -c -d . -o cap.info --gcov-tool gcov-15
lcov -a cap.info -o read.info --ignore-errors inconsistent
- The capture writes
FNA:2,0,_ZZ4mainENKUlvE_clEvandDA:5,1, with no warning. The data is consistent: line 5 ran, the lambda did not. read.infohasFNA:2,1,_ZZ4mainENKUlvE_clEv, with the "function marked 'hit'" warning.- The same with
--rc geninfo_unexecuted_blocks=1at capture (checked with gcc 16). - With
--demangle-cppat capture, the read leaves the count at 0.
Expected
The count stays 0 and no message is issued. That is what the exemption at lib/lcovutil.pm:10759-10770 is for: "don't warn about the first line of a lambda: the decl may executed [sic] even if the lambda function itself is not called". It is also what happens to the same data when the name is demangled.
Actual
Without --ignore-errors inconsistent, lcov aborts on reading a tracefile that geninfo has just written, and reports it as corrupt. With it, the lambda is reported as called, with its first line's count. On our project's data (gcc 15, lcov 2.5), 36 lambda instantiations at 27 source locations are marked, all of them uncalled according to gcov.
Mechanism (line numbers from the 2.6 release tarball; master's lib/lcovutil.pm and bin/geninfo have the same)
- The documentation implies a modern gcov needs no flag.
lcovrc(5), underderive_function_end_line, says: "lambdas are identified via function name matching - so you must enable demangling if your toolchain is too old to report demangled names in the GCOV output". gcc's gcov does reportdemangled_namein its JSON. But geninfo keeps it only under--demangle-cpp, and otherwise writes the mangledname(bin/geninfo:2556-2557). So with a current gcc, the tracefile holds_ZZ4mainENKUlvE_clEv. isLambda(lib/lcovutil.pm:7303-7315) recognises a C/C++ lambda only by the demangled spelling,$self->name() =~ /{lambda\(/, so it returns false._checkConsistency(:10716) then treats the lambda's first line as an ordinary hit line. It raisesinconsistent. If that error is ignored, or--keep-goinglets it pass, the lambda and its aliases are marked hit (:10784-10790,_fixFunction:10686-10714).- The capture does not mark the lambda. At capture, geninfo applies its default
regionfilter, so C/C++ files take the filtering path. That path runs the check only when function end lines must be derived (:10922-10924,:11827-11851), and gcc supplies them. A read without--filterruns the check on every file (:11850). So a correct capture is changed by the first tool that reads it, or that tool aborts. - The other
isLambdacallers (:10532,:11831) and the alias-naming code inaddAliasandremoveAliases(:7423-7424,:7472-7475) test the same demangled spelling on the same names.
Possible fixes
- Demangle the name before matching, with the demangler lcov already supports.
- Or recognise the Itanium encoding of a closure type,
Ul<params>E[<n>]_, with a real parse of the mangled name. A substring test forUlwould also match unrelated names. - Or have geninfo write the demangled name whenever gcov supplies one.
Workarounds
--rc check_data_consistency=0on every tool that reads a tracefile. This also switches off the rest of the consistency checks.--demangle-cppat capture. This merges aliases differently, and exempts only the lambda's first line, so a multi-line lambda whose closing line runs code of the enclosing statement is still marked.
- Dominant language
- Shell
- Stars
- 1.1k
- Forks
- 272
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 13
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from linux-test-project/lcov
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
linux-test-project/lcov#546 · 4 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 57/100
linux-test-project/lcov#555 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 55/100
linux-test-project/lcov#554 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 63/100
linux-test-project/lcov#536 · 4 comments ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
linux-test-project/lcov#469 · 2 comments ·
Maintainers usually reply within 1 day
All issues in linux-test-project/lcov
Similar issues
-
Update migenOpen
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
YosysHQ/oss-cad-suite-build#220 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
docker-library/redmine#430 ·
-
fm-spawn: isolation timeout hides the real treehouse get error and closes the pane that holds itOpen
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
kunchenguid/firstmate#7848 ·
Maintainers usually reply within 1 day
-
DEV: partitioner only creates next month, so one failed run leaves a month with no partitionPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
Maintainers usually reply within 1 day
-
docs: state the LF Projects antitrust policy in the repositoryPossibly taken @vinoo999 claimed this today. Open
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
a2aproject/A2A#2394 ·
Maintainers usually reply within 3 days