comparison gcc/gcov-dump.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Dump a gcov file, for debugging use. 1 /* Dump a gcov file, for debugging use.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
3 Free Software Foundation, Inc.
4 Contributed by Nathan Sidwell <nathan@codesourcery.com> 3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
5 4
6 Gcov is free software; you can redistribute it and/or modify 5 Gcov is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option) 7 the Free Software Foundation; either version 3, or (at your option)
20 #include "config.h" 19 #include "config.h"
21 #include "system.h" 20 #include "system.h"
22 #include "coretypes.h" 21 #include "coretypes.h"
23 #include "tm.h" 22 #include "tm.h"
24 #include "version.h" 23 #include "version.h"
24 #include "intl.h"
25 #include "diagnostic.h"
25 #include <getopt.h> 26 #include <getopt.h>
26 #define IN_GCOV (-1) 27 #define IN_GCOV (-1)
27 #include "gcov-io.h" 28 #include "gcov-io.h"
28 #include "gcov-io.c" 29 #include "gcov-io.c"
29 30
30 static void dump_file (const char *); 31 static void dump_gcov_file (const char *);
31 static void print_prefix (const char *, unsigned, gcov_position_t); 32 static void print_prefix (const char *, unsigned, gcov_position_t);
32 static void print_usage (void); 33 static void print_usage (void);
33 static void print_version (void); 34 static void print_version (void);
34 static void tag_function (const char *, unsigned, unsigned); 35 static void tag_function (const char *, unsigned, unsigned, unsigned);
35 static void tag_blocks (const char *, unsigned, unsigned); 36 static void tag_blocks (const char *, unsigned, unsigned, unsigned);
36 static void tag_arcs (const char *, unsigned, unsigned); 37 static void tag_arcs (const char *, unsigned, unsigned, unsigned);
37 static void tag_lines (const char *, unsigned, unsigned); 38 static void tag_lines (const char *, unsigned, unsigned, unsigned);
38 static void tag_counters (const char *, unsigned, unsigned); 39 static void tag_counters (const char *, unsigned, unsigned, unsigned);
39 static void tag_summary (const char *, unsigned, unsigned); 40 static void tag_summary (const char *, unsigned, unsigned, unsigned);
41 static void dump_working_sets (const char *filename ATTRIBUTE_UNUSED,
42 const struct gcov_ctr_summary *summary,
43 unsigned depth);
40 extern int main (int, char **); 44 extern int main (int, char **);
41 45
42 typedef struct tag_format 46 typedef struct tag_format
43 { 47 {
44 unsigned tag; 48 unsigned tag;
45 char const *name; 49 char const *name;
46 void (*proc) (const char *, unsigned, unsigned); 50 void (*proc) (const char *, unsigned, unsigned, unsigned);
47 } tag_format_t; 51 } tag_format_t;
48 52
49 static int flag_dump_contents = 0; 53 static int flag_dump_contents = 0;
50 static int flag_dump_positions = 0; 54 static int flag_dump_positions = 0;
55 static int flag_dump_working_sets = 0;
51 56
52 static const struct option options[] = 57 static const struct option options[] =
53 { 58 {
54 { "help", no_argument, NULL, 'h' }, 59 { "help", no_argument, NULL, 'h' },
55 { "version", no_argument, NULL, 'v' }, 60 { "version", no_argument, NULL, 'v' },
56 { "long", no_argument, NULL, 'l' }, 61 { "long", no_argument, NULL, 'l' },
57 { "positions", no_argument, NULL, 'o' }, 62 { "positions", no_argument, NULL, 'o' },
63 { "working-sets", no_argument, NULL, 'w' },
58 { 0, 0, 0, 0 } 64 { 0, 0, 0, 0 }
59 }; 65 };
66
67 #define VALUE_PADDING_PREFIX " "
68 #define VALUE_PREFIX "%2d: "
60 69
61 static const tag_format_t tag_table[] = 70 static const tag_format_t tag_table[] =
62 { 71 {
63 {0, "NOP", NULL}, 72 {0, "NOP", NULL},
64 {0, "UNKNOWN", NULL}, 73 {0, "UNKNOWN", NULL},
74 83
75 int 84 int
76 main (int argc ATTRIBUTE_UNUSED, char **argv) 85 main (int argc ATTRIBUTE_UNUSED, char **argv)
77 { 86 {
78 int opt; 87 int opt;
88 const char *p;
89
90 p = argv[0] + strlen (argv[0]);
91 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
92 --p;
93 progname = p;
94
95 xmalloc_set_program_name (progname);
79 96
80 /* Unlock the stdio streams. */ 97 /* Unlock the stdio streams. */
81 unlock_std_streams (); 98 unlock_std_streams ();
82 99
83 while ((opt = getopt_long (argc, argv, "hlpv", options, NULL)) != -1) 100 gcc_init_libintl ();
101
102 diagnostic_initialize (global_dc, 0);
103
104 while ((opt = getopt_long (argc, argv, "hlpvw", options, NULL)) != -1)
84 { 105 {
85 switch (opt) 106 switch (opt)
86 { 107 {
87 case 'h': 108 case 'h':
88 print_usage (); 109 print_usage ();
94 flag_dump_contents = 1; 115 flag_dump_contents = 1;
95 break; 116 break;
96 case 'p': 117 case 'p':
97 flag_dump_positions = 1; 118 flag_dump_positions = 1;
98 break; 119 break;
120 case 'w':
121 flag_dump_working_sets = 1;
122 break;
99 default: 123 default:
100 fprintf (stderr, "unknown flag `%c'\n", opt); 124 fprintf (stderr, "unknown flag `%c'\n", opt);
101 } 125 }
102 } 126 }
103 127
104 while (argv[optind]) 128 while (argv[optind])
105 dump_file (argv[optind++]); 129 dump_gcov_file (argv[optind++]);
106 return 0; 130 return 0;
107 } 131 }
108 132
109 static void 133 static void
110 print_usage (void) 134 print_usage (void)
111 { 135 {
112 printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n"); 136 printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n");
113 printf ("Print coverage file contents\n"); 137 printf ("Print coverage file contents\n");
114 printf (" -h, --help Print this help\n"); 138 printf (" -h, --help Print this help\n");
115 printf (" -v, --version Print version number\n");
116 printf (" -l, --long Dump record contents too\n"); 139 printf (" -l, --long Dump record contents too\n");
117 printf (" -p, --positions Dump record positions\n"); 140 printf (" -p, --positions Dump record positions\n");
141 printf (" -v, --version Print version number\n");
142 printf (" -w, --working-sets Dump working set computed from summary\n");
143 printf ("\nFor bug reporting instructions, please see:\n%s.\n",
144 bug_report_url);
118 } 145 }
119 146
120 static void 147 static void
121 print_version (void) 148 print_version (void)
122 { 149 {
123 printf ("gcov-dump %s%s\n", pkgversion_string, version_string); 150 printf ("gcov-dump %s%s\n", pkgversion_string, version_string);
124 printf ("Copyright (C) 2011 Free Software Foundation, Inc.\n"); 151 printf ("Copyright (C) 2017 Free Software Foundation, Inc.\n");
125 printf ("This is free software; see the source for copying conditions.\n" 152 printf ("This is free software; see the source for copying conditions.\n"
126 "There is NO warranty; not even for MERCHANTABILITY or \n" 153 "There is NO warranty; not even for MERCHANTABILITY or \n"
127 "FITNESS FOR A PARTICULAR PURPOSE.\n\n"); 154 "FITNESS FOR A PARTICULAR PURPOSE.\n\n");
128 } 155 }
129 156
132 { 159 {
133 static const char prefix[] = " "; 160 static const char prefix[] = " ";
134 161
135 printf ("%s:", filename); 162 printf ("%s:", filename);
136 if (flag_dump_positions) 163 if (flag_dump_positions)
137 printf ("%lu:", (unsigned long) position); 164 printf ("%5lu:", (unsigned long) position);
138 printf ("%.*s", (int) depth, prefix); 165 printf ("%.*s", (int) 2 * depth, prefix);
139 } 166 }
140 167
141 static void 168 static void
142 dump_file (const char *filename) 169 dump_gcov_file (const char *filename)
143 { 170 {
144 unsigned tags[4]; 171 unsigned tags[4];
145 unsigned depth = 0; 172 unsigned depth = 0;
146 173
147 if (!gcov_open (filename, 1)) 174 if (!gcov_open (filename, 1))
232 } 259 }
233 260
234 print_prefix (filename, tag_depth, position); 261 print_prefix (filename, tag_depth, position);
235 printf ("%08x:%4u:%s", tag, length, format->name); 262 printf ("%08x:%4u:%s", tag, length, format->name);
236 if (format->proc) 263 if (format->proc)
237 (*format->proc) (filename, tag, length); 264 (*format->proc) (filename, tag, length, depth);
238 265
239 printf ("\n"); 266 printf ("\n");
240 if (flag_dump_contents && format->proc) 267 if (flag_dump_contents && format->proc)
241 { 268 {
242 unsigned long actual_length = gcov_position () - base; 269 unsigned long actual_length = gcov_position () - base;
260 gcov_close (); 287 gcov_close ();
261 } 288 }
262 289
263 static void 290 static void
264 tag_function (const char *filename ATTRIBUTE_UNUSED, 291 tag_function (const char *filename ATTRIBUTE_UNUSED,
265 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 292 unsigned tag ATTRIBUTE_UNUSED, unsigned length,
293 unsigned depth ATTRIBUTE_UNUSED)
266 { 294 {
267 unsigned long pos = gcov_position (); 295 unsigned long pos = gcov_position ();
268 296
269 printf (" ident=%u", gcov_read_unsigned ()); 297 if (!length)
270 printf (", checksum=0x%08x", gcov_read_unsigned ()); 298 printf (" placeholder");
271 299 else
272 if (gcov_position () - pos < length) 300 {
273 { 301 printf (" ident=%u", gcov_read_unsigned ());
274 const char *name; 302 printf (", lineno_checksum=0x%08x", gcov_read_unsigned ());
275 303 printf (", cfg_checksum=0x%08x", gcov_read_unsigned ());
276 name = gcov_read_string (); 304
277 printf (", `%s'", name ? name : "NULL"); 305 if (gcov_position () - pos < length)
278 name = gcov_read_string (); 306 {
279 printf (" %s", name ? name : "NULL"); 307 const char *name;
280 printf (":%u", gcov_read_unsigned ()); 308
309 name = gcov_read_string ();
310 printf (", `%s'", name ? name : "NULL");
311 name = gcov_read_string ();
312 printf (" %s", name ? name : "NULL");
313 printf (":%u", gcov_read_unsigned ());
314 }
281 } 315 }
282 } 316 }
283 317
284 static void 318 static void
285 tag_blocks (const char *filename ATTRIBUTE_UNUSED, 319 tag_blocks (const char *filename ATTRIBUTE_UNUSED,
286 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 320 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
287 { 321 unsigned depth ATTRIBUTE_UNUSED)
288 unsigned n_blocks = GCOV_TAG_BLOCKS_NUM (length); 322 {
289 323 printf (" %u blocks", gcov_read_unsigned ());
290 printf (" %u blocks", n_blocks);
291
292 if (flag_dump_contents)
293 {
294 unsigned ix;
295
296 for (ix = 0; ix != n_blocks; ix++)
297 {
298 if (!(ix & 7))
299 {
300 printf ("\n");
301 print_prefix (filename, 0, gcov_position ());
302 printf ("\t\t%u", ix);
303 }
304 printf (" %04x", gcov_read_unsigned ());
305 }
306 }
307 } 324 }
308 325
309 static void 326 static void
310 tag_arcs (const char *filename ATTRIBUTE_UNUSED, 327 tag_arcs (const char *filename ATTRIBUTE_UNUSED,
311 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 328 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
329 unsigned depth)
312 { 330 {
313 unsigned n_arcs = GCOV_TAG_ARCS_NUM (length); 331 unsigned n_arcs = GCOV_TAG_ARCS_NUM (length);
314 332
315 printf (" %u arcs", n_arcs); 333 printf (" %u arcs", n_arcs);
316 if (flag_dump_contents) 334 if (flag_dump_contents)
323 unsigned dst, flags; 341 unsigned dst, flags;
324 342
325 if (!(ix & 3)) 343 if (!(ix & 3))
326 { 344 {
327 printf ("\n"); 345 printf ("\n");
328 print_prefix (filename, 0, gcov_position ()); 346 print_prefix (filename, depth, gcov_position ());
329 printf ("\tblock %u:", blockno); 347 printf (VALUE_PADDING_PREFIX "block %u:", blockno);
330 } 348 }
331 dst = gcov_read_unsigned (); 349 dst = gcov_read_unsigned ();
332 flags = gcov_read_unsigned (); 350 flags = gcov_read_unsigned ();
333 printf (" %u:%04x", dst, flags); 351 printf (" %u:%04x", dst, flags);
352 if (flags)
353 {
354 char c = '(';
355
356 if (flags & GCOV_ARC_ON_TREE)
357 printf ("%ctree", c), c = ',';
358 if (flags & GCOV_ARC_FAKE)
359 printf ("%cfake", c), c = ',';
360 if (flags & GCOV_ARC_FALLTHROUGH)
361 printf ("%cfall", c), c = ',';
362 printf (")");
363 }
334 } 364 }
335 } 365 }
336 } 366 }
337 367
338 static void 368 static void
339 tag_lines (const char *filename ATTRIBUTE_UNUSED, 369 tag_lines (const char *filename ATTRIBUTE_UNUSED,
340 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 370 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
371 unsigned depth)
341 { 372 {
342 if (flag_dump_contents) 373 if (flag_dump_contents)
343 { 374 {
344 unsigned blockno = gcov_read_unsigned (); 375 unsigned blockno = gcov_read_unsigned ();
345 char const *sep = NULL; 376 char const *sep = NULL;
359 } 390 }
360 391
361 if (!sep) 392 if (!sep)
362 { 393 {
363 printf ("\n"); 394 printf ("\n");
364 print_prefix (filename, 0, position); 395 print_prefix (filename, depth, position);
365 printf ("\tblock %u:", blockno); 396 printf (VALUE_PADDING_PREFIX "block %u:", blockno);
366 sep = ""; 397 sep = "";
367 } 398 }
368 if (lineno) 399 if (lineno)
369 { 400 {
370 printf ("%s%u", sep, lineno); 401 printf ("%s%u", sep, lineno);
379 } 410 }
380 } 411 }
381 412
382 static void 413 static void
383 tag_counters (const char *filename ATTRIBUTE_UNUSED, 414 tag_counters (const char *filename ATTRIBUTE_UNUSED,
384 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 415 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
385 { 416 unsigned depth)
386 static const char *const counter_names[] = GCOV_COUNTER_NAMES; 417 {
418 #define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME,
419 static const char *const counter_names[] = {
420 #include "gcov-counter.def"
421 };
422 #undef DEF_GCOV_COUNTER
387 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length); 423 unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
388 424
389 printf (" %s %u counts", 425 printf (" %s %u counts",
390 counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts); 426 counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts);
391 if (flag_dump_contents) 427 if (flag_dump_contents)
397 gcov_type count; 433 gcov_type count;
398 434
399 if (!(ix & 7)) 435 if (!(ix & 7))
400 { 436 {
401 printf ("\n"); 437 printf ("\n");
402 print_prefix (filename, 0, gcov_position ()); 438 print_prefix (filename, depth, gcov_position ());
403 printf ("\t\t%u", ix); 439 printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix);
404 } 440 }
405 441
406 count = gcov_read_counter (); 442 count = gcov_read_counter ();
407 printf (" "); 443 printf ("%" PRId64 " ", count);
408 printf (HOST_WIDEST_INT_PRINT_DEC, count);
409 } 444 }
410 } 445 }
411 } 446 }
412 447
413 static void 448 static void
414 tag_summary (const char *filename ATTRIBUTE_UNUSED, 449 tag_summary (const char *filename ATTRIBUTE_UNUSED,
415 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED) 450 unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
451 unsigned depth)
416 { 452 {
417 struct gcov_summary summary; 453 struct gcov_summary summary;
418 unsigned ix; 454 unsigned ix, h_ix;
455 gcov_bucket_type *histo_bucket;
419 456
420 gcov_read_summary (&summary); 457 gcov_read_summary (&summary);
421 printf (" checksum=0x%08x", summary.checksum); 458 printf (" checksum=0x%08x", summary.checksum);
422 459
423 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++) 460 for (ix = 0; ix != GCOV_COUNTERS_SUMMABLE; ix++)
424 { 461 {
425 printf ("\n"); 462 printf ("\n");
426 print_prefix (filename, 0, 0); 463 print_prefix (filename, depth, 0);
427 printf ("\t\tcounts=%u, runs=%u", 464 printf (VALUE_PADDING_PREFIX "counts=%u, runs=%u",
428 summary.ctrs[ix].num, summary.ctrs[ix].runs); 465 summary.ctrs[ix].num, summary.ctrs[ix].runs);
429 466
430 printf (", sum_all=" HOST_WIDEST_INT_PRINT_DEC, 467 printf (", sum_all=%" PRId64,
431 (HOST_WIDEST_INT)summary.ctrs[ix].sum_all); 468 (int64_t)summary.ctrs[ix].sum_all);
432 printf (", run_max=" HOST_WIDEST_INT_PRINT_DEC, 469 printf (", run_max=%" PRId64,
433 (HOST_WIDEST_INT)summary.ctrs[ix].run_max); 470 (int64_t)summary.ctrs[ix].run_max);
434 printf (", sum_max=" HOST_WIDEST_INT_PRINT_DEC, 471 printf (", sum_max=%" PRId64,
435 (HOST_WIDEST_INT)summary.ctrs[ix].sum_max); 472 (int64_t)summary.ctrs[ix].sum_max);
436 } 473 if (ix != GCOV_COUNTER_ARCS)
437 } 474 continue;
475 printf ("\n");
476 print_prefix (filename, depth, 0);
477 printf (VALUE_PADDING_PREFIX "counter histogram:");
478 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
479 {
480 histo_bucket = &summary.ctrs[ix].histogram[h_ix];
481 if (!histo_bucket->num_counters)
482 continue;
483 printf ("\n");
484 print_prefix (filename, depth, 0);
485 printf (VALUE_PADDING_PREFIX VALUE_PREFIX "num counts=%u, "
486 "min counter=%" PRId64 ", cum_counter=%" PRId64,
487 h_ix, histo_bucket->num_counters,
488 (int64_t)histo_bucket->min_value,
489 (int64_t)histo_bucket->cum_value);
490 }
491 if (flag_dump_working_sets)
492 dump_working_sets (filename, &summary.ctrs[ix], depth);
493 }
494 }
495
496 static void
497 dump_working_sets (const char *filename ATTRIBUTE_UNUSED,
498 const struct gcov_ctr_summary *summary,
499 unsigned depth)
500 {
501 gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS];
502 unsigned ws_ix, pctinc, pct;
503 gcov_working_set_t *ws_info;
504
505 compute_working_sets (summary, gcov_working_sets);
506
507 printf ("\n");
508 print_prefix (filename, depth, 0);
509 printf (VALUE_PADDING_PREFIX "counter working sets:");
510 /* Multiply the percentage by 100 to avoid float. */
511 pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS;
512 for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS;
513 ws_ix++, pct += pctinc)
514 {
515 if (ws_ix == NUM_GCOV_WORKING_SETS - 1)
516 pct = 9990;
517 ws_info = &gcov_working_sets[ws_ix];
518 /* Print out the percentage using int arithmatic to avoid float. */
519 printf ("\n");
520 print_prefix (filename, depth + 1, 0);
521 printf (VALUE_PADDING_PREFIX "%u.%02u%%: num counts=%u, min counter="
522 "%" PRId64,
523 pct / 100, pct - (pct / 100 * 100),
524 ws_info->num_counters,
525 (int64_t)ws_info->min_counter);
526 }
527 }