libgcov-driver.c (struct gcov_filename_aux): Rename ...
* libgcov-driver.c (struct gcov_filename_aux): Rename ... (struct gcov_filename): ... here. Include buffer and max length fields. (gcov_max_filename): Remove. (gi_filename): Remove. (gcov_exit_compute_summary): Compute max filename here. (gcov_exit_merge_gcda): Add filename parm, adjust. (gcov_exit_merge_summary): Likewise. (gcov_exit_dump_gcov): Adjust for struct gcov_filename changes. (gcov_exit): Likewise. (__gcov_init): Don't calculate max length here. * libgcov_util.c (max_filename_len): Remove. (read_gcda_file): Don't calculate max length here. (gcov_read_profile_dir): Don't propagate here. * libgcov-driver-system.c (alloc_filename_struct): Adjust for struct gcov_filename changes. (gcov_exit_open_gcda_file): Likewise. From-SVN: r213092
This commit is contained in:
parent
98fa5ef355
commit
6dc33097cc
@ -1,3 +1,23 @@
|
||||
2014-07-27 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* libgcov-driver.c (struct gcov_filename_aux): Rename ...
|
||||
(struct gcov_filename): ... here. Include buffer and max length
|
||||
fields.
|
||||
(gcov_max_filename): Remove.
|
||||
(gi_filename): Remove.
|
||||
(gcov_exit_compute_summary): Compute max filename here.
|
||||
(gcov_exit_merge_gcda): Add filename parm, adjust.
|
||||
(gcov_exit_merge_summary): Likewise.
|
||||
(gcov_exit_dump_gcov): Adjust for struct gcov_filename changes.
|
||||
(gcov_exit): Likewise.
|
||||
(__gcov_init): Don't calculate max length here.
|
||||
* libgcov_util.c (max_filename_len): Remove.
|
||||
(read_gcda_file): Don't calculate max length here.
|
||||
(gcov_read_profile_dir): Don't propagate here.
|
||||
* libgcov-driver-system.c (alloc_filename_struct): Adjust for
|
||||
struct gcov_filename changes.
|
||||
(gcov_exit_open_gcda_file): Likewise.
|
||||
|
||||
2014-07-25 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
* libgcov-driver.c (set_gcov_dump_complete,
|
||||
|
@ -83,118 +83,105 @@ create_file_directory (char *filename)
|
||||
}
|
||||
|
||||
static void
|
||||
allocate_filename_struct (struct gcov_filename_aux *gf)
|
||||
allocate_filename_struct (struct gcov_filename *gf)
|
||||
{
|
||||
const char *gcov_prefix;
|
||||
int gcov_prefix_strip = 0;
|
||||
size_t prefix_length;
|
||||
char *gi_filename_up;
|
||||
int strip = 0;
|
||||
|
||||
gcc_assert (gf);
|
||||
{
|
||||
/* Check if the level of dirs to strip off specified. */
|
||||
char *tmp = getenv("GCOV_PREFIX_STRIP");
|
||||
if (tmp)
|
||||
{
|
||||
gcov_prefix_strip = atoi (tmp);
|
||||
strip = atoi (tmp);
|
||||
/* Do not consider negative values. */
|
||||
if (gcov_prefix_strip < 0)
|
||||
gcov_prefix_strip = 0;
|
||||
if (strip < 0)
|
||||
strip = 0;
|
||||
}
|
||||
}
|
||||
gf->strip = strip;
|
||||
|
||||
/* Get file name relocation prefix. Non-absolute values are ignored. */
|
||||
gcov_prefix = getenv("GCOV_PREFIX");
|
||||
if (gcov_prefix)
|
||||
{
|
||||
prefix_length = strlen(gcov_prefix);
|
||||
|
||||
/* Remove an unnecessary trailing '/' */
|
||||
if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
|
||||
prefix_length--;
|
||||
}
|
||||
else
|
||||
prefix_length = 0;
|
||||
prefix_length = gcov_prefix ? strlen (gcov_prefix) : 0;
|
||||
|
||||
/* Remove an unnecessary trailing '/' */
|
||||
if (prefix_length && IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
|
||||
prefix_length--;
|
||||
|
||||
/* If no prefix was specified and a prefix stip, then we assume
|
||||
relative. */
|
||||
if (gcov_prefix_strip != 0 && prefix_length == 0)
|
||||
if (!prefix_length && gf->strip)
|
||||
{
|
||||
gcov_prefix = ".";
|
||||
prefix_length = 1;
|
||||
}
|
||||
/* Allocate and initialize the filename scratch space plus one. */
|
||||
gi_filename = (char *) xmalloc (prefix_length + gcov_max_filename + 2);
|
||||
if (prefix_length)
|
||||
memcpy (gi_filename, gcov_prefix, prefix_length);
|
||||
gi_filename_up = gi_filename + prefix_length;
|
||||
gf->prefix = prefix_length;
|
||||
|
||||
gf->gi_filename_up = gi_filename_up;
|
||||
gf->prefix_length = prefix_length;
|
||||
gf->gcov_prefix_strip = gcov_prefix_strip;
|
||||
/* Allocate and initialize the filename scratch space. */
|
||||
gf->filename = (char *) xmalloc (gf->max_length + prefix_length + 2);
|
||||
if (prefix_length)
|
||||
memcpy (gf->filename, gcov_prefix, prefix_length);
|
||||
}
|
||||
|
||||
/* Open a gcda file specified by GI_FILENAME.
|
||||
Return -1 on error. Return 0 on success. */
|
||||
|
||||
static int
|
||||
gcov_exit_open_gcda_file (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf)
|
||||
gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
|
||||
struct gcov_filename *gf)
|
||||
{
|
||||
int gcov_prefix_strip;
|
||||
size_t prefix_length;
|
||||
char *gi_filename_up;
|
||||
const char *fname, *s;
|
||||
const char *fname = gi_ptr->filename;
|
||||
char *dst = gf->filename + gf->prefix;
|
||||
|
||||
gcov_prefix_strip = gf->gcov_prefix_strip;
|
||||
gi_filename_up = gf->gi_filename_up;
|
||||
prefix_length = gf->prefix_length;
|
||||
fname = gi_ptr->filename;
|
||||
|
||||
/* Avoid to add multiple drive letters into combined path. */
|
||||
if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
|
||||
fname += 2;
|
||||
|
||||
/* Build relocated filename, stripping off leading
|
||||
directories from the initial filename if requested. */
|
||||
if (gcov_prefix_strip > 0)
|
||||
if (gf->strip > 0)
|
||||
{
|
||||
int level = 0;
|
||||
const char *probe = fname;
|
||||
int level;
|
||||
|
||||
s = fname;
|
||||
if (IS_DIR_SEPARATOR(*s))
|
||||
++s;
|
||||
/* Remove a leading separator, without counting it. */
|
||||
if (IS_DIR_SEPARATOR (*probe))
|
||||
probe++;
|
||||
|
||||
/* Skip selected directory levels. */
|
||||
for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
|
||||
if (IS_DIR_SEPARATOR(*s))
|
||||
/* Skip selected directory levels. If we fall off the end, we
|
||||
keep the final part. */
|
||||
for (level = gf->strip; *probe && level; probe++)
|
||||
if (IS_DIR_SEPARATOR (*probe))
|
||||
{
|
||||
fname = s;
|
||||
level++;
|
||||
fname = probe;
|
||||
level--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update complete filename with stripped original. */
|
||||
if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
|
||||
if (gf->prefix)
|
||||
{
|
||||
/* If prefix is given, add directory separator. */
|
||||
strcpy (gi_filename_up, "/");
|
||||
strcpy (gi_filename_up + 1, fname);
|
||||
}
|
||||
else
|
||||
strcpy (gi_filename_up, fname);
|
||||
/* Avoid to add multiple drive letters into combined path. */
|
||||
if (HAS_DRIVE_SPEC(fname))
|
||||
fname += 2;
|
||||
|
||||
if (!gcov_open (gi_filename))
|
||||
if (!IS_DIR_SEPARATOR (*fname))
|
||||
*dst++ = '/';
|
||||
}
|
||||
strcpy (dst, fname);
|
||||
|
||||
if (!gcov_open (gf->filename))
|
||||
{
|
||||
/* Open failed likely due to missed directory.
|
||||
Create directory and retry to open file. */
|
||||
if (create_file_directory (gi_filename))
|
||||
if (create_file_directory (gf->filename))
|
||||
{
|
||||
fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
|
||||
fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
|
||||
return -1;
|
||||
}
|
||||
if (!gcov_open (gi_filename))
|
||||
if (!gcov_open (gf->filename))
|
||||
{
|
||||
fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
|
||||
fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,17 @@ struct gcov_summary_buffer
|
||||
struct gcov_summary summary;
|
||||
};
|
||||
|
||||
/* A struct that bundles all the related information about the
|
||||
gcda filename. */
|
||||
|
||||
struct gcov_filename
|
||||
{
|
||||
char *filename; /* filename buffer */
|
||||
size_t max_length; /* maximum filename length */
|
||||
int strip; /* leading chars to strip from filename */
|
||||
size_t prefix; /* chars to prepend to filename */
|
||||
};
|
||||
|
||||
/* Chain of per-object gcov structures. */
|
||||
#ifndef IN_GCOV_TOOL
|
||||
/* We need to expose this static variable when compiling for gcov-tool. */
|
||||
@ -73,13 +84,6 @@ static
|
||||
#endif
|
||||
struct gcov_info *gcov_list;
|
||||
|
||||
/* Size of the longest file name. */
|
||||
/* We need to expose this static variable when compiling for gcov-tool. */
|
||||
#ifndef IN_GCOV_TOOL
|
||||
static
|
||||
#endif
|
||||
size_t gcov_max_filename = 0;
|
||||
|
||||
/* Flag when the profile has already been dumped via __gcov_dump(). */
|
||||
static int gcov_dump_complete;
|
||||
|
||||
@ -275,8 +279,6 @@ gcov_compute_histogram (struct gcov_summary *sum)
|
||||
}
|
||||
}
|
||||
|
||||
/* gcda filename. */
|
||||
static char *gi_filename;
|
||||
/* buffer for the fn_data from another program. */
|
||||
static struct gcov_fn_buffer *fn_buffer;
|
||||
/* buffer for summary from other programs to be written out. */
|
||||
@ -286,11 +288,13 @@ static struct gcov_summary_buffer *sum_buffer;
|
||||
functions executed once may mistakely become cold. */
|
||||
static int run_accounted = 0;
|
||||
|
||||
/* This funtions computes the program level summary and the histo-gram.
|
||||
It computes and returns CRC32 and stored summary in THIS_PRG. */
|
||||
/* This function computes the program level summary and the histo-gram.
|
||||
It computes and returns CRC32 and stored summary in THIS_PRG.
|
||||
Also determines the longest filename length of the info files. */
|
||||
|
||||
static gcov_unsigned_t
|
||||
gcov_exit_compute_summary (struct gcov_summary *this_prg)
|
||||
gcov_exit_compute_summary (struct gcov_summary *this_prg,
|
||||
size_t *max_length)
|
||||
{
|
||||
struct gcov_info *gi_ptr;
|
||||
const struct gcov_fn_info *gfi_ptr;
|
||||
@ -303,8 +307,13 @@ gcov_exit_compute_summary (struct gcov_summary *this_prg)
|
||||
|
||||
/* Find the totals for this execution. */
|
||||
memset (this_prg, 0, sizeof (*this_prg));
|
||||
*max_length = 0;
|
||||
for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
|
||||
{
|
||||
size_t len = strlen (gi_ptr->filename);
|
||||
if (len > *max_length)
|
||||
*max_length = len;
|
||||
|
||||
crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
|
||||
crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
|
||||
|
||||
@ -345,14 +354,6 @@ gcov_exit_compute_summary (struct gcov_summary *this_prg)
|
||||
return crc32;
|
||||
}
|
||||
|
||||
/* A struct that bundles all the related information about the
|
||||
gcda filename. */
|
||||
struct gcov_filename_aux{
|
||||
char *gi_filename_up;
|
||||
int gcov_prefix_strip;
|
||||
size_t prefix_length;
|
||||
};
|
||||
|
||||
/* Including system dependent components. */
|
||||
#include "libgcov-driver-system.c"
|
||||
|
||||
@ -361,7 +362,8 @@ struct gcov_filename_aux{
|
||||
Return -1 on error. In this case, caller will goto read_fatal. */
|
||||
|
||||
static int
|
||||
gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
|
||||
gcov_exit_merge_gcda (const char *filename,
|
||||
struct gcov_info *gi_ptr,
|
||||
struct gcov_summary *prg_p,
|
||||
struct gcov_summary *this_prg,
|
||||
gcov_position_t *summary_pos_p,
|
||||
@ -376,7 +378,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
|
||||
struct gcov_summary_buffer **sum_tail = &sum_buffer;
|
||||
|
||||
length = gcov_read_unsigned ();
|
||||
if (!gcov_version (gi_ptr, length, gi_filename))
|
||||
if (!gcov_version (gi_ptr, length, filename))
|
||||
return -1;
|
||||
|
||||
length = gcov_read_unsigned ();
|
||||
@ -451,8 +453,7 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
|
||||
it back out -- we'll be inserting data before
|
||||
this point, so cannot simply keep the data in the
|
||||
file. */
|
||||
fn_tail = buffer_fn_data (gi_filename,
|
||||
gi_ptr, fn_tail, f_ix);
|
||||
fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
|
||||
if (!fn_tail)
|
||||
goto read_mismatch;
|
||||
continue;
|
||||
@ -494,14 +495,14 @@ gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
|
||||
{
|
||||
read_mismatch:;
|
||||
gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
|
||||
gi_filename, f_ix >= 0 ? "function" : "summary",
|
||||
filename, f_ix >= 0 ? "function" : "summary",
|
||||
f_ix < 0 ? -1 - f_ix : f_ix);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
read_error:
|
||||
gcov_error ("profiling:%s:%s merging\n", gi_filename,
|
||||
gcov_error ("profiling:%s:%s merging\n", filename,
|
||||
error < 0 ? "Overflow": "Error");
|
||||
return -1;
|
||||
}
|
||||
@ -606,7 +607,8 @@ gcov_exit_write_gcda (const struct gcov_info *gi_ptr,
|
||||
Return -1 on error. Return 0 on success. */
|
||||
|
||||
static int
|
||||
gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *prg,
|
||||
gcov_exit_merge_summary (const char *filename,
|
||||
const struct gcov_info *gi_ptr, struct gcov_summary *prg,
|
||||
struct gcov_summary *this_prg, gcov_unsigned_t crc32,
|
||||
struct gcov_summary *all_prg __attribute__ ((unused)))
|
||||
{
|
||||
@ -644,7 +646,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
|
||||
else if (cs_prg->runs)
|
||||
{
|
||||
gcov_error ("profiling:%s:Merge mismatch for summary.\n",
|
||||
gi_filename);
|
||||
filename);
|
||||
return -1;
|
||||
}
|
||||
#if !GCOV_LOCKED
|
||||
@ -670,7 +672,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
|
||||
{
|
||||
gcov_error ("profiling:%s:Data file mismatch - some "
|
||||
"data files may have been concurrently "
|
||||
"updated without locking support\n", gi_filename);
|
||||
"updated without locking support\n", filename);
|
||||
all_prg->checksum = ~0u;
|
||||
}
|
||||
#endif
|
||||
@ -689,7 +691,7 @@ gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *pr
|
||||
summaries separate. */
|
||||
|
||||
static void
|
||||
gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
|
||||
gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
|
||||
gcov_unsigned_t crc32, struct gcov_summary *all_prg,
|
||||
struct gcov_summary *this_prg)
|
||||
{
|
||||
@ -712,11 +714,11 @@ gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
|
||||
/* Merge data from file. */
|
||||
if (tag != GCOV_DATA_MAGIC)
|
||||
{
|
||||
gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
|
||||
gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
|
||||
goto read_fatal;
|
||||
}
|
||||
error = gcov_exit_merge_gcda (gi_ptr, &prg, this_prg, &summary_pos, &eof_pos,
|
||||
crc32);
|
||||
error = gcov_exit_merge_gcda (gf->filename, gi_ptr, &prg, this_prg,
|
||||
&summary_pos, &eof_pos, crc32);
|
||||
if (error == -1)
|
||||
goto read_fatal;
|
||||
}
|
||||
@ -729,7 +731,8 @@ gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
|
||||
summary_pos = eof_pos;
|
||||
}
|
||||
|
||||
error = gcov_exit_merge_summary (gi_ptr, &prg, this_prg, crc32, all_prg);
|
||||
error = gcov_exit_merge_summary (gf->filename, gi_ptr, &prg, this_prg,
|
||||
crc32, all_prg);
|
||||
if (error == -1)
|
||||
goto read_fatal;
|
||||
|
||||
@ -744,7 +747,7 @@ read_fatal:;
|
||||
gcov_error (error < 0 ?
|
||||
"profiling:%s:Overflow writing\n" :
|
||||
"profiling:%s:Error writing\n",
|
||||
gi_filename);
|
||||
gf->filename);
|
||||
}
|
||||
|
||||
|
||||
@ -756,7 +759,7 @@ void
|
||||
gcov_exit (void)
|
||||
{
|
||||
struct gcov_info *gi_ptr;
|
||||
struct gcov_filename_aux gf;
|
||||
struct gcov_filename gf;
|
||||
gcov_unsigned_t crc32;
|
||||
struct gcov_summary all_prg;
|
||||
struct gcov_summary this_prg;
|
||||
@ -767,8 +770,8 @@ gcov_exit (void)
|
||||
return;
|
||||
|
||||
gcov_dump_complete = 1;
|
||||
|
||||
crc32 = gcov_exit_compute_summary (&this_prg);
|
||||
|
||||
crc32 = gcov_exit_compute_summary (&this_prg, &gf.max_length);
|
||||
|
||||
allocate_filename_struct (&gf);
|
||||
#if !GCOV_LOCKED
|
||||
@ -780,8 +783,7 @@ gcov_exit (void)
|
||||
gcov_exit_dump_gcov (gi_ptr, &gf, crc32, &all_prg, &this_prg);
|
||||
run_accounted = 1;
|
||||
|
||||
if (gi_filename)
|
||||
free (gi_filename);
|
||||
free (gf.filename);
|
||||
}
|
||||
|
||||
/* Reset all counters to zero. */
|
||||
@ -826,12 +828,6 @@ __gcov_init (struct gcov_info *info)
|
||||
return;
|
||||
if (gcov_version (info, info->version, 0))
|
||||
{
|
||||
size_t filename_length = strlen(info->filename);
|
||||
|
||||
/* Refresh the longest file name information */
|
||||
if (filename_length > gcov_max_filename)
|
||||
gcov_max_filename = filename_length;
|
||||
|
||||
if (!gcov_list)
|
||||
atexit (gcov_exit);
|
||||
|
||||
|
@ -38,7 +38,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
|
||||
extern gcov_position_t gcov_position();
|
||||
extern int gcov_is_error();
|
||||
extern size_t gcov_max_filename;
|
||||
|
||||
/* Verbose mode for debug. */
|
||||
static int verbose;
|
||||
@ -78,8 +77,6 @@ static int k_ctrs_mask[GCOV_COUNTERS];
|
||||
static struct gcov_ctr_info k_ctrs[GCOV_COUNTERS];
|
||||
/* Number of kind of counters that have been seen. */
|
||||
static int k_ctrs_types;
|
||||
/* The longest length of all the filenames. */
|
||||
static int max_filename_len;
|
||||
|
||||
/* Merge functions for counters. */
|
||||
#define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) __gcov_merge ## FN_TYPE,
|
||||
@ -301,13 +298,11 @@ read_gcda_file (const char *filename)
|
||||
num_fn_info = 0;
|
||||
curr_fn_info = 0;
|
||||
{
|
||||
char *str_dup = (char*) xmalloc (strlen (filename) + 1);
|
||||
int len;
|
||||
size_t len = strlen (filename) + 1;
|
||||
char *str_dup = (char*) xmalloc (len);
|
||||
|
||||
strcpy (str_dup, filename);
|
||||
memcpy (str_dup, filename, len);
|
||||
obj_info->filename = str_dup;
|
||||
if ((len = strlen (filename)) > max_filename_len)
|
||||
max_filename_len = len;
|
||||
}
|
||||
|
||||
/* Read stamp. */
|
||||
@ -433,8 +428,7 @@ read_profile_dir_init (void)
|
||||
|
||||
/* Driver for read a profile directory and convert into gcov_info list in memory.
|
||||
Return NULL on error,
|
||||
Return the head of gcov_info list on success.
|
||||
Note the file static variable GCOV_MAX_FILENAME is also set. */
|
||||
Return the head of gcov_info list on success. */
|
||||
|
||||
struct gcov_info *
|
||||
gcov_read_profile_dir (const char* dir_name, int recompute_summary ATTRIBUTE_UNUSED)
|
||||
@ -462,11 +456,6 @@ gcov_read_profile_dir (const char* dir_name, int recompute_summary ATTRIBUTE_UNU
|
||||
free (pwd);
|
||||
|
||||
|
||||
/* gcov_max_filename is defined in libgcov.c that records the
|
||||
max filename len. We need to set it here to allocate the
|
||||
array for dumping. */
|
||||
gcov_max_filename = max_filename_len;
|
||||
|
||||
return gcov_info_head;;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user