Support variables in expansion of -fprofile-generate option (PR gcov-profile/47618).

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

	PR gcov-profile/47618
	* doc/invoke.texi: Document how -fprofile-dir format
        is extended.
2018-06-05  Martin Liska  <mliska@suse.cz>

	PR gcov-profile/47618
	* libgcov-driver-system.c (replace_filename_variables): New
        function.
	(gcov_exit_open_gcda_file): Use it.

From-SVN: r261199
This commit is contained in:
Martin Liska 2018-06-05 14:10:22 +02:00 committed by Martin Liska
parent 066c4268db
commit 97a53d1d04
4 changed files with 97 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2018-06-05 Martin Liska <mliska@suse.cz>
PR gcov-profile/47618
* doc/invoke.texi: Document how -fprofile-dir format
is extended.
2018-06-05 Richard Biener <rguenther@suse.de>
* tree-cfgcleanup.c (cleanup_control_flow_pre): For edge

View File

@ -11343,6 +11343,20 @@ 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.
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
in @var{path} that are exported during run-time:
@table @gcctabopt
@item %p
process ID.
@item %q@{VAR@}
value of environment variable @var{VAR}
@end table
@item -fprofile-generate
@itemx -fprofile-generate=@var{path}
@opindex fprofile-generate

View File

@ -1,3 +1,10 @@
2018-06-05 Martin Liska <mliska@suse.cz>
PR gcov-profile/47618
* libgcov-driver-system.c (replace_filename_variables): New
function.
(gcov_exit_open_gcda_file): Use it.
2018-06-05 Martin Liska <mliska@suse.cz>
* libgcov-driver.c (gcov_compute_histogram): Remove usage

View File

@ -136,6 +136,74 @@ create_file_directory (char *filename)
#endif
}
/* Replace filename variables in FILENAME. We currently support expansion:
%p - process ID
%q{ENV} - value of environment variable ENV
*/
static char *
replace_filename_variables (char *filename)
{
char buffer[16];
char empty[] = "";
for (char *p = filename; *p != '\0'; p++)
{
unsigned length = strlen (filename);
if (*p == '%' && *(p + 1) != '\0')
{
unsigned start = p - filename;
p++;
char *replacement = NULL;
switch (*p)
{
case 'p':
sprintf (buffer, "%d", getpid ());
replacement = buffer;
p++;
break;
case 'q':
if (*(p + 1) == '{')
{
p += 2;
char *e = strchr (p, '}');
if (e)
{
*e = '\0';
replacement = getenv (p);
if (replacement == NULL)
replacement = empty;
p = e + 1;
}
else
return filename;
}
break;
default:
return filename;
}
/* Concat beginning of the path, replacement and
ending of the path. */
unsigned end = length - (p - filename);
unsigned repl_length = strlen (replacement);
char *buffer = (char *)xmalloc (start + end + repl_length + 1);
char *buffer_ptr = buffer;
buffer_ptr = (char *)mempcpy (buffer_ptr, filename, start);
buffer_ptr = (char *)mempcpy (buffer_ptr, replacement, repl_length);
buffer_ptr = (char *)mempcpy (buffer_ptr, p, end);
*buffer_ptr = '\0';
free (filename);
filename = buffer;
p = buffer + start + repl_length;
}
}
return filename;
}
static void
allocate_filename_struct (struct gcov_filename *gf)
{
@ -224,6 +292,8 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
}
strcpy (dst, fname);
gf->filename = replace_filename_variables (gf->filename);
if (!gcov_open (gf->filename))
{
/* Open failed likely due to missed directory.