Re: [PATCH] tests: add coverage-html target

2021-01-11 Thread Mark Wielaard
Hi Dmitry,

On Wed, 2020-12-23 at 00:25 +0300, Dmitry V. Levin wrote:
> Implement a target for capturing code coverage using lcov.
> It is available when elfutils is configured using --enable-gcov.
> 
> Signed-off-by: Dmitry V. Levin 
> ---
> Rather than trying to salvage the coverage target, implement a
> different
> target for capturing code coverage similar to those I use in other
> projects.  I'm sure you'll like it, too.

I like it. We need to integrate it with the elfutils-htdocs update-
coverage script that is responsible for generating:
https://sourceware.org/elfutils/coverage/

See below.

>  ChangeLog |  4 
>  configure.ac  |  3 +++
>  tests/.gitignore  |  2 ++
>  tests/ChangeLog   |  5 +
>  tests/Makefile.am | 40 
>  5 files changed, 54 insertions(+)
> 
> diff --git a/ChangeLog b/ChangeLog
> index 03c90b6b..fe4f1829 100644
> --- a/ChangeLog
> +++ b/ChangeLog
> @@ -1,3 +1,7 @@
> +2020-12-22  Dmitry V. Levin  
> +
> + * configure.ac [--enable-gcov]: Check for gcov, lcov, and
> genhtml.
> +
>  2020-12-20  Dmitry V. Levin  
>  
>   * .gitignore: Move subdirectory patterns to separate .gitignore
> files.
> diff --git a/configure.ac b/configure.ac
> index 60747bc8..346ab800 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -311,6 +311,9 @@ if test "$use_gcov" = yes; then
>CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
>CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
>LDFLAGS="$LDFLAGS -fprofile-arcs"
> +  AC_CHECK_PROG([GCOV], [gcov], [gcov])
> +  AC_CHECK_PROG([LCOV], [lcov], [lcov])
> +  AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
>  fi
>  AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)

This is a good idea. But do we need a particular version of lcov?
I get lcov: Unknown option: exclude
$ lcov --version
lcov: LCOV version 1.13
I don't insist on having it working with old lcov, just that we detect
it.

> diff --git a/tests/.gitignore b/tests/.gitignore
> index d0e83da2..4aca5c7c 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -1,3 +1,5 @@
> +/*-coverage
> +/*.lcov
>  /*.log
>  /*.trs
>  /addrcfi
>
> diff --git a/tests/ChangeLog b/tests/ChangeLog
> index 4688b50a..c0d9d4b8 100644
> --- a/tests/ChangeLog
> +++ b/tests/ChangeLog
> @@ -1,3 +1,8 @@
> +2020-12-22  Dmitry V. Levin  
> +
> + * Makefile.am [GCOV] (coverage-html): New target.
> + * .gitignore: Update.
> +
>  2020-12-20  Dmitry V. Levin  
>  
>   * .gitignore: New file.
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 502becff..293b4225 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -695,4 +695,44 @@ check: check-am coverage
>  .PHONY: coverage
>  coverage:
>   -$(srcdir)/coverage.sh
> +
> +COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME)-$(PACKAGE_VERSION).lcov
> +COVERAGE_OUTPUT_DIRECTORY = $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
> +COVERAGE_OUTPUT_INDEX_HTML = $(COVERAGE_OUTPUT_DIRECTORY)/index.html
> +COVERAGE_TITLE = $(PACKAGE_NAME)-$(PACKAGE_VERSION) coverage
> +
> +CLEANFILES += $(COVERAGE_OUTPUT_FILE)
> +
> +clean-local: coverage-clean
> +distclean-local: coverage-clean
> +coverage-clean:
> + -rm -rf $(COVERAGE_OUTPUT_DIRECTORY)
> +
> +coverage-html: $(COVERAGE_OUTPUT_INDEX_HTML)
> + @echo 'file://$(abs_builddir)/$(COVERAGE_OUTPUT_INDEX_HTML)'
> +
> +$(COVERAGE_OUTPUT_INDEX_HTML): $(COVERAGE_OUTPUT_FILE)
> + LC_ALL=C $(GENHTML) \
> + --legend \
> + --show-details \
> + --rc=genhtml_branch_coverage=1 \
> + --title='$(COVERAGE_TITLE)' \
> + --prefix='$(top_builddir)' \
> + --prefix='$(abspath $(abs_top_srcdir))' \
> + --output-directory='$(COVERAGE_OUTPUT_DIRECTORY)' \
> + $<
> +
> +$(COVERAGE_OUTPUT_FILE):
> + $(LCOV) \
> + --capture \
> + --no-checksum \
> + --rc=lcov_branch_coverage=1 \
> + --gcov-tool='$(GCOV)' \
> + --exclude="$$TMPDIR/*" \
> + --exclude='/tmp/*' \
> + --exclude='/usr/include/*' \
> + --exclude='*/tests/*' \
> + --directory='$(top_builddir)' \
> + --output-file='$@'
> +
>  endif

Note that the elfutils-htdocs git repo (which holds the website)
contains an update-coverage.sh script that does:

   # Note we want srcdir == builddir for better output.
   ${tempdir}/elfutils/configure --enable-maintainer-mode --enable-gcov
   make -j$(nproc)
   make check
   lcov -c -d backends -d lib -d libasm -d libcpu -d libdw -d libdwelf
   \
-d libdwfl -d libebl -d libelf -d src -d debuginfod \
--no-external > lcov.out
   genhtml -s --legend -t "elfutils-${version}" -o coverage lcov.out

   So that is executed at the top-level instead of inside the tests dir
   and instead of --exclude it uses -d which IMHO gives slightly nicer
   output by only showing the top-level dirs.

   Otherwise the output generated by your version looks better.

   Cheers,


Re: [PATCH] tests: add coverage-html target

2021-01-11 Thread Dmitry V. Levin
Hi Mark,

On Mon, Jan 11, 2021 at 04:07:38PM +0100, Mark Wielaard wrote:
> Hi Dmitry,
> 
> On Wed, 2020-12-23 at 00:25 +0300, Dmitry V. Levin wrote:
> > Implement a target for capturing code coverage using lcov.
> > It is available when elfutils is configured using --enable-gcov.
> > 
> > Signed-off-by: Dmitry V. Levin 
> > ---
> > Rather than trying to salvage the coverage target, implement a
> > different
> > target for capturing code coverage similar to those I use in other
> > projects.  I'm sure you'll like it, too.
> 
> I like it. We need to integrate it with the elfutils-htdocs update-
> coverage script that is responsible for generating:
> https://sourceware.org/elfutils/coverage/

I didn't know it exists. :)

> See below.
> 
> >  ChangeLog |  4 
> >  configure.ac  |  3 +++
> >  tests/.gitignore  |  2 ++
> >  tests/ChangeLog   |  5 +
> >  tests/Makefile.am | 40 
> >  5 files changed, 54 insertions(+)
> > 
> > diff --git a/ChangeLog b/ChangeLog
> > index 03c90b6b..fe4f1829 100644
> > --- a/ChangeLog
> > +++ b/ChangeLog
> > @@ -1,3 +1,7 @@
> > +2020-12-22  Dmitry V. Levin  
> > +
> > +   * configure.ac [--enable-gcov]: Check for gcov, lcov, and
> > genhtml.
> > +
> >  2020-12-20  Dmitry V. Levin  
> >  
> > * .gitignore: Move subdirectory patterns to separate .gitignore
> > files.
> > diff --git a/configure.ac b/configure.ac
> > index 60747bc8..346ab800 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -311,6 +311,9 @@ if test "$use_gcov" = yes; then
> >CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
> >CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
> >LDFLAGS="$LDFLAGS -fprofile-arcs"
> > +  AC_CHECK_PROG([GCOV], [gcov], [gcov])
> > +  AC_CHECK_PROG([LCOV], [lcov], [lcov])
> > +  AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
> >  fi
> >  AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)
> 
> This is a good idea. But do we need a particular version of lcov?
> I get lcov: Unknown option: exclude
> $ lcov --version
> lcov: LCOV version 1.13
> I don't insist on having it working with old lcov, just that we detect
> it.

lcov --exclude was introduced by lcov commit v1.14~19; yes, we can check
whether e.g. "lcov --exclude=/ --version" works.  Alternatively, we could
use --directory option, but that would require some discipline in
maintaining the list of directories.  What's your preferred choice?

> > diff --git a/tests/.gitignore b/tests/.gitignore
> > index d0e83da2..4aca5c7c 100644
> > --- a/tests/.gitignore
> > +++ b/tests/.gitignore
> > @@ -1,3 +1,5 @@
> > +/*-coverage
> > +/*.lcov
> >  /*.log
> >  /*.trs
> >  /addrcfi
> >
> > diff --git a/tests/ChangeLog b/tests/ChangeLog
> > index 4688b50a..c0d9d4b8 100644
> > --- a/tests/ChangeLog
> > +++ b/tests/ChangeLog
> > @@ -1,3 +1,8 @@
> > +2020-12-22  Dmitry V. Levin  
> > +
> > +   * Makefile.am [GCOV] (coverage-html): New target.
> > +   * .gitignore: Update.
> > +
> >  2020-12-20  Dmitry V. Levin  
> >  
> > * .gitignore: New file.
> > diff --git a/tests/Makefile.am b/tests/Makefile.am
> > index 502becff..293b4225 100644
> > --- a/tests/Makefile.am
> > +++ b/tests/Makefile.am
> > @@ -695,4 +695,44 @@ check: check-am coverage
> >  .PHONY: coverage
> >  coverage:
> > -$(srcdir)/coverage.sh
> > +
> > +COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME)-$(PACKAGE_VERSION).lcov
> > +COVERAGE_OUTPUT_DIRECTORY = $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage

By the way, I'm not sure whether we need -$(PACKAGE_VERSION) in
COVERAGE_OUTPUT_FILE and COVERAGE_OUTPUT_DIRECTORY.

> > +COVERAGE_OUTPUT_INDEX_HTML = $(COVERAGE_OUTPUT_DIRECTORY)/index.html
> > +COVERAGE_TITLE = $(PACKAGE_NAME)-$(PACKAGE_VERSION) coverage
> > +
> > +CLEANFILES += $(COVERAGE_OUTPUT_FILE)
> > +
> > +clean-local: coverage-clean
> > +distclean-local: coverage-clean
> > +coverage-clean:
> > +   -rm -rf $(COVERAGE_OUTPUT_DIRECTORY)
> > +
> > +coverage-html: $(COVERAGE_OUTPUT_INDEX_HTML)
> > +   @echo 'file://$(abs_builddir)/$(COVERAGE_OUTPUT_INDEX_HTML)'
> > +
> > +$(COVERAGE_OUTPUT_INDEX_HTML): $(COVERAGE_OUTPUT_FILE)
> > +   LC_ALL=C $(GENHTML) \
> > +   --legend \
> > +   --show-details \
> > +   --rc=genhtml_branch_coverage=1 \
> > +   --title='$(COVERAGE_TITLE)' \
> > +   --prefix='$(top_builddir)' \
> > +   --prefix='$(abspath $(abs_top_srcdir))' \
> > +   --output-directory='$(COVERAGE_OUTPUT_DIRECTORY)' \
> > +   $<
> > +
> > +$(COVERAGE_OUTPUT_FILE):
> > +   $(LCOV) \
> > +   --capture \
> > +   --no-checksum \
> > +   --rc=lcov_branch_coverage=1 \
> > +   --gcov-tool='$(GCOV)' \
> > +   --exclude="$$TMPDIR/*" \
> > +   --exclude='/tmp/*' \
> > +   --exclude='/usr/include/*' \
> > +   --exclude='*/tests/*' \
> > +   --directory='$(top_builddir)' \
> > +   --output-file='$@'
> > +
> >  endif
> 
> Note that the elfutils-htdocs git repo (which holds the website)
> con

Re: [PATCH] tests: add coverage-html target

2021-01-11 Thread Mark Wielaard
Hi Dmitry,

On Mon, 2021-01-11 at 18:33 +0300, Dmitry V. Levin wrote:
> On Mon, Jan 11, 2021 at 04:07:38PM +0100, Mark Wielaard wrote:
> > 
> lcov --exclude was introduced by lcov commit v1.14~19; yes, we can check
> whether e.g. "lcov --exclude=/ --version" works.  Alternatively, we could
> use --directory option, but that would require some discipline in
> maintaining the list of directories.  What's your preferred choice?

Could we somehow base it on the toplevel SUBDIRS?
Maybe (untested)

  COVDIRS = $(subst tests,,$(SUBDIRS))
  COVDARGS = $(patsubst %,-d%,$(COVDIRS))

> > > +COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME)-$(PACKAGE_VERSION).lcov
> > > +COVERAGE_OUTPUT_DIRECTORY = $(PACKAGE_NAME)-$(PACKAGE_VERSION)-
> > > coverage
> 
> By the way, I'm not sure whether we need -$(PACKAGE_VERSION) in
> COVERAGE_OUTPUT_FILE and COVERAGE_OUTPUT_DIRECTORY.

Maybe not in the output dir/file, but it is nice to have in the title.

> > Note that the elfutils-htdocs git repo (which holds the website)
> > contains an update-coverage.sh script that does:
> > 
> ># Note we want srcdir == builddir for better output.
> >${tempdir}/elfutils/configure --enable-maintainer-mode --enable-gcov
> >make -j$(nproc)
> >make check
> >lcov -c -d backends -d lib -d libasm -d libcpu -d libdw -d libdwelf
> >\
> > -d libdwfl -d libebl -d libelf -d src -d debuginfod \
> > --no-external > lcov.out
> >genhtml -s --legend -t "elfutils-${version}" -o coverage lcov.out
> > 
> >So that is executed at the top-level instead of inside the tests dir
> >and instead of --exclude it uses -d which IMHO gives slightly nicer
> >output by only showing the top-level dirs.
> 
> I suppose the difference between --exclude and -d is only visible when
> srcdir != builddir.  If these directories are different, then
> update-coverage.sh will likely miss some information because of this
> explicit list of directories.

Yeah, so if using --exclude fixes that, then please do use that
instead.

Cheers,

Mark


Re: 0x1000 offset in symbol resolution?

2021-01-11 Thread Mark Wielaard
Hi Milian,

On Wed, 2020-12-30 at 16:51 +0100, Milian Wolff wrote:
> I stumbled upon a strange behavior while symbolizing a perf.data file
> with 
> hotspot/perfparser/elfutils that I have trouble understanding. I hope it's ok 
> to send this call for help here.
> 
> I'm running with elfutils 0.181, g++ 10.2, glibc 2.32 on archlinux with 
> kernel 
> 5.9.14.
> [...]
> So here, the address `0x5a40` should come from the second mapping, 
> which has an offset 0x0 and starts at `0x5000` and has a size of 
> `0x1000`. How can that possibly map to the `main` symbol which has an offset 
> of `0x1a40`?
> 
> Does anyone know what's going on here?

Isn't this simply the ELF file being loaded/mmapped in separate
(overlapping) chunks?

What does eu-readelf -l show?
Is the address/offset range loaded/mmapped executable?

Cheers,

Mark


Re: 0x1000 offset in symbol resolution?

2021-01-11 Thread Milian Wolff
On Montag, 11. Januar 2021 17:05:30 CET Mark Wielaard wrote:
> Hi Milian,
> 
> On Wed, 2020-12-30 at 16:51 +0100, Milian Wolff wrote:
> > I stumbled upon a strange behavior while symbolizing a perf.data file
> > with
> > hotspot/perfparser/elfutils that I have trouble understanding. I hope it's
> > ok to send this call for help here.
> > 
> > I'm running with elfutils 0.181, g++ 10.2, glibc 2.32 on archlinux with
> > kernel 5.9.14.
> > [...]
> > So here, the address `0x5a40` should come from the second mapping,
> > which has an offset 0x0 and starts at `0x5000` and has a size of
> > `0x1000`. How can that possibly map to the `main` symbol which has an
> > offset of `0x1a40`?
> > 
> > Does anyone know what's going on here?
> 
> Isn't this simply the ELF file being loaded/mmapped in separate
> (overlapping) chunks?

Ah, indeed - thanks for this question! It actually seems like perf only 
records this one single mmap event. I.e.:

```
$ perf record ./a.out
$ perf script --show-mmap-events | grep -E 'MMAP.*a.out' 
   a.out 139334 16992.223215: PERF_RECORD_MMAP2 139334/139334: 
[0x55bb21e7(0x1000) @ 0 fe:00 8009266 4286144336]: r-xp /home/milian/
projects/kdab/rnd/hotspot/build/a.out
```

And that is probably the bug. Because when I run the following slightly 
changed perf session, the issue doesn't occur - and I see more mmap events 
too:

```
$ perf record --call-graph dwarf ./a.out
$ perf script --show-mmap-events 2>/dev/null | grep -E 'MMAP.*a.out' 
a.out 139453 17065.223302: PERF_RECORD_MMAP2 139453/139453: 
[0x5589a3711000(0x5000) @ 0 fe:00 8009266 4286144336]: r--p /home/milian/
projects/kdab/rnd/hotspot/build/a.out
a.out 139453 17065.223305: PERF_RECORD_MMAP2 139453/139453: 
[0x5589a3712000(0x1000) @ 0 fe:00 8009266 4286144336]: r-xp /home/milian/
projects/kdab/rnd/hotspot/build/a.out
a.out 139453 17065.223306: PERF_RECORD_MMAP2 139453/139453: 
[0x5589a3713000(0x2000) @ 0 fe:00 8009266 4286144336]: rw-p /home/milian/
projects/kdab/rnd/hotspot/build/a.out
a.out 139453 17065.223307: PERF_RECORD_MMAP2 139453/139453: 
[0x5589a3715000(0x1000) @ 0x1000 fe:00 8009266 4286144336]: rw-p /home/milian/
projects/kdab/rnd/hotspot/build/a.out
a.out 139453 17065.223994: PERF_RECORD_MMAP2 139453/139453: 
[0x5589a3713000(0x2000) @ 0 fe:00 8009266 4286144336]: r--p /home/milian/
projects/kdab/rnd/hotspot/build/a.out
```

Thank you Mark, I'll take this over to the perf mailing list, as it doesn't 
seem to be a problem with elfutils.

> What does eu-readelf -l show?

Probably irrelevant now, but here is the output nevertheless:

```
Program Headers:
  Type   Offset   VirtAddr   PhysAddr   FileSiz  
MemSiz   Flg Align
  PHDR   0x40 0x0040 0x0040 0x000268 
0x000268 R   0x8
  INTERP 0x0002a8 0x02a8 0x02a8 0x1c 
0x1c R   0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD   0x00 0x 0x 0x000934 
0x000934 R   0x1000
  LOAD   0x000940 0x1940 0x1940 0x000530 
0x000530 R E 0x1000
  LOAD   0x000e70 0x2e70 0x2e70 0x000218 
0x000218 RW  0x1000
  LOAD   0x001088 0x4088 0x4088 0x50 
0x0001c8 RW  0x1000
  DYNAMIC0x000e88 0x2e88 0x2e88 0x0001d0 
0x0001d0 RW  0x8
  GNU_RELRO  0x000e70 0x2e70 0x2e70 0x000218 
0x001190 R   0x1
  GNU_EH_FRAME   0x000828 0x0828 0x0828 0x34 
0x34 R   0x4
  GNU_STACK  0x00 0x 0x 0x00 
0x00 RW  0x0
  NOTE   0x0002c4 0x02c4 0x02c4 0x38 
0x38 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00 
   01  [RO: .interp]
   02  [RO: .interp .note.ABI-tag .note.gnu.build-id .dynsym .gnu.version 
.gnu.version_r .gnu.hash .dynstr .rela.dyn .rela.plt .rodata .eh_frame_hdr 
.eh_frame]
   03  [RO: .text .init .fini .plt]
   04  [RELRO: .fini_array .init_array .dynamic .got]
   05  .data .got.plt .bss
   06  [RELRO: .dynamic]
   07  [RELRO: .fini_array .init_array .dynamic .got]
   08  [RO: .eh_frame_hdr]
   09 
   10  [RO: .note.ABI-tag .note.gnu.build-id]
```

> Is the address/offset range loaded/mmapped executable?

See above, I now believe the problem is the lack of reported mmap event to 
begin with.

-- 
Milian Wolff
m...@milianw.de
http://milianw.de

signature.asc
Description: This is a digitally signed message part.


Re: [PATCH] src/elflint.c: fix printing of unknown flags

2021-01-11 Thread Mark Wielaard
Hi Sergei,

On Thu, Dec 31, 2020 at 12:11:42PM +, Sergei Trofimovich via Elfutils-devel 
wrote:
> before the change section_flags_string() ignored unknown section
> flags: snprintf() did write numeric value int obuffer, but
> "*cp = '\0'" hegated the effect.
> 
> The change advances the 'cp' pointer'.
> 
> While at it add a '|' separator between known and unknown flags.

Nice. Thanks for finding this.
Added with a ChangeLog entry and slightly updating the code formatting.

Cheers,

Mark


[PATCH v2] Add coverage target

2021-01-11 Thread Dmitry V. Levin
Implement a target for capturing code coverage using lcov.
It is available when elfutils is configured using --enable-gcov.

Tested with
autoreconf -if && ./configure --enable-maintainer-mode --enable-gcov &&
make && make check && make coverage

Signed-off-by: Dmitry V. Levin 
---
 .gitignore   |  2 ++
 ChangeLog|  6 ++
 Makefile.am  | 49 +
 configure.ac |  3 +++
 4 files changed, 60 insertions(+)

diff --git a/.gitignore b/.gitignore
index 9bf350c1..8bcd88d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,7 @@
 =*
 Makefile
 Makefile.in
+/*.lcov
 /ABOUT-NLS
 /INSTALL
 /aclocal.m4
@@ -26,6 +27,7 @@ Makefile.in
 /config.log
 /config.status
 /configure
+/coverage
 /elfutils.spec
 /stamp-h1
 /version.h
diff --git a/ChangeLog b/ChangeLog
index 03c90b6b..09c1d968 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2021-01-12  Dmitry V. Levin  
+
+   * configure.ac [--enable-gcov]: Check for gcov, lcov, and genhtml.
+   * Makefile.am [GCOV] (coverage): New target.
+   * .gitignore: Update.
+
 2020-12-20  Dmitry V. Levin  
 
* .gitignore: Move subdirectory patterns to separate .gitignore files.
diff --git a/Makefile.am b/Makefile.am
index 818e3599..30f763a9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,6 +47,55 @@ distcheck-hook:
 rpm: dist
rpmbuild -ts --sign elfutils-@PACKAGE_VERSION@.tar.bz2
 
+if GCOV
+
+COVERAGE_OUTPUT_FILE = $(PACKAGE_NAME).lcov
+COVERAGE_OUTPUT_DIRECTORY = coverage
+COVERAGE_OUTPUT_INDEX_HTML = $(COVERAGE_OUTPUT_DIRECTORY)/index.html
+COVERAGE_TITLE = $(PACKAGE_NAME)-$(PACKAGE_VERSION)
+
+COVERAGE_DIRS = $(filter-out tests,$(SUBDIRS))
+src_COVERAGE_DIRS = $(patsubst %,$(srcdir)/%,$(COVERAGE_DIRS))
+build_COVERAGE_DIRS = $(patsubst %,$(builddir)/%,$(COVERAGE_DIRS))
+all_COVERAGE_DIRS = $(sort $(src_COVERAGE_DIRS) $(build_COVERAGE_DIRS))
+LCOV_DIRS_ARGS = $(patsubst %,--directory=%,$(all_COVERAGE_DIRS))
+
+CLEANFILES = $(COVERAGE_OUTPUT_FILE)
+
+.PHONY: coverage coverage-clean
+
+clean-local: coverage-clean
+distclean-local: coverage-clean
+
+coverage-clean:
+   -rm -rf $(COVERAGE_OUTPUT_DIRECTORY)
+
+coverage: $(COVERAGE_OUTPUT_INDEX_HTML)
+   @echo 'file://$(abs_builddir)/$(COVERAGE_OUTPUT_INDEX_HTML)'
+
+$(COVERAGE_OUTPUT_INDEX_HTML): $(COVERAGE_OUTPUT_FILE)
+   LC_ALL=C $(GENHTML) \
+   --legend \
+   --show-details \
+   --rc=genhtml_branch_coverage=1 \
+   --title='$(COVERAGE_TITLE)' \
+   --prefix='$(abspath $(abs_srcdir))' \
+   --prefix='$(abspath $(abs_builddir)/..)' \
+   --output-directory='$(COVERAGE_OUTPUT_DIRECTORY)' \
+   $<
+
+$(COVERAGE_OUTPUT_FILE):
+   $(LCOV) \
+   --capture \
+   --no-external \
+   --no-checksum \
+   --rc=lcov_branch_coverage=1 \
+   --gcov-tool='$(GCOV)' \
+   --output-file='$@' \
+   $(LCOV_DIRS_ARGS)
+
+endif
+
 # Tell version 3.79 and up of GNU make to not build goals in this
 # directory in parallel.
 .NOTPARALLEL:
diff --git a/configure.ac b/configure.ac
index 60747bc8..346ab800 100644
--- a/configure.ac
+++ b/configure.ac
@@ -311,6 +311,9 @@ if test "$use_gcov" = yes; then
   CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
   CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
   LDFLAGS="$LDFLAGS -fprofile-arcs"
+  AC_CHECK_PROG([GCOV], [gcov], [gcov])
+  AC_CHECK_PROG([LCOV], [lcov], [lcov])
+  AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
 fi
 AM_CONDITIONAL(GCOV, test "$use_gcov" = yes)
 
-- 
ldv


[PATCH elfutils-htdocs] update-coverage.sh: use "make coverage"

2021-01-11 Thread Dmitry V. Levin
The coverage report is now prepared by "make coverage".

Signed-off-by: Dmitry V. Levin 
---
 update-coverage.sh | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/update-coverage.sh b/update-coverage.sh
index 46f30ab2..cddfbf24 100755
--- a/update-coverage.sh
+++ b/update-coverage.sh
@@ -29,10 +29,7 @@ autoreconf -v -f -i
 ${tempdir}/elfutils/configure --enable-maintainer-mode --enable-gcov
 make -j$(nproc)
 make check
-lcov -c -d backends -d lib -d libasm -d libcpu -d libdw -d libdwelf \
- -d libdwfl -d libebl -d libelf -d src -d debuginfod \
- --no-external > lcov.out
-genhtml -s --legend -t "elfutils-${version}" -o coverage lcov.out
+make coverage
 
 # Go back end get our new coverage data
 popd
-- 
ldv