[v3] gcov: Runtime configurable destination output
diff mbox

Message ID 1464033826-13049-1-git-send-email-aconole@bytheb.org
State New
Headers show

Commit Message

Aaron Conole May 23, 2016, 8:03 p.m. UTC
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.
---
 libgcc/libgcov-driver-system.c | 43 +++++++++++++++++++++++++++++++++++++++++-
 libgcc/libgcov-driver.c        |  6 ++++++
 2 files changed, 48 insertions(+), 1 deletion(-)

Comments

Nathan Sidwell May 24, 2016, 1:47 p.m. UTC | #1
On 05/23/16 16:03, 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 patch is nearly there, but a couple of nits and an error on my part.


> +/* Configured via the GCOV_ERROR_FILE environment variable;
> +   it will either be stderr, or a file of the user's choosing. */
> +static FILE *gcov_error_file;

I was wrong about making this static.  Your original externally visible 
definition (with leading __) was right.  The reason is that multiple gcov-aware 
shared objects should use the same FILE for errors.  If you could restore that 
part of your previous patch, along  with a comment explaining why 
gcov_error_file is externally visible, but get_gcov_error is static, that'd be 
great.

> +
> +/* A utility function to populate the gcov_error_file pointer */
> +
> +static FILE *
> +get_gcov_error_file(void)
> +{
> +#if IN_GCOV_TOOL
> +  return stderr;
> +#endif

Prefer #else ... #endif to encapsulate the  remaining bit of the function.

>
>  /* A utility function for outputing errors.  */

May as well fix the spelling error
   outputing -> outputting


> +#if !IN_GCOV_TOOL
> +static void
> +gcov_error_exit(void)
> +{
> +  if (gcov_error_file && gcov_error_file != stderr)
> +    {
> +      fclose(gcov_error_file);

needs space -- the habit'll grow


> +#if !IN_GCOV_TOOL
> +static void gcov_error_exit(void);

space before '('

nathan

Patch
diff mbox

diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 4e3b244..461715f 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -23,6 +23,31 @@  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/>.  */
 
+/* Configured via the GCOV_ERROR_FILE environment variable;
+   it will either be stderr, or a file of the user's choosing. */
+static FILE *gcov_error_file;
+
+/* A utility function to populate the gcov_error_file pointer */
+
+static FILE *
+get_gcov_error_file(void)
+{
+#if IN_GCOV_TOOL
+  return stderr;
+#endif
+  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;
+}
+
 /* A utility function for outputing errors.  */
 
 static int __attribute__((format(printf, 1, 2)))
@@ -30,12 +55,28 @@  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.  */
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 9c4eeca..92fb8ab 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -46,6 +46,10 @@  void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
 /* A utility function for outputing 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