⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gcov.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		    * 100), function_branches, function_name);	  fprintf (stdout,		"%6.2lf%% of %d branches taken at least once in function %s\n",		   (((double) function_branches_taken / function_branches)		    * 100), function_branches, function_name);	}      else	fprintf (stdout, "No branches in function %s\n", function_name);      if (function_calls)	fprintf (stdout, "%6.2lf%% of %d calls executed in function %s\n",		 (((double) function_calls_executed / function_calls)		  * 100), function_calls, function_name);      else	fprintf (stdout, "No calls in function %s\n", function_name);    }}/* Calculate line execution counts, and output the data to a .tcov file.  */static voidoutput_data (){  /* When scanning data, this is true only if the data applies to the     current source file.  */  int this_file;  /* An array indexed by line number which indicates how many times that line     was executed.  */  long *line_counts;  /* An array indexed by line number which indicates whether the line was     present in the bb file (i.e. whether it had code associate with it).     Lines never executed are those which both exist, and have zero execution     counts.  */  char *line_exists;  /* An array indexed by line number, which contains a list of branch     probabilities, one for each branch on that line.  */  struct arcdata **branch_probs;  struct sourcefile *s_ptr;  char *source_file_name;  FILE *source_file;  struct bb_info_list *current_graph;  int count;  char *cptr;  long block_num;  long line_num;  long last_line_num;  int i;  struct arcdata *a_ptr;  /* Buffer used for reading in lines from the source file.  */  char string[STRING_SIZE];  /* For calculating coverage at the file level.  */  int total_source_lines;  int total_source_lines_executed;  int total_branches;  int total_branches_executed;  int total_branches_taken;  int total_calls;  int total_calls_executed;  /* Now, for each source file, allocate an array big enough to hold a count     for each line.  Scan through the bb_data, and when the file name matches     the current file name, then for each following line number, increment     the line number execution count indicated by the execution count of     the appropriate basic block.  */  for (s_ptr = sources; s_ptr; s_ptr = s_ptr->next)    {      /* If this is a relative file name, and an object directory has been	 specified, then make it relative to the object directory name.  */      if (*s_ptr->name != '/' && object_directory != 0	  && *object_directory != '\0')	{	  int objdir_count = strlen (object_directory);	  source_file_name = xmalloc (objdir_count + strlen (s_ptr->name) + 2);	  strcpy (source_file_name, object_directory);	  if (object_directory[objdir_count - 1] != '/')	    source_file_name[objdir_count++] = '/';	  strcpy (source_file_name + objdir_count, s_ptr->name);	}      else	source_file_name = s_ptr->name;      line_counts = (long *) xmalloc (sizeof (long) * s_ptr->maxlineno);      bzero ((char *) line_counts, sizeof (long) * s_ptr->maxlineno);      line_exists = xmalloc (s_ptr->maxlineno);      bzero (line_exists, s_ptr->maxlineno);      if (output_branch_probs)	{	  branch_probs = (struct arcdata **) xmalloc (sizeof (struct arcdata **)						      * s_ptr->maxlineno);	  bzero ((char *) branch_probs, 		 sizeof (struct arcdata **) * s_ptr->maxlineno);	}            /* There will be a zero at the beginning of the bb info, before the	 first list of line numbers, so must initialize block_num to 0.  */      block_num = 0;      this_file = 0;      current_graph = 0;      {	/* Pointer into the bb_data, incremented while scanning the data.  */	char *ptr = bb_data;	for (count = 0; count < bb_data_size; count++)	  {	    long delim;	    __fetch_long (&line_num, ptr, 4);	    ptr += 4;	    if (line_num == -1)	      {		/* Marks the beginning of a file name.  Check to see whether		   this is the filename we are currently collecting data for.  */		if (strcmp (s_ptr->name, ptr))		  this_file = 0;		else		  this_file = 1;	      		/* Scan past the file name.  */		do {		  count++;		  __fetch_long (&delim, ptr, 4);		  ptr += 4;		} while (delim != line_num);	      }	    else if (line_num == -2)	      {		/* Marks the start of a new function.  Advance to the next		   program flow graph.  */		if (! current_graph)		  current_graph = bb_graph_list;		else		  {		    if (block_num == current_graph->num_blocks - 1)		      /* Last block falls through to exit.  */		      ;		    else if (block_num == current_graph->num_blocks - 2)		      {			if (output_branch_probs && this_file)			  calculate_branch_probs (current_graph, block_num,						  branch_probs, last_line_num);		      }		    else		      {			fprintf (stderr,				 "didn't use all bb entries of graph, function %s\n",				 function_name);			fprintf (stderr, "block_num = %d, num_blocks = %d\n",				 block_num, current_graph->num_blocks);		      }		    current_graph = current_graph->next;		    block_num = 0;		    if (output_function_summary && this_file)		      function_summary ();		  }		if (output_function_summary)		  {		    function_source_lines = 0;		    function_source_lines_executed = 0;		    function_branches = 0;		    function_branches_executed = 0;		    function_branches_taken = 0;		    function_calls = 0;		    function_calls_executed = 0;		  }		/* Save the function name for later use.  */		function_name = ptr;		/* Scan past the file name.  */		do {		  count++;		  __fetch_long (&delim, ptr, 4);		  ptr += 4;		} while (delim != line_num);	      }	    else if (line_num == 0)	      {		/* Marks the end of a block.  */		if (block_num >= current_graph->num_blocks)		  {		    fprintf (stderr, "ERROR: too many basic blocks in .bb file %s\n",			     function_name);		    abort ();		  }		  		if (output_branch_probs && this_file)		  calculate_branch_probs (current_graph, block_num,					  branch_probs, last_line_num);		block_num++;	      }	    else if (this_file)	      {		if (output_function_summary)		  {		    if (line_exists[line_num] == 0)		      function_source_lines++;		    if (line_counts[line_num] == 0			&& current_graph->bb_graph[block_num].exec_count != 0)		      function_source_lines_executed++;		  }		/* Accumulate execution data for this line number.  */		line_counts[line_num]		  += current_graph->bb_graph[block_num].exec_count;		line_exists[line_num] = 1;		last_line_num = line_num;	      }	  }      }      if (output_function_summary && this_file)	function_summary ();      /* Calculate summary test coverage statistics.  */      total_source_lines = 0;      total_source_lines_executed = 0;      total_branches = 0;      total_branches_executed = 0;      total_branches_taken = 0;      total_calls = 0;      total_calls_executed = 0;      for (count = 1; count < s_ptr->maxlineno; count++)	{	  if (line_exists[count])	    {	      total_source_lines++;	      if (line_counts[count])		total_source_lines_executed++;	    }	  if (output_branch_probs)	    {	      for (a_ptr = branch_probs[count]; a_ptr; a_ptr = a_ptr->next)		{		  if (a_ptr->call_insn)		    {		      total_calls++;		      if (a_ptr->prob != -1)			total_calls_executed++;		    }		  else		    {		      total_branches++;		      if (a_ptr->prob != -1)			total_branches_executed++;		      if (a_ptr->prob > 0)			total_branches_taken++;		    }		}	    }	}      if (total_source_lines)	fprintf (stdout,		 "%6.2lf%% of %d source lines executed in file %s\n",		 (((double) total_source_lines_executed / total_source_lines)		  * 100), total_source_lines, source_file_name);      else	fprintf (stdout, "No executable source lines in file %s\n",		 source_file_name);      if (output_branch_probs)	{	  if (total_branches)	    {	      fprintf (stdout, "%6.2lf%% of %d branches executed in file %s\n",		       (((double) total_branches_executed / total_branches)			* 100), total_branches, source_file_name);	      fprintf (stdout,		    "%6.2lf%% of %d branches taken at least once in file %s\n",		       (((double) total_branches_taken / total_branches)			* 100), total_branches, source_file_name);	    }	  else	    fprintf (stdout, "No branches in file %s\n", source_file_name);	  if (total_calls)	    fprintf (stdout, "%6.2lf%% of %d calls executed in file %s\n",		     (((double) total_calls_executed / total_calls)		      * 100), total_calls, source_file_name);	  else	    fprintf (stdout, "No calls in file %s\n", source_file_name);	}      if (output_gcov_file)	{	  /* Now the statistics are ready.  Read in the source file one line	     at a time, and output that line to the gcov file preceded by	     its execution count if non zero.  */      	  source_file = fopen (source_file_name, "r");	  if (source_file == NULL)	    {	      fprintf (stderr, "Could not open source file %s.\n",		       source_file_name);	      free (line_counts);	      free (line_exists);	      continue;	    }	  count = strlen (source_file_name);	  cptr = rindex (s_ptr->name, '/');	  if (cptr)	    cptr = cptr + 1;	  else	    cptr = s_ptr->name;	  if (output_long_names && strcmp (cptr, input_file_name))	    {	      gcov_file_name = xmalloc (count + 7 + strlen (input_file_name));	      	      cptr = rindex (input_file_name, '/');	      if (cptr)		strcpy (gcov_file_name, cptr + 1);	      else		strcpy (gcov_file_name, input_file_name);	      strcat (gcov_file_name, ".");	      cptr = rindex (source_file_name, '/');	      if (cptr)		strcat (gcov_file_name, cptr + 1);	      else		strcat (gcov_file_name, source_file_name);	    }	  else	    {	      gcov_file_name = xmalloc (count + 6);	      cptr = rindex (source_file_name, '/');	      if (cptr)		strcpy (gcov_file_name, cptr + 1);	      else		strcpy (gcov_file_name, source_file_name);	    }	  /* Don't strip off the ending for compatibility with tcov, since	     this results in confusion if there is more than one file with	     the same basename, e.g. tmp.c and tmp.h.  */	  strcat (gcov_file_name, ".gcov");	  gcov_file = fopen (gcov_file_name, "w");	  if (gcov_file == NULL)	    {	      fprintf (stderr, "Could not open output file %s.\n",		       gcov_file_name);	      fclose (source_file);	      free (line_counts);	      free (line_exists);	      continue;	    }	  fprintf (stdout, "Creating %s.\n", gcov_file_name);	  for (count = 1; count < s_ptr->maxlineno; count++)	    {	      char *retval;	      int len;	      retval = fgets (string, STRING_SIZE, source_file);	      /* For lines which don't exist in the .bb file, print nothing		 before the source line.  For lines which exist but were never		 executed, print ###### 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.  */	      if (line_exists[count])		{		  if (line_counts[count])		    fprintf (gcov_file, "%12d    %s", line_counts[count],			     string);		  else		    fprintf (gcov_file, "      ######    %s", string);		}	      else		fprintf (gcov_file, "\t\t%s", string);	      /* In case the source file line is larger than our buffer, keep		 reading and outputting lines until we get a newline.  */	      len = strlen (string);	      while ((len == 0 || string[strlen (string) - 1] != '\n')		     && retval != NULL)		{		  retval = fgets (string, STRING_SIZE, source_file);		  fputs (string, gcov_file);		}	      if (output_branch_probs)		{		  for (i = 0, a_ptr = branch_probs[count]; a_ptr;		       a_ptr = a_ptr->next, i++)		    {		      if (a_ptr->call_insn)			{			  if (a_ptr->prob == -1)			    fprintf (gcov_file, "call %d never executed\n", i);			  else			    fprintf (gcov_file,				     "call %d returns = %d%%\n",				     i, 100 - a_ptr->prob);			}		      else			{			  if (a_ptr->prob == -1)			    fprintf (gcov_file, "branch %d never executed\n",				     i);			  else			    fprintf (gcov_file, "branch %d taken = %d%%\n", i,				     a_ptr->prob);			}		    }		}	      /* Gracefully handle errors while reading the source file.  */	      if (retval == NULL)		{		  fprintf (stderr,			   "Unexpected EOF while reading source file %s.\n",			   source_file_name);		  break;		}	    }	  /* Handle all remaining source lines.  There may be lines	     after the last line of code.  */	  {	    char *retval = fgets (string, STRING_SIZE, source_file);	    while (retval != NULL)	      {		int len;		fprintf (gcov_file, "\t\t%s", string);		/* In case the source file line is larger than our buffer, keep		   reading and outputting lines until we get a newline.  */		len = strlen (string);		while ((len == 0 || string[strlen (string) - 1] != '\n')		       && retval != NULL)		  {		    retval = fgets (string, STRING_SIZE, source_file);		    fputs (string, gcov_file);		  }		retval = fgets (string, STRING_SIZE, source_file);	      }	  }	  fclose (source_file);	  fclose (gcov_file);	}      free (line_counts);      free (line_exists);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -