diff mbox

Validate that destination gcov file does not exist for, gcov-tool (PR gcov-profile/78783).

Message ID a44c80a2-f717-1bc5-64e6-2dea6d67f666@suse.cz
State New
Headers show

Commit Message

Martin Liška April 14, 2017, 12:45 p.m. UTC
Hello.

Patch handles ICE when gcov-tool either merges or scales gcov files and
destination folder (where all files are merged) is non-empty.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
And gcov.exp works on x86_64-linux-gnu.

Ready to be installed?
Martin

Comments

Nathan Sidwell April 14, 2017, 12:48 p.m. UTC | #1
On 04/14/2017 08:45 AM, Martin Liška wrote:
> Hello.
>
> Patch handles ICE when gcov-tool either merges or scales gcov files and
> destination folder (where all files are merged) is non-empty.
>
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> And gcov.exp works on x86_64-linux-gnu.

Ok. Perhaps change the message from:
fatal_error (input_location, "Output file %s should be removed "
+		 "in destination folder: %s", filename, out);

to 'output file %s already exists in folder %s' or something?  I.e report what 
the problem is, not what the solution might be -- after all, if the only 
solution is to delete the output file, why isn't gcov-tool doing that?

nathan
Martin Liška April 14, 2017, 1:32 p.m. UTC | #2
On 04/14/2017 02:48 PM, Nathan Sidwell wrote:
> On 04/14/2017 08:45 AM, Martin Liška wrote:
>> Hello.
>>
>> Patch handles ICE when gcov-tool either merges or scales gcov files and
>> destination folder (where all files are merged) is non-empty.
>>
>> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
>> And gcov.exp works on x86_64-linux-gnu.
>
> Ok. Perhaps change the message from:
> fatal_error (input_location, "Output file %s should be removed "
> +         "in destination folder: %s", filename, out);

Thanks, I'll change that.

>
> to 'output file %s already exists in folder %s' or something?  I.e report what the problem is, not what the solution might be -- after all, if the only solution is to delete the output file, why isn't gcov-tool doing that?

It's doing that on targets that have nftw:

static int
unlink_profile_dir (const char *path ATTRIBUTE_UNUSED)
{
#if HAVE_FTW_H
     return nftw(path, unlink_gcda_file, 64, FTW_DEPTH | FTW_PHYS);
#else
     return -1;
#endif
}

Martin

>
> nathan
>
diff mbox

Patch

From 14b0d700bccb87559203d40216975e67ca52415b Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Thu, 13 Apr 2017 16:10:26 +0200
Subject: [PATCH] Validate that destination gcov file does not exist for
 gcov-tool (PR gcov-profile/78783).

libgcc/ChangeLog:

2017-04-13  Martin Liska  <mliska@suse.cz>

	* libgcov-driver.c (gcov_get_filename): New function.

gcc/ChangeLog:

2017-04-13  Martin Liska  <mliska@suse.cz>

	* gcov-tool.c (gcov_output_files): Validate that destination
	file is either removed by the tool or by a user.
---
 gcc/gcov-tool.c         | 9 +++++++++
 libgcc/libgcov-driver.c | 9 +++++++++
 2 files changed, 18 insertions(+)

diff --git a/gcc/gcov-tool.c b/gcc/gcov-tool.c
index cadf09377dd..e241de2bfe2 100644
--- a/gcc/gcov-tool.c
+++ b/gcc/gcov-tool.c
@@ -46,6 +46,7 @@  extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
 extern void gcov_do_dump (struct gcov_info *, int);
+extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
 /* Set to verbose output mode.  */
@@ -114,6 +115,14 @@  gcov_output_files (const char *out, struct gcov_info *profile)
   if (ret)
     fatal_error (input_location, "Cannot change directory to %s", out);
 
+  /* Verify that output file does not exist (either was removed by
+     unlink_profile_data or removed by user).  */
+  const char *filename = gcov_get_filename (profile);
+
+  if (access (filename, F_OK) != -1)
+    fatal_error (input_location, "Output file %s should be removed "
+		 "in destination folder: %s", filename, out);
+
   gcov_do_dump (profile, 0);
 
   ret = chdir (pwd);
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 70fe69f26b5..c3b2fd4d5ce 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -852,6 +852,15 @@  gcov_do_dump (struct gcov_info *list, int run_counted)
   free (gf.filename);
 }
 
+#if IN_GCOV_TOOL
+const char *
+__attribute__ ((unused))
+gcov_get_filename (struct gcov_info *list)
+{
+  return list->filename;
+}
+#endif
+
 #if !IN_GCOV_TOOL
 void
 __gcov_dump_one (struct gcov_root *root)
-- 
2.12.2