Skip to content

Commit 106d3ad

Browse files
committed
Add gcov demo
1 parent b96660f commit 106d3ad

File tree

5 files changed

+577
-0
lines changed

5 files changed

+577
-0
lines changed

gcov/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/idea
2+
/idea.gcda
3+
/idea.gcno
4+
/idea.c.gcov

gcov/Makefile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
CPPFLAGS = -DTEST
2+
#CPPFLAGS = -DTEST -DCUSTOM_GCOV
3+
CFLAGS = -Wall -m32 -fprofile-arcs -ftest-coverage
4+
LDFLAGS = -m32 -fprofile-arcs -ftest-coverage
5+
6+
.PHONY: all clean
7+
8+
all: idea
9+
10+
idea: idea.o
11+
12+
idea.o: idea.c idea.h
13+
14+
clean:
15+
-rm -f idea idea.o
16+
-rm -f idea.gcno idea.gcda idea.c.gcov
17+
-rm -f *~

gcov/README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# gcov Demo
2+
3+
[gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) is a tool for coverage testing, i.e. showing whether a given line in a program was called and how many times.
4+
It's used to profile the program and let you know what are the hot areas in the program that could be made more efficient.
5+
6+
This is a demo of using gcov on an implementation of the [IDEA encryption algorithm](https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm).
7+
The original source code is [here](https://github.com/bgreenlee/PassKeeper).
8+
Minor updates were added to fix compiling errors and warnings. A `Makefile` was added.
9+
10+
To test gcov, run `make` to build the program into the `idea` executable file:
11+
12+
```
13+
$ make
14+
cc -Wall -m32 -fprofile-arcs -ftest-coverage -DTEST -c -o idea.o idea.c
15+
cc -m32 -fprofile-arcs -ftest-coverage idea.o -o idea
16+
$ ls
17+
idea idea.c idea.gcno idea.h idea.o Makefile README.md
18+
```
19+
20+
An `idea.gcno` file is also generated (gcov notes).
21+
As told in the [official documentation](https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html), the `.gcno file` is a platform-independent static representation of the program, i.e. the control flow graph: basic blocks and arcs between basic blocks.
22+
23+
Running the program provides the runtime information in the `idea.gcda` file:
24+
25+
```
26+
$ ./idea
27+
[...]
28+
$ ls
29+
idea idea.c idea.gcda idea.gcno idea.h idea.o Makefile README.md
30+
```
31+
32+
The `.gcda` file is a platform-independent representation of the runtime profiling information, i.e. arc transition counts between basic blocks.
33+
34+
gcov then provides a human-readable view of the profiling information based on the two files (`.gcno` and `.gcda`), resulting in a `.gcov` file.
35+
36+
```
37+
razvan@yggdrasil:~/projects/snippets.git/gcov$ gcov idea.c
38+
File 'idea.c'
39+
Lines executed:97.32% of 149
40+
Creating 'idea.c.gcov'
41+
42+
razvan@yggdrasil:~/projects/snippets.git/gcov$ ls
43+
idea idea.c idea.c.gcov idea.gcda idea.gcno idea.h idea.o Makefile README.md
44+
razvan@yggdrasil:~/projects/snippets.git/gcov$ less idea.c.gcov
45+
```
46+
47+
The `idea.c.gcov` file lists the program source code together with the number of times each line was called.
48+
49+
Additional information is provided by using certain options to the `gcov` command:
50+
51+
```
52+
razvan@yggdrasil:~/projects/snippets.git/gcov$ gcov -acf idea.c
53+
Function 'main'
54+
Lines executed:96.00% of 50
55+
56+
Function 'ideaCipher'
57+
Lines executed:100.00% of 38
58+
59+
Function 'ideaInvertKey'
60+
Lines executed:100.00% of 33
61+
62+
Function 'ideaExpandKey'
63+
Lines executed:100.00% of 10
64+
65+
Function 'mulInv'
66+
Lines executed:88.89% of 18
67+
68+
File 'idea.c'
69+
Lines executed:97.32% of 149
70+
Creating 'idea.c.gcov'
71+
```
72+
73+
[gcovr](https://github.com/gcovr/gcovr) can be used to present coverage information in different formats.
74+
75+
## Custom Coverage
76+
77+
It may be the case that coverage / profile information for only certain functions is of interest.
78+
gcov offers an API to reset and dump the coverage information (as told in the [official documentation](https://gcc.gnu.org/onlinedocs/gcc/Gcov-and-Optimization.html#Gcov-and-Optimization), thereby restricting colected information to the program sequence between `__gcov_reset()` and `__gcov_dump()` function calls.
79+
80+
Update the `CPPFLAGS` variabile in the `Makefile` to use the `-DCUSTOM_GCOV` flag, i.e. the first two lines of the `Makefile` should be:
81+
82+
```
83+
#CPPFLAGS = -DTEST
84+
CPPFLAGS = -DTEST -DCUSTOM_GCOV
85+
```
86+
87+
The `CUSTOM_GCOV` flag will restrict the coverage information to the following program sequence:
88+
89+
```
90+
340 #ifdef CUSTOM_GCOV
91+
341 __gcov_reset();
92+
342 #endif
93+
343 for (l = 0; l < BLOCKS; l++)
94+
344 ideaCipher(YY, YY, EK); /* repeated encryption */
95+
345 #ifdef CUSTOM_GCOV
96+
346 __gcov_dump();
97+
347 #endif
98+
```
99+
100+
Now rebuild and rerun the program:
101+
```
102+
$ make clean
103+
$ make
104+
$ ./idea
105+
```
106+
107+
The coverage information will now be limited to the calls of the `ideaCipher()` function in the loop in lines `343` and `344`.
108+
109+
## Internals
110+
111+
The `.gcda` file is by default created at runtime in the current working directory.
112+
This can be changed by using the `-fprofile-dir` command line option to `gcc`.
113+
114+
The `.gcno` file is created by the compiler when using the `-ftest-coverage` command line option to `gcc`.
115+
It is technically not required for coverage information, as is the case with the `.gcda` file; the `.gcno` file is used as a support file by `gcov` to provide a human-readable view of the profiling information.
116+
PGO (*Profile Guided Optimization*) uses only `.gcda` files.
117+
118+
The format of the `.gcda` and `.gcno` files is documented in the [gcov-io.h file](http://src.gnu-darwin.org/src/contrib/gcc/gcov-io.h.html) and parsed and used in the [gcov-io.c file](http://src.gnu-darwin.org/src/contrib/gcc/gcov-io.c.html).

0 commit comments

Comments
 (0)