diff mbox

[v4] gcov: Runtime configurable destination output

Message ID ad743fe7-c5d6-c528-73c2-8add2c71f9d9@acm.org
State New
Headers show

Commit Message

Nathan Sidwell June 2, 2016, 12:23 p.m. UTC
On 05/31/16 11:04, Aaron Conole wrote:
> Nathan Sidwell <nathan@acm.org> writes:
>
>> On 05/26/16 13:08, Aaron Conole wrote:
>>> The previous gcov behavior was to always output errors on the stderr channel.
>>> This is fine for most uses, but some programs will require stderr to be
>>> untouched by libgcov for certain tests. This change allows configuring
>>> the gcov output via an environment variable which will be used to open
>>> the appropriate file.
>>
>> this is ok, thanks.


After offlist discussion, I committed this patch.  Thanks Aaron!


nathan
diff mbox

Patch

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.

Index: libgcov-driver-system.c
===================================================================
--- libgcov-driver-system.c	(revision 237032)
+++ libgcov-driver-system.c	(working copy)
@@ -23,19 +23,64 @@  a copy of the GCC Runtime Library Except
 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: libgcov-driver.c
===================================================================
--- libgcov-driver.c	(revision 237032)
+++ libgcov-driver.c	(working copy)
@@ -43,9 +43,13 @@  void __gcov_init (struct gcov_info *p __
 
 #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