* gcov-io.h: Add a local time stamp.
(struct gcov_info): Add stamp field.
(gcov_truncate): New.
* coverage.c (read_counts_file): Skip the stamp.
(coverage_begin_output): Write the stamp.
(build_gcov_info): Declare and init the stamp.
(coverage_finish): Only unlink data file, if stamp is zero.
* gcov-dump.c (dump_file): Dump the stamp.
* gcov.c (bbg_stamp): New.
(release_structures): Clear bbg_stamp.
(read_graph_file): Read stamp.
(read_count_file): Check stamp.
* libgcov.c (gcov_exit): Check stamp and truncate if needed.
From-SVN: r69006
2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+ * gcov-io.h: Add a local time stamp.
+ (struct gcov_info): Add stamp field.
+ (gcov_truncate): New.
+ * coverage.c (read_counts_file): Skip the stamp.
+ (coverage_begin_output): Write the stamp.
+ (build_gcov_info): Declare and init the stamp.
+ (coverage_finish): Only unlink data file, if stamp is zero.
+ * gcov-dump.c (dump_file): Dump the stamp.
+ * gcov.c (bbg_stamp): New.
+ (release_structures): Clear bbg_stamp.
+ (read_graph_file): Read stamp.
+ (read_count_file): Check stamp.
+ * libgcov.c (gcov_exit): Check stamp and truncate if needed.
+
+2003-07-06 Nathan Sidwell <nathan@codesourcery.com>
+
* tree.h (default_flag_random_seed): Remove.
* toplev.h (local_tick): Declare.
* tree.c (flag_random_seed, default_flag_random_seed): Move to
return;
}
+ /* Read and discard the stamp. */
+ gcov_read_unsigned ();
+
counts_hash = htab_create (10,
htab_counts_entry_hash, htab_counts_entry_eq,
htab_counts_entry_del);
{
gcov_write_unsigned (GCOV_GRAPH_MAGIC);
gcov_write_unsigned (GCOV_VERSION);
+ gcov_write_unsigned (local_tick);
}
bbg_file_opened = 1;
}
fields = field;
value = tree_cons (field, null_pointer_node, value);
+ /* stamp */
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
+ TREE_CHAIN (field) = fields;
+ fields = field;
+ value = tree_cons (field, convert (unsigned_intSI_type_node,
+ build_int_2 (local_tick, 0)),
+ value);
+
/* Filename */
string_type = build_pointer_type (build_qualified_type (char_type_node,
TYPE_QUAL_CONST));
if (error)
unlink (bbg_file_name);
-#if SELF_COVERAGE
- /* If the compiler is instrumented, we should not
- unconditionally remove the counts file, because we might be
- recompiling ourselves. The .da files are all removed during
- copying the stage1 files. */
- if (error)
-#endif
+ if (!local_tick)
+ /* Only remove the da file, if we cannot stamp it. If we can
+ stamp it, libgcov will DTRT. */
unlink (da_file_name);
}
}
printf ("%s:warning:current version is `%.4s'\n", filename, e);
}
+ /* stamp */
+ {
+ unsigned stamp = gcov_read_unsigned ();
+
+ printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
+ }
+
while (1)
{
gcov_position_t base, position = gcov_position ();
The basic format of the files is
- file : int32:magic int32:version record*
+ file : int32:magic int32:version int32:stamp record*
The magic ident is different for the bbg and the counter files.
The version is the same for both files and is derived from gcc's
- version number. Although the ident and version are formally 32 bit
+ version number. The stamp value is used to synchronize bbg and
+ counter files and to synchronize merging within a counter file. It
+ need not be an absolute time stamp, merely a ticker that increments
+ fast enough and cycles slow enough to distinguish different
+ compile/run/compile cycles.
+
+ Although the ident and version are formally 32 bit
numbers, they are derived from 4 character ASCII strings. The
version number consists of the single character major version
number, a two character minor version number (leading zero for
gcov_unsigned_t version; /* expected version number */
struct gcov_info *next; /* link to next, used by libgcc */
+ gcov_unsigned_t stamp; /* uniquifying time stamp */
const char *filename; /* output file name */
-
+
unsigned n_functions; /* number of functions */
const struct gcov_fn_info *functions; /* table of functions */
GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
const struct gcov_summary *);
+static void gcov_truncate (void);
static void gcov_rewrite (void);
GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
#else
gcov_var.offset = 0;
fseek (gcov_var.file, 0L, SEEK_SET);
}
+
+static inline void
+gcov_truncate (void)
+{
+ ftruncate (fileno (gcov_var.file), 0L);
+}
#endif
#endif /* IN_LIBGCOV >= 0 */
static char *bbg_file_name;
+/* Stamp of the bbg file */
+static unsigned bbg_stamp;
+
/* Name and file pointer of the input file for the arc count data. */
static char *da_file_name;
free (da_file_name);
da_file_name = bbg_file_name = NULL;
bbg_file_time = 0;
+ bbg_stamp = 0;
while ((src = sources))
{
fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
bbg_file_name, v, e);
}
-
+ bbg_stamp = gcov_read_unsigned ();
+
while ((tag = gcov_read_unsigned ()))
{
unsigned length = gcov_read_unsigned ();
fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
da_file_name, v, e);
}
+ tag = gcov_read_unsigned ();
+ if (tag != bbg_stamp)
+ {
+ fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
+ goto cleanup;
+ }
while ((tag = gcov_read_unsigned ()))
{
gcov_unsigned_t tag, length;
gcov_position_t summary_pos = 0;
- /* Totals for this object file. */
memset (&this_object, 0, sizeof (this_object));
+ memset (&object, 0, sizeof (object));
+
+ /* Totals for this object file. */
for (t_ix = c_ix = 0,
ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs;
t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++)
gcov_version_mismatch (gi_ptr, length);
goto read_fatal;
}
+
+ length = gcov_read_unsigned ();
+ if (length != gi_ptr->stamp)
+ {
+ /* Read from a different compilation. Overwrite the
+ file. */
+ gcov_truncate ();
+ goto rewrite;
+ }
/* Merge execution counts for each function. */
for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions;
rewrite:;
gcov_rewrite ();
}
- else
- memset (&object, 0, sizeof (object));
if (!summary_pos)
memset (&program, 0, sizeof (program));
/* Write out the data. */
gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
+ gcov_write_unsigned (gi_ptr->stamp);
/* Write execution counts for each function. */
for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; f_ix--;