[Bug gcov-profile/94570] New: -fprofile-dir is broken on Cygwin
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
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
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" ?