[Bug gcov-profile/94570] New: -fprofile-dir is broken on Cygwin

2020-04-12 Thread john at selbie dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94570

Bug ID: 94570
   Summary: -fprofile-dir is broken on Cygwin
   Product: gcc
   Version: 9.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: gcov-profile
  Assignee: unassigned at gcc dot gnu.org
  Reporter: john at selbie dot com
CC: marxin at gcc dot gnu.org
  Target Milestone: ---

The following bug is unique to gcc and g++ running on Cygwin.  I can repro this
on both gcc 9.2 and 9.3.

Using almost any source file, execute the following to start the first phase of
a profile guided optimization on Cygwin with a target directory to store .gcda
files:

$ g++ anyprogram.cpp -o anyprogram -fprofile-generate -fprofile-dir=profiledata

Then run the compiled code to start the program:

$ ./anyprogram.exe

After the program completes, the following output is revealed to show that the
coverage code couldn't save the gcda file:

profiling:profiledata/#home#jselbie\anyprogram.gcda:Skip

The .gcda file is not crated.

You can even see the mangled string it in the resulting binary:

$ strings anyprogram.exe | grep jselbie
profiledata/#home#jselbie\anyprogram.gcda


I see two possible issues that's causing this.

First, the anyprogram.gcda string is getting appended with a back slash instead
of a forward slash

A quick cursory glace of GCC sources would suggest the issue is in
\gcc\coverage.c. Looking at the code for coverage_init inside gcc/converage.c
reveals the following:

  if (profile_data_prefix)
{
#if HAVE_DOS_BASED_FILE_SYSTEM
 const char *separator = "\\";
#else
 const char *separator = "/";
#endif
 filename = concat (getpwd (), separator, filename, NULL);
 filename = mangle_path (filename);
 len = strlen (filename);
}


Another cursory search of gcc sources suggest HAVE_DOS_BASED_FILE_SYSTEM is
defined by this preprocessor stuff:

#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined
(__CYGWIN__)
#  ifndef HAVE_DOS_BASED_FILE_SYSTEM
#define HAVE_DOS_BASED_FILE_SYSTEM 1
#  endif

Because HAVE_DOS_BASED_FILE_SYSTEM is getting defined for Cygwin, then
coverage_init is going to use a backslash separator as well. Whether CYGWIN
should be considered a DOS based file system or a special exception needs to be
made in coverage_init, well, I'm not sure.

The second issue is with the way the path gets mangled with # chars.  That's
not consistent with the Linux build (at least with g++ 7.5 that I have going).


The workaround for now is to skip using the -fprofile-dir flag and allow
default save behavior for the gcda flag.

[Bug gcov-profile/94570] -fprofile-dir is broken on Cygwin

2020-04-15 Thread john at selbie dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94570

--- Comment #3 from John Selbie  ---
I am not sure I agree.  But I do defer to your expertise.

The problem is that Cygwin is not really a DOS_BASED_FILE_SYSTEM.  It's
emulating Unix - including using forward-slashes everywhere.  So I don't know
why it's trying to embed backslashes in the code.

Wouldn't the fix be this:

@@ -1215,7 +1215,7 @@ coverage_init (const char *filename)
 of filename in order to prevent file path clashing.  */
   if (profile_data_prefix)
{
-#if HAVE_DOS_BASED_FILE_SYSTEM
+#if HAVE_DOS_BASED_FILE_SYSTEM && !CYGWIN
  const char *separator = "\\";
 #else
  const char *separator = "/";


There's so reason to use backslashes at all, even for native Win32. Windows and
DOS can't handle forward slashes at the command line, but absolutely can handle
paths with forward slashes in code.  So an even simpler fix:

@@ -1215,12 +1215,7 @@ coverage_init (const char *filename)
 of filename in order to prevent file path clashing.  */
   if (profile_data_prefix)
{
-#if HAVE_DOS_BASED_FILE_SYSTEM
- const char *separator = "\\";
-#else
- const char *separator = "/";
-#endif
- filename = concat (getpwd (), separator, filename, NULL);
+ filename = concat (getpwd (), "/", filename, NULL);
  filename = mangle_path (filename);
  len = strlen (filename);
}


But even then I'm skeptical. I had "hacked the binary" with a hex editor to
change the backslash to a forward slash.  Same error, even though the modified
path appears on the screen:

   profiling:profile/#home#jselbie#bench/anyprogram.gcda:Skip

I even hacked it the other way to use forward slashes more consistently.  Same
thing:

profiling:profile\#home#jselbie#bench\anyprogram.gcda:Skip

So while I think forward-slash consistency is a key.  It's not the only bug
preventing the -fprofile-dir flag to work.

[Bug gcov-profile/94570] -fprofile-dir is broken on Cygwin

2020-04-15 Thread john at selbie dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94570

--- Comment #5 from John Selbie  ---
> All right, so it's normal Unix file system. Can you please show me output
of the 'pwd' command?

jselbie@IRONMAIDEN ~/bench
$ pwd
/home/jselbie/bench


I'm happy to test your patches, but I've actually never built gcc from scratch
before.  I'd have to read the docs on how to do that.  Is it has as simple as
running "./configure" and "make" ?