GCC Middle and Back End API Reference
gcov.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "intl.h"
#include "diagnostic.h"
#include "version.h"
#include "demangle.h"
#include <getopt.h>
#include "gcov-io.h"
#include "gcov-io.c"
Include dependency graph for gcov.c:

Data Structures

struct  arc_info
struct  block_info
struct  function_info
struct  coverage_info
struct  line_info
struct  source_info
struct  name_map

Macros

#define IN_GCOV   1
#define ENTRY_BLOCK   (0)
#define EXIT_BLOCK   (1)

Typedefs

typedef struct arc_info arc_t
typedef struct block_info block_t
typedef struct function_info function_t
typedef struct coverage_info coverage_t
typedef struct line_info line_t
typedef struct source_info source_t
typedef struct name_map name_map_t

Functions

static int process_args (int, char **)
static void print_usage (static int output_branch_count(FILE int)
static void print_usage ()
static void print_version ()
static int process_args ()
static char * get_gcov_intermediate_filename ()
static void output_intermediate_file ()
static void process_file ()
static void output_gcov_file ()
static void generate_results ()
static void release_function ()
static void release_structures ()
static void create_file_names ()
static int name_search ()
static int name_sort ()
static unsigned find_source ()
static function_tread_graph_file ()
static int read_count_file ()
static void solve_flow_graph ()
static void find_exception_blocks ()
static void add_branch_counts ()
static char const * format_gcov ()
static void executed_summary ()
static void function_summary ()
static char * canonicalize_name ()
static char * make_gcov_file_name ()
static char * mangle_name ()
static void add_line_counts ()
static void accumulate_line_counts ()
static int output_branch_count ()
static const char * read_line ()
static void output_lines ()

Variables

static function_tfunctions
static function_t ** fn_end = &functions
static source_tsources
static unsigned n_sources
static unsigned a_sources
static name_map_tnames
static unsigned n_names
static unsigned a_names
static unsigned object_runs
static unsigned program_count
static unsigned total_lines
static unsigned total_executed
static time_t bbg_file_time
static char * bbg_file_name
static unsigned bbg_stamp
static char * da_file_name
static int no_data_file
static int multiple_files = 0
static int flag_branches = 0
static int flag_unconditional = 0
static int flag_gcov_file = 1
static int flag_display_progress = 0
static int flag_intermediate_format = 0
static int flag_demangled_names = 0
static int flag_long_names = 0
static int flag_all_blocks = 0
static int flag_function_summary = 0
static char * object_directory = 0
static char * source_prefix = 0
static size_t source_length = 0
static int flag_relative_only = 0
static int flag_preserve_paths = 0
static int flag_counts = 0
static struct option options []

Macro Definition Documentation

#define ENTRY_BLOCK   (0)

Array of basic blocks. Like in GCC, the entry block is at blocks[0] and the exit block is at blocks[1].

#define EXIT_BLOCK   (1)
#define IN_GCOV   1

Gcov.c: prepend line execution counts and branch probabilities to a source file. Copyright (C) 1990-2013 Free Software Foundation, Inc. Contributed by James E. Wilson of Cygnus Support. Mangled by Bob Manson of Cygnus Support. Mangled further by Nathan Sidwell natha.nosp@m.n@co.nosp@m.desou.nosp@m.rcer.nosp@m.y.com

Gcov is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Gcov is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Gcov; see the file COPYING3. If not see http://www.gnu.org/licenses/. ??? Print a list of the ten blocks with the highest execution counts, and list the line numbers corresponding to those blocks. Also, perhaps list the line numbers with the highest execution counts, only printing the first if there are several which are all listed in the same block. ??? Should have an option to print the number of basic blocks, and the percent of them that are covered. Need an option to show individual block counts, and show probabilities of fall through arcs.


Typedef Documentation

typedef struct arc_info arc_t

Describes an arc between two basic blocks.

typedef struct block_info block_t

Describes a basic block. Contains lists of arcs to successor and predecessor blocks.

typedef struct coverage_info coverage_t

Describes coverage of a file or function.

typedef struct function_info function_t

Describes a single function. Contains an array of basic blocks.

typedef struct line_info line_t

Describes a single line of source. Contains a chain of basic blocks with code on it.

typedef struct name_map name_map_t
typedef struct source_info source_t

Describes a file mentioned in the block graph. Contains an array of line info.


Function Documentation

static void accumulate_line_counts ( )
static

Accumulate the line counts of a file.

 Reverse the function order.   
         Total and reverse the branch information.   
         The user expects the line count to be the number of times
         a line has been executed. Simply summing the block count
         will give an artificially high number.  The Right Thing
         is to sum the entry counts to the graph of blocks on this
         line, then find the elementary cycles of the local graph
         and add the transition counts of those cycles.   
         Reverse the block information.   
         Sum the entry arcs.   
             Initialize the cs_count.   
         Find the loops. This uses the algorithm described in
         Tiernan 'An Efficient Search Algorithm to Find the
         Elementary Circuits of a Graph', CACM Dec 1970. We hold
         the P array by having each block point to the arc that
         connects to the previous block. The H array is implicitly
         held because of the arc ordering, and the block's
         previous arc pointer.

         Although the algorithm is O(N^3) for highly connected
         graphs, at worst we'll have O(N^2), as most blocks have
         only one or two exits. Most graphs will be small.

         For each loop we find, locate the arc with the smallest
         transition count, and add that to the cumulative
         count.  Decrease flow over the cycle and remove the arc
         from consideration.   
                     Not to same graph, or before first vertex.   
                     Already in path.   
                     Found a closing arc.   
                     Locate the smallest arc count of the loop.   
                     Remove the flow from the cycle.   
                     Unwind to the cyclic arc.   
                     Move on.   
                 Add new block to chain.   
             We could not add another vertex to the path. Remove
             the last vertex from the list.   
                 It was not the first vertex. Move onto next arc.   
             Mark this block as unusable.   
static void add_branch_counts ( )
static

Increment totals in COVERAGE according to arc ARC.

Referenced by mangle_name().

static void add_line_counts ( )
static

Scan through the bb_data for each line in the block, increment the line number execution count indicated by the execution count of the appropriate basic block.

Scan each basic block.

       Entry or exit block  
static char* canonicalize_name ( )
static

Canonicalize the filename NAME by canonicalizing directory separators, eliding . components and resolving .. components appropriately. Always returns a unique string.

 The canonical name cannot be longer than the incoming name.   
       Elide a '.' directory  
         '..', we can only elide it and the previous directory, if
         we're not a symlink.   
             Cannot elide, or unreadable or a symlink.   
         Regular pathname component.   

Referenced by create_file_names().

static void create_file_names ( )
static

Generate the names of the graph and data files. If OBJECT_DIRECTORY is not specified, these are named from FILE_NAME sans extension. If OBJECT_DIRECTORY is specified and is a directory, the files are in that directory, but named from the basename of the FILE_NAME, sans extension. Otherwise OBJECT_DIRECTORY is taken to be the name of the object file and the data files are named from that.

 Free previous file names.   
     Append source file name.   
 Remove the extension.   

References a_names, a_sources, canonicalize_name(), source_info::coverage, n_names, n_sources, coverage_info::name, source_info::name, name_map::name, name_search(), source_length, source_prefix, and name_map::src.

static void executed_summary ( )
static

Summary of execution

References flag_long_names.

static void find_exception_blocks ( )
static

Mark all the blocks only reachable via an incoming catch.

First mark all blocks as exceptional.

 Now mark all the blocks reachable via non-fake edges  
static unsigned find_source ( )
static

Find or create a source file structure for FILE_NAME. Copies FILE_NAME on creation

Extend the name map array &ndash; we'll be inserting one or two
entries.   
 Not found, try the canonical name.  


     Not found with canonical name, create a new source.   
     Append the non-canonical name.   
 Resort the name map.   
static char const* format_gcov ( )
static

Format a GCOV_TYPE integer as either a percent ratio, or absolute count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places. If DP is zero, no decimal point is printed. Only print 100% when TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply format TOP. Return pointer to a static string.

static void function_summary ( )
static

Output summary info for a function or file.

References mangle_name().

static void generate_results ( )
static
     Open the intermediate file.   
         Ignore this source, if it is an absolute path (after
         source prefix removal).   
           Output the intermediate format without requiring source
           files.  This outputs a section to a *single* file.   
     Now we've finished writing the intermediate file.   
static char* get_gcov_intermediate_filename ( )
static

Get the name of the gcov file. The return value must be free'd.

It appends the '.gcov' extension to the basename of the file. The resulting file name will be in PWD.

e.g., input: foo.da, output: foo.da.gcov input: a/b/foo.cc, output: foo.cc.gcov

Find the 'basename'.

References arc_info::count, block_info::count, and arc_info::src.

static char* make_gcov_file_name ( )
static

Generate an output file name. INPUT_NAME is the canonicalized main input file and SRC_NAME is the canonicalized file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation. With long_output_names we prepend the processed name of the input file to each output name (except when the current source file is the input file, so you don't get a double concatenation). The two components are separated by '##'. With preserve_paths we create a filename from all path components of the source file, replacing '/' with '#', and .. with '^', without it we simply take the basename component. (Remember, the canonicalized name will already have elided '.' components and converted \ separators.)

Generate the input filename part.

References line_info::blocks, block_info::chain, function_info::line, source_info::lines, function_info::src, and line_info::u.

static char* mangle_name ( )
static
static int name_search ( )
static

A is a string and B is a pointer to name_map_t. Compare for file name orderability.

Referenced by create_file_names().

static int name_sort ( )
static

A and B are a pointer to name_map_t. Compare for file name orderability.

References bbg_file_name, and fnotice().

static int output_branch_count ( )
static

Output information about ARC number IX. Returns nonzero if anything is output.

static void output_gcov_file ( )
static
static void output_intermediate_file ( )
static

Output the result in intermediate format used by 'lcov'.

The intermediate format contains a single file named 'foo.cc.gcov', with no source code included. A sample output is

file:foo.cc function:5,1,Z3foov function:13,1,main function:19,1,_GLOBAL__sub_I__Z3foov function:19,1,_Z41__static_initialization_and_destruction_0ii lcount:5,1 lcount:7,9 lcount:9,8 lcount:11,1 file:/.../iostream lcount:74,1 file:/.../basic_ios.h file:/.../ostream file:/.../ios_base.h function:157,0,_ZStorSt12_Ios_IostateS lcount:157,0 file:/.../char_traits.h function:258,0,_ZNSt11char_traitsIcE6lengthEPKc lcount:258,0 ...

The default gcov outputs multiple files: 'foo.cc.gcov', 'iostream.gcov', 'ios_base.h.gcov', etc. with source code included. Instead the intermediate format here outputs only a single file 'foo.cc.gcov' similar to the above example.

function:<name>,<line_number>,<execution_count>

               branch:<line_num>,<branch_coverage_type>
               branch_coverage_type
                 : notexec (Branch not executed)
                 : taken (Branch executed and taken)
                 : nottaken (Branch executed, but not taken)

References function_info::blocks, block_info::line, source_info::num_lines, and block_info::u.

static void output_lines ( )
static

Read in the source file one line at a time, and output that line to the gcov file preceded by its execution count and other information.

For lines which don't exist in the .bb file, print '-' before
the source line.  For lines which exist but were never
executed, print '#####' or '=====' before the source line.
Otherwise, print the execution count before the source line.
There are 16 spaces of indentation added before the source
line so that tabs won't be messed up.   

Handle all remaining source lines. There may be lines after the last line of code.

static void print_usage ( static int output_branch_count (FILE  int)
static

Unlock the stdio streams.

 Handle response files.   

References flag_display_progress, and process_file().

static void print_usage ( void  )
static

Print a usage message and exit. If ERROR_P is nonzero, this is an error, otherwise the output of –help.

References flag_all_blocks, flag_branches, flag_counts, flag_demangled_names, flag_function_summary, flag_gcov_file, flag_long_names, NULL, and print_usage().

static void print_version ( void  )
static

Print version information and exit.

static int process_args ( int  ,
char **   
)
static

Forward declarations.

static int process_args ( )
static

Process args, return index to first non-arg.

         print_usage will exit.   
         print_version will exit.   
         print_usage will exit.   
static void process_file ( )
static

Process a single input file.

         Now insert it into the source file's list of
         functions. Normally functions will be encountered in
         ascending order, so a simple scan is quick.  Note we're
         building this list in reverse order.   
         Mark last line in files touched by function.   
       The function was not in the executable &ndash; some other
       instance must have been selected.   

Referenced by print_usage().

static int read_count_file ( )
static

Reads profiles from the count file and attach to each function. Return nonzero if fatal error.

Try to find the function in the list. To speed up the search, first start from the last function found.

static function_t* read_graph_file ( )
static

Read the notes file. Return list of functions read – in reverse order.

                     Exceptional exit from this function, the
                     source block must be a call.   
                     Non-local return from a callee of this
                     function. The destination block is a setjmp.   
             We have a fake exit from this block.  The other
             non-fall through exits must be to catch handlers.
             Mark them as catch arcs.   

References function_info::blocks, arc_info::count, arc_info::count_valid, arc_info::dst, arc_info::fake, arc_info::fall_through, GCOV_ARC_FAKE, GCOV_ARC_FALLTHROUGH, GCOV_ARC_ON_TREE, gcov_read_unsigned(), arc_info::is_call_non_return, block_info::is_call_site, arc_info::is_nonlocal_return, block_info::is_nonlocal_return, function_info::num_blocks, function_info::num_counts, block_info::num_pred, block_info::num_succ, arc_info::on_tree, block_info::pred, arc_info::pred_next, arc_info::src, block_info::succ, and arc_info::succ_next.

static const char* read_line ( )
static
static void release_function ( )
static

Release a function structure

static void release_structures ( )
static

Release all memory used.

References name_map::name.

static void solve_flow_graph ( )
static

Solve the flow graph. Propagate counts from the instrumented arcs to the blocks and the uninstrumented arcs.

 The arcs were built in reverse order.  Fix that now.   
       We can't deduce the entry block counts from the lack of
       predecessors.   
       Likewise, we can't deduce exit block counts from the lack
       of its successors.   
 Propagate the measured counts, this must be done in the same
 order as the code in profile.c   
         If there is only one non-fake exit, it is an
         unconditional branch.   
               If this block is instrumenting a call, it might be
               an artificial block. It is not artificial if it has
               a non-fallthrough exit, or the destination of this
               arc has more than one entry.  Mark the destination
               block as a return site, if none of those conditions
               hold.   
     Sort the successor arcs into ascending dst order. profile.c
     normally produces arcs in the right order, but sometimes with
     one or two out of order.  We're not using a particularly
     smart sort.   
     Place it on the invalid chain, it will be ignored if that's
     wrong.   
 If the graph has been correctly solved, every block will have a
 valid count.   

References arc_info::dst, NULL, and arc_info::succ_next.


Variable Documentation

unsigned a_names
static

Referenced by create_file_names().

unsigned a_sources
static

Referenced by create_file_names().

char* bbg_file_name
static

Name of the notes (gcno) output file. The "bbg" prefix is for historical reasons, when the notes file contained only the basic block graph notes.

Referenced by name_sort().

time_t bbg_file_time
static

Modification time of graph file.

unsigned bbg_stamp
static

Stamp of the bbg file

char* da_file_name
static

Name and file pointer of the input file for the count data (gcda).

int flag_all_blocks = 0
static

Output count information for every basic block, not merely those that contain line number information.

Referenced by mangle_name(), and print_usage().

int flag_branches = 0
static

Output branch probabilities.

Referenced by print_usage().

int flag_counts = 0
static

Output the number of times a branch was taken as opposed to the percentage of times it was taken.

Referenced by print_usage().

int flag_demangled_names = 0
static

Output demangled function names.

Referenced by print_usage().

int flag_display_progress = 0
static

Output progress indication if this is true. This is off by default and can be turned on by the -d option.

Referenced by print_usage().

int flag_function_summary = 0
static

Output summary info for each function.

Referenced by print_usage().

int flag_gcov_file = 1
static

Output a gcov file if this is true. This is on by default, and can be turned off by the -n option.

Referenced by print_usage().

int flag_intermediate_format = 0
static

Output *.gcov file in intermediate format used by 'lcov'.

int flag_long_names = 0
static

For included files, make the gcov output file name include the name of the input source file. For example, if x.h is included in a.c, then the output file name is a.c##x.h.gcov instead of x.h.gcov.

Referenced by executed_summary(), and print_usage().

int flag_preserve_paths = 0
static

Preserve all pathname components. Needed when object files and source files are in subdirectories. '/' is mangled as '#', '.' is elided and '..' mangled to '^'.

int flag_relative_only = 0
static

Only show data for sources with relative pathnames. Absolute ones usually indicate a system header file, which although it may contain inline functions, is usually uninteresting.

int flag_unconditional = 0
static

Show unconditional branches too.

function_t** fn_end = &functions
static
function_t* functions
static

Holds a list of function basic block graphs.

int multiple_files = 0
static

If there is several input files, compute and display results after reading all data files. This way if two or more gcda file refer to the same source file (eg inline subprograms in a .h file), the counts are added.

unsigned n_names
static

Referenced by create_file_names().

unsigned n_sources
static

Referenced by create_file_names().

name_map_t* names
static
int no_data_file
static

Data file is missing.

char* object_directory = 0
static

Object directory file prefix. This is the directory/file where the graph and data files are looked for, if nonzero.

unsigned object_runs
static

This holds data summary information.

struct option options[]
static
Initial value:
{
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "all-blocks", no_argument, NULL, 'a' },
{ "branch-probabilities", no_argument, NULL, 'b' },
{ "branch-counts", no_argument, NULL, 'c' },
{ "intermediate-format", no_argument, NULL, 'i' },
{ "no-output", no_argument, NULL, 'n' },
{ "long-file-names", no_argument, NULL, 'l' },
{ "function-summaries", no_argument, NULL, 'f' },
{ "demangled-names", no_argument, NULL, 'm' },
{ "preserve-paths", no_argument, NULL, 'p' },
{ "relative-only", no_argument, NULL, 'r' },
{ "object-directory", required_argument, NULL, 'o' },
{ "object-file", required_argument, NULL, 'o' },
{ "source-prefix", required_argument, NULL, 's' },
{ "unconditional-branches", no_argument, NULL, 'u' },
{ "display-progress", no_argument, NULL, 'd' },
{ 0, 0, 0, 0 }
}
unsigned program_count
static
size_t source_length = 0
static

Referenced by create_file_names().

char* source_prefix = 0
static

Source directory prefix. This is removed from source pathnames that match, when generating the output file name.

Referenced by create_file_names().

source_t* sources
static
unsigned total_executed
static
unsigned total_lines
static