This patch nadgers the driver's subprocess names to include the driver name. It results in more informative error messages. For instance, rather than:

  >./xg++ -B./ frob.cc -c -fdump-tree-nope
  cc1plus: error: unrecognized command line option '-fdump-tree-nope'

we get:

  >./xg++ -B./ frob.cc -c -fdump-tree-nope
  xg++(cc1plus): error: unrecognized command line option '-fdump-tree-nope'

Thereby cluing the user into this being a compiler error. (When this error is buried inside a build log, the poor user can be more confused as to what this cc1plus thing might be).

I achieve this by taking advantage of the subprocess spawning taking separate arguments for the program to exec, and the argv[0] value passed to that program. Because subprocesses can use argv[0] to locate themselves I propagate the directory name, so that remains as before.

When using valgrind, this substitution is not performed, because valgrind relies on argv[0] being the program pathname.

The -v output is unaffected, as that is emitted before altering argv[0]. argv[0] is also restored after spawning.

This then allows us to elide process_command's check of whether the input file exists. That's optimizing for failure, but I suspect is desired merely to avoid an error of the form:
  cc1plus: fatal error: frob.cc: No such file or directory

As you can see process_command does some special handling for lto & @files, which is kind of icky and now goes away. We get:
  xg++(cc1plus): fatal error: frob.cc: No such file or directory

Thoughts? Ok? Stupid idea?

nathan

--
Nathan Sidwell
2019-05-14  Nathan Sidwell  <nat...@acm.org>

	* gcc.c (execute): Splice current executable name into spawned
	argv[0] for better subprocess diagnostics.
	(process_command): Do not check if input file exists.

	* lib/prune.exp (prune_gcc_output): Adjust collect regexps.

Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 271131)
+++ gcc/gcc.c	(working copy)
@@ -3206,6 +3206,48 @@ execute (void)
       int err;
       const char *string = commands[i].argv[0];
 
+      if (commands[i].argv == argbuf.address ())
+	{
+	  /* Munge argv[0], the one given in the exec'd command's
+	     argv, to include information about from whence it was
+	     spawned.  We preserve the directory component so the
+	     command can determine where it is, but not what it was
+	     called.  Thus its otherwise-unlocated errors specify
+	     something like 'g++(cc1plus)' rather than plain
+	     'cc1plus'.  Only do this if argv is the argbuf address,
+	     so as to not interfere with valgrind insertion.  */
+	  size_t slen = strlen (string);
+	  size_t plen = strlen (progname);
+	  size_t tlen = strlen (commands[i].prog);
+
+	  /* Remove the filename component from the path.  */
+	  while (slen && !IS_DIR_SEPARATOR (string[slen-1]))
+	    slen--;
+	  char *ren = XNEWVEC (char, slen + plen + tlen + 3);
+	  size_t off = 0;
+
+	  /* Copy directory, including final dir separator.  */
+	  memcpy (ren + off, string, slen);
+	  off += slen;
+	  /* Append our progname.  */
+	  memcpy (ren + off, progname, plen);
+	  off += plen;
+
+	  ren[off++] = '(';
+
+	  /* Append the plain progname (lacking any os-specific
+	     suffix).  */
+	  memcpy (ren + off, commands[i].prog, tlen);
+	  off += tlen;
+
+	  ren[off++] = ')';
+
+	  /* And a NUL.  */
+	  ren[off++] = 0;
+
+	  commands[i].argv[0] = ren;
+	}
+
       errmsg = pex_run (pex,
 			((i + 1 == n_commands ? PEX_LAST : 0)
 			 | (string == commands[i].prog ? PEX_SEARCH : 0)),
@@ -3220,6 +3262,12 @@ execute (void)
 		       string, errmsg);
 	}
 
+      if (commands[i].argv[0] != string)
+	{
+	  free (const_cast <char *> (commands[i].argv[0]));
+	  commands[i].argv[0] = string;
+	}
+
       if (i && string != commands[i].prog)
 	free (CONST_CAST (char *, string));
     }
@@ -4561,44 +4609,11 @@ process_command (unsigned int decoded_op
       if (decoded_options[j].opt_index == OPT_SPECIAL_input_file)
 	{
 	  const char *arg = decoded_options[j].arg;
-          const char *p = strrchr (arg, '@');
-          char *fname;
-	  long offset;
-	  int consumed;
 #ifdef HAVE_TARGET_OBJECT_SUFFIX
 	  arg = convert_filename (arg, 0, access (arg, F_OK));
 #endif
-	  /* For LTO static archive support we handle input file
-	     specifications that are composed of a filename and
-	     an offset like FNAME@OFFSET.  */
-	  if (p
-	      && p != arg
-	      && sscanf (p, "@%li%n", &offset, &consumed) >= 1
-	      && strlen (p) == (unsigned int)consumed)
-	    {
-              fname = (char *)xmalloc (p - arg + 1);
-              memcpy (fname, arg, p - arg);
-              fname[p - arg] = '\0';
-	      /* Only accept non-stdin and existing FNAME parts, otherwise
-		 try with the full name.  */
-	      if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
-		{
-		  free (fname);
-		  fname = xstrdup (arg);
-		}
-	    }
-	  else
-	    fname = xstrdup (arg);
-
-          if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
-	    {
-	      bool resp = fname[0] == '@' && access (fname + 1, F_OK) < 0;
-	      error ("%s: %m", fname + resp);
-	    }
-          else
-	    add_infile (arg, spec_lang);
+	  add_infile (arg, spec_lang);
 
-          free (fname);
 	  continue;
 	}
 
Index: gcc/testsuite/lib/prune.exp
===================================================================
--- gcc/testsuite/lib/prune.exp	(revision 271131)
+++ gcc/testsuite/lib/prune.exp	(working copy)
@@ -37,8 +37,8 @@ proc prune_gcc_output { text } {
     regsub -all "(^|\n)\[^\n\]*:   . skipping \[0-9\]* instantiation contexts \[^\n\]*" $text "" text
     regsub -all "(^|\n)\[^\n\]*:   in constexpr expansion \[^\n\]*" $text "" text
     regsub -all "(^|\n)    inlined from \[^\n\]*" $text "" text
-    regsub -all "(^|\n)collect2: error: ld returned \[^\n\]*" $text "" text
-    regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text
+    regsub -all "(^|\n)\[a-z+]*\\(?collect2\\)?: error: ld returned \[^\n\]*" $text "" text
+    regsub -all "(^|\n)\[a-z+]*\\(?collect\\)?: re(compiling|linking)\[^\n\]*" $text "" text
     regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
     regsub -all "(^|\n)\[0-9\]\[0-9\]* errors\." $text "" text
     regsub -all "(^|\n)(In file included|\[ \]+from)\[^\n\]*" $text "" text

Reply via email to