1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
|
@c CYGNUS LOCAL: gcov
@c This is a variant form of the gcov doc, modified to fit into GCC manual
@node Gcov
@chapter @code{gcov}: a Test Coverage Program
@code{gcov} is a tool you can use, together with @sc{gnu} CC, to test code
coverage in your programs. @code{gcov} is free software, but for the
moment it is only available from Cygnus Support (pending discussions
with the FSF about how they think Cygnus should @emph{really} write it).
This chapter describes version 1.5 of @code{gcov}.
Jim Wilson wrote @code{gcov}, and the original form of this note.
Pat McGregor edited the documentation.
@menu
* Gcov Intro:: Introduction to gcov.
* Invoking Gcov:: How to use gcov.
* Gcov and Optimization:: Using gcov with GCC optimization.
@end menu
@lowersections
@node Gcov Intro
@chapter Introduction to @code{gcov}
@code{gcov} is a test coverage program. Use it in concert with @sc{gnu} CC
to analyze your programs to help create more efficient, faster running
code. You can use @code{gcov} as a profiling tool, to help discover where
your optimization efforts will best affect your code. You can also use
@code{gcov} in concert with the other profiling tool, @code{gprof}, to
assess which parts of your code use the greatest amount of computing
time.
Profiling tools help you analyze your code's performance. Using a
profiler such as @code{gcov} or @code{gprof}, you can find out some
basic performance statistics, such as:
@itemize @bullet
@item
how often each line of code executes
@item
what lines of code are actually executed
@item
how much computing time each section of code uses
@end itemize
Once you know these things about how your code works when compiled, you
can look at each module to see which modules should be optimized.
@code{gcov} helps you determine where to work on optimization.
Software developers also use coverage testing in concert with
testsuites, to make sure software is actually good enough for a release.
Testsuites can verify that a program works as expected; a coverage
program tests to see how much of the program is exercised by the
testsuite. Developers can then determine what kinds of test cases need
to be added to the testsuites to create both better testing and a better
final product.
You should compile your code without optimization if you plan to use
@code{gcov}, because the optimization, by combining some lines of code
into one function, may not give you as much information as you need to
look for `hot spots' where the code is using a great deal of computer
time. Likewise, because @code{gcov} accumulates statistics by line (at
the lowest resolution), it works best with a programming style that
places only one statement on each line. If you use complicated macros
that expand to loops or to other control structures, the statistics are
less helpful---they only report on the line where the macro call
appears. If your complex macros behave like functions, you can replace
them with inline functions to solve this problem.
@code{gcov} creates a logfile called @file{@var{sourcename}.gcov} which
indicates how many times each line of a source file
@file{@var{sourcename}.c} has executed. You can use these logfiles in
conjuction with @code{gprof} to aid in fine-tuning the performance of
your programs. @code{gprof} gives timing information you can use along
with the information you get from @code{gcov}.
@code{gcov} works only on code compiled with @sc{gnu} CC; it is not
compatible with any other profiling or test coverage mechanism.
@node Invoking Gcov
@chapter Invoking gcov
@smallexample
gcov [-b] [-v] [-n] [-l] [-f] [-o directory] @var{sourcefile}
@end smallexample
@table @code
@item -b
Write branch frequencies to the output file. Write branch summary info
to standard output. This option allows you to see how often each branch
was taken.
@item -v
Display the @code{gcov} version number (on the standard error stream).
@item -n
Do not create the @code{gcov} output file.
@item -l
Create long file names for included source files. For example, if the
header file @samp{x.h} contains code, and was included in the file
@samp{a.c}, then running @code{gcov} on the file @samp{a.c} will produce
an output file called @samp{a.c.x.h.gcov} instead of @samp{x.h.gcov}.
This can be useful if @samp{x.h} is included in multiple source files.
@item -f
Output summaries for each function in addition to the file level summary.
@item -o
The directory where the object files live. Gcov will search for @code{.bb},
@code{.bbg}, and @code{.da} files in this directory.
@end table
@need 3000
To use @code{gcov}, first compile your program with two special @sc{gnu} CC
options: @samp{-fprofile-arcs -ftest-coverage}. Then run the program.
Then run @code{gcov} with your program's source file names as arguments.
For example, if your program is called @samp{tmp.c}, this is what you
see when you use the basic @code{gcov} facility:
@smallexample
$ gcc -fprofile-arcs -ftest-coverage tmp.c
$ a.out
$ gcov tmp.c
87.50% of 8 source lines executed in file tmp.c
Creating tmp.c.gcov.
@end smallexample
The file @file{tmp.c.gcov} contains output from @code{gcov}.
Here is a sample:
@smallexample
main()
@{
1 int i, total;
1 total = 0;
11 for (i = 0; i < 10; i++)
10 total += i;
1 if (total != 45)
###### printf ("Failure\n");
else
1 printf ("Success\n");
1 @}
@end smallexample
@need 450
When you use the @samp{-b} option, your output looks like this:
@smallexample
$ gcov -b tmp.c
87.50% of 8 source lines executed in file tmp.c
80.00% of 5 branches executed in file tmp.c
80.00% of 5 branches taken at least once in file tmp.c
50.00% of 2 calls executed in file tmp.c
Creating tmp.c.gcov.
@end smallexample
Here is a sample of a resulting @file{tmp.c.gcov} file:
@smallexample
main()
@{
1 int i, total;
1 total = 0;
11 for (i = 0; i < 10; i++)
branch 0 taken = 91%
branch 1 taken = 100%
branch 2 taken = 100%
10 total += i;
1 if (total != 45)
branch 0 taken = 100%
###### printf ("Failure\n");
call 0 never executed
branch 1 never executed
else
1 printf ("Success\n");
call 0 returns = 100%
1 @}
@end smallexample
For each basic block, a line is printed after the last line of the basic
block describing the branch or call that ends the basic block. There can
be multiple branches and calls listed for a single source line if there
are multiple basic blocks that end on that line. In this case, the
branches and calls are each given a number. There is no simple way to map
these branches and calls back to source constructs. In general, though,
the lowest numbered branch or call will correspond to the leftmost construct
on the source line.
For a branch, if it was executed at least once, then a percentage
indicating the number of times the branch was taken divided by the number
of times the branch was executed will be printed. Otherwise, the message
``never executed'' is printed.
For a call, if it was executed at least once, then a percentage indicating
the number of times the call returned divided by the number of times the
call was executed will be printed. This will usually be 100%, but may be
less for functions call @code{exit} or @code{longjmp}, and thus may not
return everytime they are called.
@node Gcov and Optimization
@chapter Using @code{gcov} with GCC Optimization
If you plan to use @code{gcov} to help optimize your code, you must
first compile your program with two special @sc{gnu} CC options:
@samp{-fprofile-arcs -ftest-coverage}. Aside from that, you can use any
other @sc{gnu} CC options; but if you want to prove that every single line
in your program was executed, you should not compile with optimization
at the same time. On some machines the optimizer can eliminate some
simple code lines by combining them with other lines. For example, code
like this:
@smallexample
if (a != b)
c = 1;
else
c = 0;
@end smallexample
@noindent
can be compiled into one instruction on some machines. In this case,
there is no way for @code{gcov} to calculate separate execution counts
for each line because there isn't separate code for each line. Hence
the @code{gcov} output looks like this if you compiled the program with
optimization:
@smallexample
100 if (a != b)
100 c = 1;
100 else
100 c = 0;
@end smallexample
The output shows that this block of code, combined by optimization,
executed 100 times. In one sense this result is correct, because there
was only one instruction representing all four of these lines. However,
the output does not indicate how many times the result was 0 and how
many times the result was 1.
@raisesections
|