When using -fprofile-generate=/some/path mangle absolute path of file (PR lto/85759).

2018-06-29  Martin Liska  <mliska@suse.cz>

	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
This commit is contained in:
Martin Liska 2018-06-29 16:03:36 +02:00 committed by Martin Liska
parent 52057dc4ac
commit 1f2bb38a85
6 changed files with 81 additions and 38 deletions

View File

@ -1,3 +1,12 @@
2018-06-29 Martin Liska <mliska@suse.cz>
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 <kyrylo.tkachov@arm.com>
* config/arm/arm.c (output_move_double): Don't allow STRD instructions

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -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;
}