Subject: Re: Having problems generating a code coverage report

From: jian he <[email-masked]>
Date: Thu, 31 Oct 2024 23:36:21 +0800

On Thu, Oct 31, 2024 at 10:02 PM Aleksander Alekseev
<[email-masked]> wrote:
>
> Hi,
>
> > On Wed, Oct 30, 2024 at 05:26:49PM -0400, Peter Geoghegan wrote:
> > > I use Debian unstable for most of my day to day work. Apparently
> > > Debian unstable has exactly the same version of lcov as Ubuntu 24.04.
> > >
> > > I've also been unable to generate coverage reports for some time (at
> > > least on Debian, with LCOV version 2.0-1).
> >
> > So do I, for both the debian SID and the lcov parts.
>
> I downgraded to lcov 1.16 [1] and it helped. This is merely a
> workaround of course, not a long-time solution.
>
> [1]: https://github.com/linux-test-project/lcov/releases/tag/v1.16
>
> --

my ubuntu meson version: 0.61.2, which also fails.
with similar errors you've posted.

from these two posts,
https://github.com/mesonbuild/meson/pull/12345
https://github.com/mesonbuild/meson/issues/11995

Maybe upgrading meson can solve this problem.

---

From: Aleksander Alekseev <[email-masked]>
Date: Thu, 31 Oct 2024 19:37:43 +0300

Hi Jian,

> Maybe upgrading meson can solve this problem.

Thanks for the hint. I'm using Meson 1.3.2. Although it's not ancient
(Feb 2024) there is 1.6.0 available. I'll try upgrading and let you
know the results.

-- 
Best regards,
Aleksander Alekseev

---

From: Aleksander Alekseev <[email-masked]>
Date: Fri, 1 Nov 2024 17:22:17 +0300

Hi,

> (Feb 2024) there is 1.6.0 available. I'll try upgrading and let you

I upgraded to Meson 1.6.0 and Lcov 2.0-1. Unfortunately it doesn't work:

```
genhtml: ERROR: no data for line:864, TLA:UNC,
file:/home/eax/projects/c/postgresql/src/bin/psql/psqlscanslash.l
    (use "genhtml --ignore-errors unmapped ..." to bypass this error)
Traceback (most recent call last):
  File "/home/eax/.venv/bin/meson", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/eax/.venv/lib/python3.12/site-packages/mesonbuild/mesonmain.py",
line 293, in main
    return run(sys.argv[1:], launcher)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eax/.venv/lib/python3.12/site-packages/mesonbuild/mesonmain.py",
line 281, in run
    return run_script_command(args[1], args[2:])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eax/.venv/lib/python3.12/site-packages/mesonbuild/mesonmain.py",
line 222, in run_script_command
    return module.run(script_args)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eax/.venv/lib/python3.12/site-packages/mesonbuild/scripts/coverage.py",
line 208, in run
    return coverage(options.outputs, options.source_root,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eax/.venv/lib/python3.12/site-packages/mesonbuild/scripts/coverage.py",
line 148, in coverage
    subprocess.check_call([genhtml_exe,
  File "/usr/lib/python3.12/subprocess.py", line 413, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['genhtml', '--prefix',
'/home/eax/projects/c/postgresql/build', '--prefix',
'/home/eax/projects/c/postgresql', '--output-directory',
'/home/eax/projects/c/postgresql/build/meson-logs/coveragereport',
'--title', 'Code coverage', '--legend', '--show-details',
'--branch-coverage',
'/home/eax/projects/c/postgresql/build/meson-logs/coverage.info']'
returned non-zero exit status 1.
ninja: build stopped: subcommand failed.
```

If I add `--ignore-errors unmapped` as suggested and execute:

```
genhtml --ignore-errors unmapped --prefix
/home/eax/projects/c/postgresql/build --prefix
/home/eax/projects/c/postgresql --output-directory
/home/eax/projects/c/postgresql/build/meson-logs/coveragereport
--title 'Code coverage' --legend --show-details --branch-coverage
/home/eax/projects/c/postgresql/build/meson-logs/coverage.info
```

... I get:

```
...
Processing file src/pl/plpython/plpy_util.c
  lines=33 hit=22 functions=4 hit=4 branches=14 hit=5
Processing file src/include/catalog/index.h
  lines=10 hit=10 functions=2 hit=2
genhtml: ERROR: duplicate merge record src/include/catalog
```

I didn't investigate further.

-- 
Best regards,
Aleksander Alekseev

---

From: Aleksander Alekseev <[email-masked]>
Date: Fri, 1 Nov 2024 18:42:37 +0300

Hi everyone,

> [...]

Lcov 2.1 and 2.2beta don't work either.

-- 
Best regards,
Aleksander Alekseev

---

From: Andres Freund <[email-masked]>
Date: Wed, 21 Jan 2026 13:57:58 -0500

Hi,

> Lcov 2.1 and 2.2beta don't work either.

I just encountered this. The problem seems to only happen when the build
directory is inside the source directory.

Not that that's a great solution, but just having the build dir be in a
separate directory fixed the issue for me.

Greetings,

Andres Freund

---

From: Michael Paquier <[email-masked]>
Date: Thu, 22 Jan 2026 09:48:35 +0900

> separate directory fixed the issue for me.

Even with a VPATH build on Debien GID?  FWIW, I am unable to run a
coverage-html even in this case from the root of a build, finishing
with stuff like that:
/usr/bin/lcov --gcov-tool /usr/bin/gcov -q --no-external -c -i -d . -d
/home/user/git/postgres/ -o lcov_base.info
lcov: ERROR: (empty) no .gcno files found in /home/user/git/postgres
(use "lcov --ignore-errors empty ..." to bypass this error)

Passing "--ignore-errors empty" to LCOVFLAGS bypasses the first step
but genhtml complains, like:
genhtml: ERROR: (corrupt) unable to read trace file 'lcov_base.info':

meson is no better as far as I've tried, so I have pretty much given
up with coverage reports in this environment at this stage.  If there
is a magic recipe, I am not really aware of one..
--
Michael

---

From: Andres Freund <[email-masked]>
Date: Wed, 21 Jan 2026 20:59:45 -0500

Hi,

On 2026-01-22 09:48:35 +0900, Michael Paquier wrote:
> Even with a VPATH build on Debien GID?

Well, mine was a meson build.

> is a magic recipe, I am not really aware of one..

I have the following .lcovrc in my postgres source dir:

ignore_errors=inconsistent,gcov,range
check_data_consistency=0
stop_on_error=0
genhtml_hierarchical=1
genhtml_show_navigation=1
parallel=16
geninfo_gcov_tool=/usr/bin/gcov-15

(assuming you build with gcc 15)

With that meson coverage information works (i.e. ninja coverage-html) for both
lcov 2.0 and 2.4 as long as the build directory is outside of the source
directory. Both on Debian Sid and macos.

Greetings,

Andres Freund

---

From: Michael Paquier <[email-masked]>
Date: Thu, 22 Jan 2026 14:35:40 +0900

> directory. Both on Debian Sid and macos.

Thanks for sharing.  Yes, I have a matching gcc version at 15.2
currently.  I have been playing with this area of the configuration
for some time without finding the correct combination before giving
up, and these suggestions are actually helping for meson.  So now I
can get a report offline.  Yeah at least it's one thing working.

Hmm.  configure with and without VPATH still burp at me on HEAD.  If I
tweak the lcov commands in src/Makefile.global.in like in the attached 
patch then the non-VPATH build can work, where I remove the srcdir
part (aka reverting c3d9a66024a9).  For the VPATH build, this patch
does not work at all, it generates an incomplete report, ignoring
entirely contrib/, with its base index.html starting inside src/,
missing a bunch of subdirectories.  I can live with this custom patch
for now, just wondering if anybody else sees what I am seeing for a
few months now.

Thoughts?  At least two out of the three methods are working with the
attached instead of one out of three.  Not sure what to do with VPATH,
but well.
--
Michael
From db627eb90cf625249a670300e295cff1c69c0a88 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email-masked]>
Date: Thu, 22 Jan 2026 14:32:45 +0900
Subject: [PATCH] Tweak lcov commands

This fixes coverage reports for non-VPATH builds, generates incorrect
reports with VPATH builds.
---
 src/Makefile.global.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 947a2d79e291..d066ed162034 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -1061,12 +1061,12 @@ LCOVFLAGS = -q --no-external
 all_gcno_files = $(shell find . -name '*.gcno' -print)
 
 lcov_base.info: $(all_gcno_files)
-	$(LCOV) $(LCOVFLAGS) -c -i -d . -d $(srcdir) -o $@
+	$(LCOV) $(LCOVFLAGS) -c -i -d . -o $@
 
 all_gcda_files = $(shell find . -name '*.gcda' -print)
 
 lcov_test.info: $(all_gcda_files)
-	$(LCOV) $(LCOVFLAGS) -c -d . -d $(srcdir) -o $@
+	$(LCOV) $(LCOVFLAGS) -c -d . -o $@

 # hook for clean-up
-- 
2.51.0

---

From: Andres Freund <[email-masked]>
Date: Thu, 22 Jan 2026 13:19:43 -0500

Hi,

> can get a report offline.  Yeah at least it's one thing working.

Cool.

> for now, just wondering if anybody else sees what I am seeing for a

If I suppress the empty errors & warnings with --ignore-errors empty,empty the
current "-d . -d $(srcdir)" kinda works.  Unfortunately, in VPATH builds, the
directory structure is quite messed up. It seems to get a bit better if I add
-p $(srcdir) to the genhtml invocation, but a few generated files still show
up bogus.

The bogus build files unfortunately aren't trivial to fix, if I additionally
add a "-p $(pwd)" (i.e. add the build dir as a prefix), I get errors about
"duplicate merge record".   But it's not too bad to see that stupid path for
the generated files.

Greetings,

Andres Freund

---

From: Michael Paquier <[email-masked]>
Date: Fri, 23 Jan 2026 07:11:11 +0900

> -p $(srcdir) to the genhtml invocation, but a few generated files still show

With a bit more information to skip more error patterns, I actually
got an unpatched HEAD build able to work properly as well, with:
ignore_errors=inconsistent,gcov,range,empty,usage,usage,empty,empty,path

The VPATH build is indeed looking pretty broken here, with the
top-level including the contents of src/ and /home/, /home/ pointing
to contrib/.  I'll live with that, that's so much better than nothing
working locally.  Thanks for all the pointers, Andres.
--
Michael

---

From: Jacob Champion <[email-masked]>
Date: Wed, 10 Jun 2026 17:49:47 -0700

> directory. Both on Debian Sid and macos.

Setting `genhtml_no_prefix = 1` fixes the directory name collision for
me (clang 22, lcov 2.4) without rehoming the build directory. (As does
hacking meson to pass the source root --prefix before the build root,
which makes for prettier output. Apparently lcov doesn't handle the
case where one prefix is a substring of the other very well.)

Also, in case it helps anyone: I found that clang-15 generates
outright buggy .gcno information for some of our #included C snippets,
such as `#include "equalfuncs.switch.c"`, and lcov-2's stricter
processing correctly complains about it. Apparently that was fixed at
some point with newer clangs.

--Jacob