gcc: Gcov and Optimization
1
1 10.3 Using 'gcov' with GCC Optimization
1 =======================================
1
1 If you plan to use 'gcov' to help optimize your code, you must first
1 compile your program with two special GCC options: '-fprofile-arcs
1 -ftest-coverage'. Aside from that, you can use any other GCC options;
1 but if you want to prove that every single line in your program was
1 executed, you should not compile with optimization at the same time. On
1 some machines the optimizer can eliminate some simple code lines by
1 combining them with other lines. For example, code like this:
1
1 if (a != b)
1 c = 1;
1 else
1 c = 0;
1
1 can be compiled into one instruction on some machines. In this case,
1 there is no way for 'gcov' to calculate separate execution counts for
1 each line because there isn't separate code for each line. Hence the
1 'gcov' output looks like this if you compiled the program with
1 optimization:
1
1 100: 12:if (a != b)
1 100: 13: c = 1;
1 100: 14:else
1 100: 15: c = 0;
1
1 The output shows that this block of code, combined by optimization,
1 executed 100 times. In one sense this result is correct, because there
1 was only one instruction representing all four of these lines. However,
1 the output does not indicate how many times the result was 0 and how
1 many times the result was 1.
1
1 Inlineable functions can create unexpected line counts. Line counts
1 are shown for the source code of the inlineable function, but what is
1 shown depends on where the function is inlined, or if it is not inlined
1 at all.
1
1 If the function is not inlined, the compiler must emit an out of line
1 copy of the function, in any object file that needs it. If 'fileA.o'
1 and 'fileB.o' both contain out of line bodies of a particular inlineable
1 function, they will also both contain coverage counts for that function.
1 When 'fileA.o' and 'fileB.o' are linked together, the linker will, on
1 many systems, select one of those out of line bodies for all calls to
1 that function, and remove or ignore the other. Unfortunately, it will
1 not remove the coverage counters for the unused function body. Hence
1 when instrumented, all but one use of that function will show zero
1 counts.
1
1 If the function is inlined in several places, the block structure in
1 each location might not be the same. For instance, a condition might
1 now be calculable at compile time in some instances. Because the
1 coverage of all the uses of the inline function will be shown for the
1 same source lines, the line counts themselves might seem inconsistent.
1
1 Long-running applications can use the '__gcov_reset' and '__gcov_dump'
1 facilities to restrict profile collection to the program region of
1 interest. Calling '__gcov_reset(void)' will clear all profile counters
1 to zero, and calling '__gcov_dump(void)' will cause the profile
1 information collected at that point to be dumped to '.gcda' output
1 files. Instrumented applications use a static destructor with priority
1 99 to invoke the '__gcov_dump' function. Thus '__gcov_dump' is executed
1 after all user defined static destructors, as well as handlers
1 registered with 'atexit'. If an executable loads a dynamic shared
1 object via dlopen functionality, '-Wl,--dynamic-list-data' is needed to
1 dump all profile data.
1