Patchwork [google] Fix parallel make issue exposed by recent gcda change (issue7426043)

login
register
mail settings
Submitter Teresa Johnson
Date Feb. 28, 2013, 12:51 a.m.
Message ID <20130228005151.D0C0880D3B@tjsboxrox.mtv.corp.google.com>
Download mbox | patch
Permalink /patch/223760/
State New
Headers show

Comments

Teresa Johnson - Feb. 28, 2013, 12:51 a.m.
Fix race with writing module infos in a parallel make exposed
by change that added primary module info to all gcda files. Instead
of saving eof_pos from the initial write, seek to the zero byte
written at the end of the file when reopening and writing the module
infos.

Tested with regression tests and internal test. Ok for google branches?

2013-02-27  Teresa Johnson  <tejohnson@google.com>

	* libgcc/libgcov.c (gcov_dump_module_info): Seek to zero
        word using new end of file relative seek.
	(gcov_merge_gcda_file): Make eof_pos local.
	(gcov_write_gcda_file): Pass new argument to gcov_seek,
        remove old eof_pos handling.
	* gcc/coverage.c (build_info_type): Remove eof_pos from gcov_info.
	(build_info): Ditto.
	* gcc/gcov-io.c (gcov_seek): Add new parameter from_end.
	* gcc/gcov-io.h (struct gcov_info): Remove eof_pos from gcov_info.


--
This patch is available for review at http://codereview.appspot.com/7426043

Patch

Index: libgcc/libgcov.c
===================================================================
--- libgcc/libgcov.c	(revision 196314)
+++ libgcc/libgcov.c	(working copy)
@@ -226,9 +226,6 @@  static struct gcov_summary program;
 /* Record the position of summary info.  */
 static gcov_position_t summary_pos = 0;
 
-/* Record the postion of eof.  */
-static gcov_position_t eof_pos = 0;
-
 /* Number of chars in prefix to be stripped.  */
 static int gcov_prefix_strip = 0;
 
@@ -580,7 +577,7 @@  gcov_dump_module_info (int do_lipo)
 
     /* Overwrite the zero word at the of the file.  */
     gcov_rewrite ();
-    gcov_seek (gi_ptr->eof_pos);
+    gcov_seek (1, 1);
 
     gcov_write_module_infos (gi_ptr, do_lipo);
     /* Write the end marker  */
@@ -947,8 +944,8 @@  gcov_merge_gcda_file (struct gcov_info *gi_ptr)
   const struct gcov_fn_info *gfi_ptr;
   int error = 0;
   gcov_unsigned_t tag, length, version, stamp;
+  gcov_position_t eof_pos = 0;
 
-  eof_pos = 0;
   summary_pos = 0;
   sum_buffer = 0;
   sum_tail = &sum_buffer;
@@ -1202,15 +1199,14 @@  gcov_write_gcda_file (struct gcov_info *gi_ptr)
   const struct gcov_ctr_info *ci_ptr;
   unsigned t_ix, f_ix, n_counts, length;
   int error = 0;
-  gcov_position_t eof_pos1 = 0;
 
   /* Write out the data.  */
-  gcov_seek (0);
+  gcov_seek (0, 0);
   gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
   gcov_write_unsigned (gi_ptr->stamp);
 
    if (summary_pos)
-     gcov_seek (summary_pos);
+     gcov_seek (summary_pos, 0);
   gcc_assert (!summary_pos || summary_pos == gcov_position ());
 
   /* Generate whole program statistics.  */
@@ -1259,14 +1255,10 @@  gcov_write_gcda_file (struct gcov_info *gi_ptr)
             gcov_write_counter (*c_ptr++);
           ci_ptr++;
         }
-      eof_pos1 = gcov_position ();
     }
-    eof_pos = eof_pos1;
     /* Write the end marker  */
     gcov_write_unsigned (0);
 
-    gi_ptr->eof_pos = eof_pos;
-
     if ((error = gcov_close ()))
       gcov_error (error  < 0 ?
                   "profiling:%s:Overflow writing\n" :
Index: gcc/coverage.c
===================================================================
--- gcc/coverage.c	(revision 196314)
+++ gcc/coverage.c	(working copy)
@@ -1961,12 +1961,6 @@  build_info_type (tree type, tree fn_info_ptr_type)
   DECL_CHAIN (field) = fields;
   fields = field;
 
-  /* eof_pos */
-  field = build_decl (BUILTINS_LOCATION, FIELD_DECL,
-                      NULL_TREE, get_gcov_unsigned_t ());
-  DECL_CHAIN (field) = fields;
-  fields = field;
-
   /* merge fn array */
   merge_fn_type
     = build_function_type_list (void_type_node,
@@ -2412,11 +2406,6 @@  build_info (tree info_type, tree fn_ary)
 				  filename_string));
   info_fields = DECL_CHAIN (info_fields);
 
-  /* eof_pos */
-  CONSTRUCTOR_APPEND_ELT (v1, info_fields,
-                          build_int_cstu (TREE_TYPE (info_fields), 0));
-  info_fields = DECL_CHAIN (info_fields);
-
   /* merge fn array -- NULL slots indicate unmeasured counters */
   merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
   for (ix = 0; ix != GCOV_COUNTERS; ix++)
Index: gcc/gcov-io.c
===================================================================
--- gcc/gcov-io.c	(revision 196314)
+++ gcc/gcov-io.c	(working copy)
@@ -812,15 +812,19 @@  gcov_sync (gcov_position_t base, gcov_unsigned_t l
 #endif
 
 #if IN_LIBGCOV
-/* Move to a given position in a gcov file.  */
+/* Move to a given position in a gcov file. If FROM_END is true,
+   then seek to the given BASE relative to the end of the file.  */
 
 GCOV_LINKAGE void
-gcov_seek (gcov_position_t base)
+gcov_seek (gcov_position_t base, int from_end)
 {
+  int offset = base << 2;
   gcc_assert (gcov_var.mode < 0);
   if (gcov_var.offset)
     gcov_write_block (gcov_var.offset);
-  _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET);
+  _GCOV_fseek (gcov_var.file,
+               from_end ? -offset : offset,
+               from_end ? SEEK_END : SEEK_SET);
   gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2;
 }
 
Index: gcc/gcov-io.h
===================================================================
--- gcc/gcov-io.h	(revision 196314)
+++ gcc/gcov-io.h	(working copy)
@@ -802,7 +802,6 @@  struct gcov_info
 
   gcov_unsigned_t stamp;	/* uniquifying time stamp */
   const char *filename;		/* output file name */
-  gcov_unsigned_t eof_pos;      /* end position of profile data */
   gcov_merge_fn merge[GCOV_COUNTERS];  /* merge functions (null for
 					  unused) */
   
@@ -1011,7 +1010,8 @@  GCOV_LINKAGE const struct dyn_imp_mod **
 gcov_get_sorted_import_module_array (struct gcov_info *mod_info, unsigned *len)
     ATTRIBUTE_HIDDEN;
 static void gcov_rewrite (void);
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
+GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/, int /* from_end */)
+    ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_string_length (const char *) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE unsigned gcov_gcda_file_size (struct gcov_info *);