diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2021-09-13 19:49:49 +0200 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2021-09-13 19:49:49 +0200 |
commit | b18a97e5dd0935e1c4a626c230f21457d0aad3d5 (patch) | |
tree | c1818f41af6fe780deafb6cd6a183f32085fe654 /gcc/gcov.c | |
parent | e76a53644c9d70e998c0d050e9a456af388c6b61 (diff) | |
download | gcc-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.c | 205 |
1 files changed, 123 insertions, 82 deletions
@@ -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 |