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.