From 2b0c34c8d13ab4a899a722ae272a366bf6051168 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Wed, 17 May 2023 18:44:37 +0200 Subject: gcov: example to generate coverage --- src/SUMMARY.md | 1 + src/development/README.md | 1 + src/development/gcov.md | 60 +++++++++++++++++++++++++++++++++++++++++++ src/development/gcov/Makefile | 24 +++++++++++++++++ src/development/gcov/cov.cc | 17 ++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 src/development/gcov.md create mode 100644 src/development/gcov/Makefile create mode 100644 src/development/gcov/cov.cc (limited to 'src') diff --git a/src/SUMMARY.md b/src/SUMMARY.md index f0c9984..ae7bc1e 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -49,6 +49,7 @@ - [ld.so](./development/ld.so.md) - [symbol versioning](./development/symbolver.md) - [python](./development/python.md) + - [gcov](./development/gcov.md) - [Linux](./linux/README.md) - [systemd](./linux/systemd.md) diff --git a/src/development/README.md b/src/development/README.md index bbd27a2..dfea5cd 100644 --- a/src/development/README.md +++ b/src/development/README.md @@ -8,3 +8,4 @@ - [ld.so](./ld.so.md) - [symbol versioning](./symbolver.md) - [python](./python.md) +- [gcov](./gcov.md) diff --git a/src/development/gcov.md b/src/development/gcov.md new file mode 100644 index 0000000..c97a1b0 --- /dev/null +++ b/src/development/gcov.md @@ -0,0 +1,60 @@ +# gcov(1) + +Generate code coverage reports in text format. + +Compile the source files of interest and link the final binary with the +following flags: +- `-fprofile-arcs` instruments the generated code such that it writes a `.gcda` + file when being executed with details about which branches are taken +- `-ftest-coverage` writes a `.gcno` notes file which is used by `gcov` during + generation of the coverage report + +Depending on the build environment one may also set `-fprofile-abs-path` to +generate absolute path names into the `.gcno` note files, this can ease setups +where compilations are done in different directories to the source directory. + +> `gcc` / `clang` also support an alias flag `--coverage` which during +> compilation time is equivalent to `-fprofile-arcs -ftest-coverage` and during +> link time `-lgcov`. + +After running the instrumented binary, the human readable report can then be +generated for a single file for example such as +```shell +gcov +``` + +## Example +```cpp +{{#include gcov/cov.cc:3:}} +``` + +The `gcov` coverage report can be generated as follows for `gcc` or `clang`. +```make +{{#include gcov/Makefile:3:}} +``` + +The will generate a report similar to the following. +```text +cat cov.cc.gcov + -: 0:Source:cov.cc + -: 0:Graph:cov.gcno + -: 0:Data:cov.gcda + -: 0:Runs:1 + -: 1:// Copyright (C) 2023 johannst + -: 2: + -: 3:#include + -: 4: + 2: 5:void tell_me(int desc) { + 2: 6: if (desc & 1) { + 2: 7: std::puts("this"); + -: 8: } else { + #####: 9: std::puts("that"); + -: 10: } + 2: 11:} + -: 12: + 1: 13:int main(int argc, char *argv[]) { + 1: 14: tell_me(argc); + 1: 15: tell_me(argc); + 1: 16: return 0; + -: 17:} +``` diff --git a/src/development/gcov/Makefile b/src/development/gcov/Makefile new file mode 100644 index 0000000..f27f8d8 --- /dev/null +++ b/src/development/gcov/Makefile @@ -0,0 +1,24 @@ +# Copyright (C) 2023 johannst + +CXXFLAGS = -fprofile-arcs -ftest-coverage +# or the alias +#CXXFLAGS = --coverage + +cov-gcc: clean + g++ $(CXXFLAGS) -c -o cov.o cov.cc + g++ $(CXXFLAGS) -o $@ cov.o + ./$@ + gcov --demangled-names cov.cc + cat cov.cc.gcov +.PHONY: cov-gcc + +cov-clang: clean + clang++ $(CXXFLAGS) -c -o cov.o cov.cc + clang++ $(CXXFLAGS) -o $@ cov.o + ./$@ + llvm-cov gcov --demangled-names cov.cc + cat cov.cc.gcov +.PHONY: cov-clang + +clean: + $(RM) *.gcov *.gcno *.gcda *.o cov-* diff --git a/src/development/gcov/cov.cc b/src/development/gcov/cov.cc new file mode 100644 index 0000000..3737d81 --- /dev/null +++ b/src/development/gcov/cov.cc @@ -0,0 +1,17 @@ +// Copyright (C) 2023 johannst + +#include + +void tell_me(int desc) { + if (desc & 1) { + std::puts("this"); + } else { + std::puts("that"); + } +} + +int main(int argc, char *argv[]) { + tell_me(argc); + tell_me(argc); + return 0; +} -- cgit v1.2.3