GCC Middle and Back End API Reference
gcov.c File Reference

Data Structures

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

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 []

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.  
                 S_ISLNK is not POSIX.1-1996.  
                 Cannot elide, or unreadable or a symlink.  
             Regular pathname component.  

References len, and memcpy().

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, free(), memcpy(), memset(), 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 -- we'll be inserting one or two
         entries.  
     Not found, try the canonical name. 
         Not found with canonical name, create a new source.  
             You lose if separators don't match exactly in the
             prefix.  
         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(), and strlen().

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
@verbatim 

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
                    @verbatim 

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, 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.  

References strlen().

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 -- 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_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, 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