From 1f2bb38a85710f650d1ea87f0765cb50e19c3212 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 29 Jun 2018 16:03:36 +0200 Subject: [PATCH] When using -fprofile-generate=/some/path mangle absolute path of file (PR lto/85759). 2018-06-29 Martin Liska PR lto/85759 * coverage.c (coverage_init): Mangle full path name. * doc/invoke.texi: Document the change. * gcov-io.c (mangle_path): New. * gcov-io.h (mangle_path): Likewise. * gcov.c (mangle_name): Use mangle_path for path mangling. From-SVN: r262251 --- gcc/ChangeLog | 9 +++++++++ gcc/coverage.c | 20 ++++++++++++++++-- gcc/doc/invoke.texi | 3 +++ gcc/gcov-io.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ gcc/gcov-io.h | 1 + gcc/gcov.c | 37 +--------------------------------- 6 files changed, 81 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a76fea96782..a0da66e6932 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-06-29 Martin Liska + + PR lto/85759 + * coverage.c (coverage_init): Mangle full path name. + * doc/invoke.texi: Document the change. + * gcov-io.c (mangle_path): New. + * gcov-io.h (mangle_path): Likewise. + * gcov.c (mangle_name): Use mangle_path for path mangling. + 2018-06-29 Kyrylo Tkachov * config/arm/arm.c (output_move_double): Don't allow STRD instructions diff --git a/gcc/coverage.c b/gcc/coverage.c index 350cc4559c5..9c9d3dbd39e 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -1220,8 +1220,24 @@ coverage_init (const char *filename) g->get_passes ()->get_pass_profile ()->static_pass_number; g->get_dumps ()->dump_start (profile_pass_num, NULL); - if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename)) - profile_data_prefix = getpwd (); + if (!IS_ABSOLUTE_PATH (filename)) + { + /* When a profile_data_prefix is provided, then mangle full path + 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 = mangle_path (filename); + len = strlen (filename); + } + else + profile_data_prefix = getpwd (); + } if (profile_data_prefix) prefix_len = strlen (profile_data_prefix); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 248e6039722..0180bec183e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11352,6 +11352,9 @@ and used by @option{-fprofile-use} and @option{-fbranch-probabilities} and its related options. Both absolute and relative paths can be used. By default, GCC uses the current directory as @var{path}, thus the profile data file appears in the same directory as the object file. +In order to prevent filename clashing, if object file name is not an absolute +path, we mangle absolute path of @file{@var{sourcename}.gcda} file and +use it as file name of a @file{.gcda} file. When an executable is run in a massive parallel environment, it is recommended to save profile to different folders. That can be done with variables diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c index e07ae76420b..311e4d014bf 100644 --- a/gcc/gcov-io.c +++ b/gcc/gcov-io.c @@ -566,6 +566,55 @@ gcov_read_counter (void) return value; } +/* Mangle filename path of BASE and output new allocated pointer with + mangled path. */ + +char * +mangle_path (char const *base) +{ + /* Convert '/' to '#', convert '..' to '^', + convert ':' to '~' on DOS based file system. */ + const char *probe; + char *buffer = (char *)xmalloc (strlen (base) + 10); + char *ptr = buffer; + +#if HAVE_DOS_BASED_FILE_SYSTEM + if (base[0] && base[1] == ':') + { + ptr[0] = base[0]; + ptr[1] = '~'; + ptr += 2; + base += 2; + } +#endif + for (; *base; base = probe) + { + size_t len; + + for (probe = base; *probe; probe++) + if (*probe == '/') + break; + len = probe - base; + if (len == 2 && base[0] == '.' && base[1] == '.') + *ptr++ = '^'; + else + { + memcpy (ptr, base, len); + ptr += len; + } + if (*probe) + { + *ptr++ = '#'; + probe++; + } + } + + /* Terminate the string. */ + *ptr = '\0'; + + return buffer; +} + /* We need to expose the below function when compiling for gcov-tool. */ #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index 56391defab3..7a11f0aec7f 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -371,6 +371,7 @@ GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *) ATTRIBUTE_HIDDEN; GCOV_LINKAGE const char *gcov_read_string (void); GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/, gcov_unsigned_t /*length */); +char *mangle_path (char const *base); #if !IN_GCOV /* Available outside gcov */ diff --git a/gcc/gcov.c b/gcc/gcov.c index 2114a43d140..ad2de4d5b22 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -2461,42 +2461,7 @@ mangle_name (char const *base, char *ptr) ptr += len; } else - { - /* Convert '/' to '#', convert '..' to '^', - convert ':' to '~' on DOS based file system. */ - const char *probe; - -#if HAVE_DOS_BASED_FILE_SYSTEM - if (base[0] && base[1] == ':') - { - ptr[0] = base[0]; - ptr[1] = '~'; - ptr += 2; - base += 2; - } -#endif - for (; *base; base = probe) - { - size_t len; - - for (probe = base; *probe; probe++) - if (*probe == '/') - break; - len = probe - base; - if (len == 2 && base[0] == '.' && base[1] == '.') - *ptr++ = '^'; - else - { - memcpy (ptr, base, len); - ptr += len; - } - if (*probe) - { - *ptr++ = '#'; - probe++; - } - } - } + ptr = mangle_path (base); return ptr; } -- 2.30.2