aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcov.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2021-09-13 19:49:49 +0200
committerThomas Koenig <tkoenig@gcc.gnu.org>2021-09-13 19:49:49 +0200
commitb18a97e5dd0935e1c4a626c230f21457d0aad3d5 (patch)
treec1818f41af6fe780deafb6cd6a183f32085fe654 /gcc/gcov.c
parente76a53644c9d70e998c0d050e9a456af388c6b61 (diff)
downloadgcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.zip
gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.gz
gcc-b18a97e5dd0935e1c4a626c230f21457d0aad3d5.tar.bz2
Merged current trunk to branch.
Diffstat (limited to 'gcc/gcov.c')
-rw-r--r--gcc/gcov.c205
1 files changed, 123 insertions, 82 deletions
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 8dcec94..cf0a49d 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -1,6 +1,6 @@
/* Gcov.c: prepend line execution counts and branch probabilities to a
source file.
- Copyright (C) 1990-2020 Free Software Foundation, Inc.
+ Copyright (C) 1990-2021 Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
Mangled further by Nathan Sidwell <nathan@codesourcery.com>
@@ -371,6 +371,9 @@ public:
/* Register a new function. */
void add_function (function_info *fn);
+ /* Debug the source file. */
+ void debug ();
+
/* Index of the source_info in sources vector. */
unsigned index;
@@ -428,6 +431,31 @@ source_info::get_functions_at_location (unsigned line_num) const
return slot;
}
+void source_info::debug ()
+{
+ fprintf (stderr, "source_info: %s\n", name);
+ for (vector<function_info *>::iterator it = functions.begin ();
+ it != functions.end (); it++)
+ {
+ function_info *fn = *it;
+ fprintf (stderr, " function_info: %s\n", fn->get_name ());
+ for (vector<block_info>::iterator bit = fn->blocks.begin ();
+ bit != fn->blocks.end (); bit++)
+ {
+ fprintf (stderr, " block_info id=%d, count=%" PRId64 " \n",
+ bit->id, bit->count);
+ }
+ }
+
+ for (unsigned lineno = 1; lineno < lines.size (); ++lineno)
+ {
+ line_info &line = lines[lineno];
+ fprintf (stderr, " line_info=%d, count=%" PRId64 "\n", lineno, line.count);
+ }
+
+ fprintf (stderr, "\n");
+}
+
class name_map
{
public:
@@ -579,6 +607,10 @@ static int flag_human_readable_numbers = 0;
static int flag_function_summary = 0;
+/* Print debugging dumps. */
+
+static int flag_debug = 0;
+
/* Object directory file prefix. This is the directory/file where the
graph and data files are looked for, if nonzero. */
@@ -630,8 +662,8 @@ static void accumulate_line_counts (source_info *);
static void output_gcov_file (const char *, source_info *);
static int output_branch_count (FILE *, int, const arc_info *);
static void output_lines (FILE *, const source_info *);
-static char *make_gcov_file_name (const char *, const char *);
-static char *mangle_name (const char *, char *);
+static string make_gcov_file_name (const char *, const char *);
+static char *mangle_name (const char *);
static void release_structures (void);
extern int main (int, char **);
@@ -896,6 +928,7 @@ print_usage (int error_p)
fnotice (file, " -c, --branch-counts Output counts of branches taken\n\
rather than percentages\n");
fnotice (file, " -d, --display-progress Display progress information\n");
+ fnotice (file, " -D, --debug Display debugging dumps\n");
fnotice (file, " -f, --function-summaries Output summaries for each function\n");
fnotice (file, " -h, --help Print this help, then exit\n");
fnotice (file, " -j, --json-format Output JSON intermediate format\n\
@@ -930,7 +963,7 @@ static void
print_version (void)
{
fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
- fprintf (stdout, "Copyright %s 2020 Free Software Foundation, Inc.\n",
+ fprintf (stdout, "Copyright %s 2021 Free Software Foundation, Inc.\n",
_("(C)"));
fnotice (stdout,
_("This is free software; see the source for copying conditions. There is NO\n\
@@ -963,6 +996,7 @@ static const struct option options[] =
{ "hash-filenames", no_argument, NULL, 'x' },
{ "use-colors", no_argument, NULL, 'k' },
{ "use-hotness-colors", no_argument, NULL, 'q' },
+ { "debug", no_argument, NULL, 'D' },
{ 0, 0, 0, 0 }
};
@@ -973,7 +1007,7 @@ process_args (int argc, char **argv)
{
int opt;
- const char *opts = "abcdfhHijklmno:pqrs:tuvwx";
+ const char *opts = "abcdDfhHijklmno:pqrs:tuvwx";
while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
{
switch (opt)
@@ -1044,6 +1078,9 @@ process_args (int argc, char **argv)
case 't':
flag_use_stdout = 1;
break;
+ case 'D':
+ flag_debug = 1;
+ break;
case 'v':
print_version ();
/* print_version will exit. */
@@ -1097,6 +1134,41 @@ output_intermediate_json_line (json::array *object,
object->append (lineo);
}
+/* Strip filename extension in STR. */
+
+static string
+strip_extention (string str)
+{
+ string::size_type pos = str.rfind ('.');
+ if (pos != string::npos)
+ str = str.substr (0, pos);
+
+ return str;
+}
+
+/* Calcualte md5sum for INPUT string and return it in hex string format. */
+
+static string
+get_md5sum (const char *input)
+{
+ md5_ctx ctx;
+ char md5sum[16];
+ string str;
+
+ md5_init_ctx (&ctx);
+ md5_process_bytes (input, strlen (input), &ctx);
+ md5_finish_ctx (&ctx, md5sum);
+
+ for (unsigned i = 0; i < 16; i++)
+ {
+ char b[3];
+ sprintf (b, "%02x", (unsigned char)md5sum[i]);
+ str += b;
+ }
+
+ return str;
+}
+
/* 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.
@@ -1106,20 +1178,26 @@ output_intermediate_json_line (json::array *object,
input: foo.da, output: foo.da.gcov
input: a/b/foo.cc, output: foo.cc.gcov */
-static char *
-get_gcov_intermediate_filename (const char *file_name)
+static string
+get_gcov_intermediate_filename (const char *input_file_name)
{
- const char *gcov = ".gcov.json.gz";
- char *result;
- const char *cptr;
+ string base = basename (input_file_name);
+ string str = strip_extention (base);
- /* Find the 'basename'. */
- cptr = lbasename (file_name);
-
- result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1);
- sprintf (result, "%s%s", cptr, gcov);
+ if (flag_hash_filenames)
+ {
+ str += "##";
+ str += get_md5sum (input_file_name);
+ }
+ else if (flag_preserve_paths && base != input_file_name)
+ {
+ str += "##";
+ str += mangle_path (input_file_name);
+ str = strip_extention (str);
+ }
- return result;
+ str += ".gcov.json.gz";
+ return str.c_str ();
}
/* Output the result in JSON intermediate format.
@@ -1379,7 +1457,9 @@ process_all_functions (void)
static void
output_gcov_file (const char *file_name, source_info *src)
{
- char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);
+ string gcov_file_name_str
+ = make_gcov_file_name (file_name, src->coverage.name);
+ const char *gcov_file_name = gcov_file_name_str.c_str ();
if (src->coverage.lines)
{
@@ -1401,13 +1481,12 @@ output_gcov_file (const char *file_name, source_info *src)
unlink (gcov_file_name);
fnotice (stdout, "Removing '%s'\n", gcov_file_name);
}
- free (gcov_file_name);
}
static void
generate_results (const char *file_name)
{
- char *gcov_intermediate_filename;
+ string gcov_intermediate_filename;
for (vector<function_info *>::iterator it = functions.begin ();
it != functions.end (); it++)
@@ -1466,6 +1545,8 @@ generate_results (const char *file_name)
}
accumulate_line_counts (src);
+ if (flag_debug)
+ src->debug ();
if (!flag_use_stdout)
file_summary (&src->coverage);
@@ -1508,11 +1589,13 @@ generate_results (const char *file_name)
root->print (&pp);
pp_formatted_text (&pp);
- gzFile output = gzopen (gcov_intermediate_filename, "w");
+ fnotice (stdout, "Creating '%s'\n",
+ gcov_intermediate_filename.c_str ());
+ gzFile output = gzopen (gcov_intermediate_filename.c_str (), "w");
if (output == NULL)
{
fnotice (stderr, "Cannot open JSON output file %s\n",
- gcov_intermediate_filename);
+ gcov_intermediate_filename.c_str ());
return;
}
@@ -1520,7 +1603,7 @@ generate_results (const char *file_name)
|| gzclose (output))
{
fnotice (stderr, "Error writing JSON output file %s\n",
- gcov_intermediate_filename);
+ gcov_intermediate_filename.c_str ());
return;
}
}
@@ -1804,6 +1887,8 @@ read_graph_file (void)
arc = XCNEW (arc_info);
arc->dst = &fn->blocks[dest];
+ /* Set id in order to find EXIT_BLOCK. */
+ arc->dst->id = dest;
arc->src = src_blk;
arc->count = 0;
@@ -2505,15 +2590,6 @@ canonicalize_name (const char *name)
return result;
}
-/* Print hex representation of 16 bytes from SUM and write it to BUFFER. */
-
-static void
-md5sum_to_hex (const char *sum, char *buffer)
-{
- for (unsigned i = 0; i < 16; i++)
- sprintf (buffer + (2 * i), "%02x", (unsigned char)sum[i]);
-}
-
/* 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
@@ -2526,77 +2602,42 @@ md5sum_to_hex (const char *sum, char *buffer)
component. (Remember, the canonicalized name will already have
elided '.' components and converted \\ separators.) */
-static char *
+static string
make_gcov_file_name (const char *input_name, const char *src_name)
{
- char *ptr;
- char *result;
-
- if (flag_long_names && input_name && strcmp (src_name, input_name))
- {
- /* Generate the input filename part. */
- result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
-
- ptr = result;
- ptr = mangle_name (input_name, ptr);
- ptr[0] = ptr[1] = '#';
- ptr += 2;
- }
- else
- {
- result = XNEWVEC (char, strlen (src_name) + 10);
- ptr = result;
- }
-
- ptr = mangle_name (src_name, ptr);
- strcpy (ptr, ".gcov");
+ string str;
/* When hashing filenames, we shorten them by only using the filename
component and appending a hash of the full (mangled) pathname. */
if (flag_hash_filenames)
+ str = (string (mangle_name (src_name)) + "##"
+ + get_md5sum (src_name) + ".gcov");
+ else
{
- md5_ctx ctx;
- char md5sum[16];
- char md5sum_hex[33];
-
- md5_init_ctx (&ctx);
- md5_process_bytes (src_name, strlen (src_name), &ctx);
- md5_finish_ctx (&ctx, md5sum);
- md5sum_to_hex (md5sum, md5sum_hex);
- free (result);
+ if (flag_long_names && input_name && strcmp (src_name, input_name) != 0)
+ {
+ str += mangle_name (input_name);
+ str += "##";
+ }
- result = XNEWVEC (char, strlen (src_name) + 50);
- ptr = result;
- ptr = mangle_name (src_name, ptr);
- ptr[0] = ptr[1] = '#';
- ptr += 2;
- memcpy (ptr, md5sum_hex, 32);
- ptr += 32;
- strcpy (ptr, ".gcov");
+ str += mangle_name (src_name);
+ str += ".gcov";
}
- return result;
+ return str;
}
/* Mangle BASE name, copy it at the beginning of PTR buffer and
return address of the \0 character of the buffer. */
static char *
-mangle_name (char const *base, char *ptr)
+mangle_name (char const *base)
{
- size_t len;
-
/* Generate the source filename part. */
if (!flag_preserve_paths)
- base = lbasename (base);
+ return xstrdup (lbasename (base));
else
- base = mangle_path (base);
-
- len = strlen (base);
- memcpy (ptr, base, len);
- ptr += len;
-
- return ptr;
+ return mangle_path (base);
}
/* Scan through the bb_data for each line in the block, increment