On behalf of Aaron Conole <aconole@redhat.com>
authorAaron Conole <aconole@redhat.com>
Thu, 2 Jun 2016 12:22:01 +0000 (12:22 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 2 Jun 2016 12:22:01 +0000 (12:22 +0000)
On behalf of  Aaron Conole  <aconole@redhat.com>
* libgcov-driver-system.c (__gcov_error_file): New.
(get_gcov_error_file): New.
(gcov_error): Use and set __gcov_error_file.
(gcov_error_exit): New.
* libgcov-driver.c (gcov_exit): Call gcov_error_exit.

From-SVN: r237033

libgcc/ChangeLog
libgcc/libgcov-driver-system.c
libgcc/libgcov-driver.c

index d99eb63a05d1ea4543651adcca343f75bd958608..a003c5171fbf28f1222c32df210bcf2d09ec891c 100644 (file)
@@ -1,3 +1,11 @@
+2016-06-02  Aaron Conole  <aconole@redhat.com>
+
+       * libgcov-driver-system.c (__gcov_error_file): New.
+       (get_gcov_error_file): New.
+       (gcov_error): Use and set __gcov_error_file.
+       (gcov_error_exit): New.
+       * libgcov-driver.c (gcov_exit): Call gcov_error_exit.
+
 2016-05-26  Nathan Sidwell  <nathan@acm.org>
 
        * config/nvptx/free.asm: Delete.
index 4e3b244c7c13775a8ac944df3685471b259f9154..ff8a521690b150e1177c9e647bd615d4ccd715e4 100644 (file)
@@ -23,19 +23,64 @@ a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
-/* A utility function for outputing errors.  */
+/* Configured via the GCOV_ERROR_FILE environment variable;
+   it will either be stderr, or a file of the user's choosing.
+   Non-static to prevent multiple gcov-aware shared objects from
+   instantiating their own copies. */
+FILE *__gcov_error_file = NULL;
+
+/* A utility function to populate the __gcov_error_file pointer.
+   This should NOT be called outside of the gcov system driver code. */
+
+static FILE *
+get_gcov_error_file(void)
+{
+#if !IN_GCOV_TOOL
+  return stderr;
+#else
+  char *gcov_error_filename = getenv ("GCOV_ERROR_FILE");
+
+  if (gcov_error_filename)
+    {
+      FILE *openfile = fopen (gcov_error_filename, "a");
+      if (openfile)
+        __gcov_error_file = openfile;
+    }
+  if (!__gcov_error_file)
+    __gcov_error_file = stderr;
+  return __gcov_error_file;
+#endif
+}
+
+/* A utility function for outputting errors.  */
 
 static int __attribute__((format(printf, 1, 2)))
 gcov_error (const char *fmt, ...)
 {
   int ret;
   va_list argp;
+
+  if (!__gcov_error_file)
+    __gcov_error_file = get_gcov_error_file ();
+
   va_start (argp, fmt);
-  ret = vfprintf (stderr, fmt, argp);
+  ret = vfprintf (__gcov_error_file, fmt, argp);
   va_end (argp);
   return ret;
 }
 
+#if !IN_GCOV_TOOL
+static void
+gcov_error_exit (void)
+{
+  if (__gcov_error_file && __gcov_error_file != stderr)
+    {
+      fclose (__gcov_error_file);
+      __gcov_error_file = NULL;
+    }
+}
+#endif
+
 /* Make sure path component of the given FILENAME exists, create
    missing directories. FILENAME must be writable.
    Returns zero on success, or -1 if an error occurred.  */
index 9c4eeca0163714c4275b355bfb23d6007f515da4..d51397e0f8a0d8d48063fbe4f4b14e0a252a6f7c 100644 (file)
@@ -43,9 +43,13 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
 
 #ifdef L_gcov
 
-/* A utility function for outputing errors.  */
+/* A utility function for outputting errors.  */
 static int gcov_error (const char *, ...);
 
+#if !IN_GCOV_TOOL
+static void gcov_error_exit (void);
+#endif
+
 #include "gcov-io.c"
 
 struct gcov_fn_buffer
@@ -878,6 +882,8 @@ gcov_exit (void)
     __gcov_root.prev->next = __gcov_root.next;
   else
     __gcov_master.root = __gcov_root.next;
+
+  gcov_error_exit ();
 }
 
 /* Add a new object file onto the bb chain.  Invoked automatically