Don't search for $SHELL in procfs.c

Message ID yddvaat1np6.fsf@CeBiTec.Uni-Bielefeld.DE
State New, archived
Headers

Commit Message

Rainer Orth June 8, 2018, 12:12 p.m. UTC
  When building gdb mainline on Solaris with g++ 8.1 with the fixes in

	https://sourceware.org/ml/gdb-patches/2018-06/msg00196.html

one failure remains:

/vol/src/gnu/gdb/gdb/dist/gdb/procfs.c: In member function ‘virtual void procfs_target::create_inferior(const char*, const string&, char**, int)’:
/vol/src/gnu/gdb/gdb/dist/gdb/procfs.c:3098:12: error: ‘char* std::strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
    strncpy (tryname, p, len);
    ~~~~~~~~^~~~~~~~~~~~~~~~~
/vol/src/gnu/gdb/gdb/dist/gdb/procfs.c:3097:19: note: length computed here
      len = strlen (p);
            ~~~~~~~^~~
cc1plus: all warnings being treated as errors

I didn't even try to get rid of this, but revived an older patch of mine
to rip out the code to search for $SHELL in $PATH.  procfs.c is the only
caller of fork_inferior that does this, and I don't see why Solaris
should be special here.  Since all callers call fork_inferior with
shell_file_arg = NULL now, one might even think about getting rid of
that arg as a followup.

Built on 64-bit Solaris 11.5/x86 (amd64-pc-solaris2.11), make check
running.  Ok for mainline if that passes?

Thanks.
        Rainer
  

Comments

Pedro Alves June 8, 2018, 1:17 p.m. UTC | #1
On 06/08/2018 01:12 PM, Rainer Orth wrote:
> When building gdb mainline on Solaris with g++ 8.1 with the fixes in
> 
> 	https://sourceware.org/ml/gdb-patches/2018-06/msg00196.html
> 
> one failure remains:
> 
> /vol/src/gnu/gdb/gdb/dist/gdb/procfs.c: In member function ‘virtual void procfs_target::create_inferior(const char*, const string&, char**, int)’:
> /vol/src/gnu/gdb/gdb/dist/gdb/procfs.c:3098:12: error: ‘char* std::strncpy(char*, const char*, size_t)’ output truncated before terminating nul copying as many bytes from a string as its length [-Werror=stringop-truncation]
>     strncpy (tryname, p, len);
>     ~~~~~~~~^~~~~~~~~~~~~~~~~
> /vol/src/gnu/gdb/gdb/dist/gdb/procfs.c:3097:19: note: length computed here
>       len = strlen (p);
>             ~~~~~~~^~~
> cc1plus: all warnings being treated as errors
> 
> I didn't even try to get rid of this, but revived an older patch of mine
> to rip out the code to search for $SHELL in $PATH.  procfs.c is the only
> caller of fork_inferior that does this, and I don't see why Solaris
> should be special here.  Since all callers call fork_inferior with
> shell_file_arg = NULL now, one might even think about getting rid of
> that arg as a followup.

On Unix ports, spawning a child process results in one fork, tracing the
fork child, and then one exec event for when the child execs the shell,
and then another exec event when the shell execs the program that we want
the child to be running.

The comment is talking about some system behaving differently:

-      /* We will be looking down the PATH to find shell_file.  If we
-	 just do this the normal way (via execlp, which operates by
-	 attempting an exec for each element of the PATH until it
-	 finds one which succeeds), then there will be an exec for
-	 each failed attempt, each of which will cause a PR_SYSEXIT
-	 stop, and we won't know how to distinguish the PR_SYSEXIT's
-	 for these failed execs with the ones for successful execs
-	 (whether the exec has succeeded is stored at that time in the
-	 carry bit or some such architecture-specific and
-	 non-ABI-specified place).
-

That might have been for some older Solaris, or even for one of the
other ports that used to use procfs.c too (IRIX, etc.).

If it's not relevant for Solaris versions we care about, yeah,
let's just get rid of it.

> 
> Built on 64-bit Solaris 11.5/x86 (amd64-pc-solaris2.11), make check
> running.  Ok for mainline if that passes?

OK.

Thanks,
Pedro Alves
  

Patch

# HG changeset patch
# Parent  b84d0dfb82ddb3346ad186f337d57d34c8edff38
Don't search for $SHELL in procfs.c

diff --git a/gdb/procfs.c b/gdb/procfs.c
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -3053,92 +3053,16 @@  procfs_set_exec_trap (void)
 /* This function is called BEFORE gdb forks the inferior process.  Its
    only real responsibility is to set things up for the fork, and tell
    GDB which two functions to call after the fork (one for the parent,
-   and one for the child).
-
-   This function does a complicated search for a unix shell program,
-   which it then uses to parse arguments and environment variables to
-   be sent to the child.  I wonder whether this code could not be
-   abstracted out and shared with other unix targets such as
-   inf-ptrace?  */
+   and one for the child).  */
 
 static void
 procfs_create_inferior (struct target_ops *ops, const char *exec_file,
 			const std::string &allargs, char **env, int from_tty)
 {
-  char *shell_file = getenv ("SHELL");
-  char *tryname;
   int pid;
 
-  if (shell_file != NULL && strchr (shell_file, '/') == NULL)
-    {
-
-      /* We will be looking down the PATH to find shell_file.  If we
-	 just do this the normal way (via execlp, which operates by
-	 attempting an exec for each element of the PATH until it
-	 finds one which succeeds), then there will be an exec for
-	 each failed attempt, each of which will cause a PR_SYSEXIT
-	 stop, and we won't know how to distinguish the PR_SYSEXIT's
-	 for these failed execs with the ones for successful execs
-	 (whether the exec has succeeded is stored at that time in the
-	 carry bit or some such architecture-specific and
-	 non-ABI-specified place).
-
-	 So I can't think of anything better than to search the PATH
-	 now.  This has several disadvantages: (1) There is a race
-	 condition; if we find a file now and it is deleted before we
-	 exec it, we lose, even if the deletion leaves a valid file
-	 further down in the PATH, (2) there is no way to know exactly
-	 what an executable (in the sense of "capable of being
-	 exec'd") file is.  Using access() loses because it may lose
-	 if the caller is the superuser; failing to use it loses if
-	 there are ACLs or some such.  */
-
-      const char *p;
-      const char *p1;
-      /* FIXME-maybe: might want "set path" command so user can change what
-	 path is used from within GDB.  */
-      const char *path = getenv ("PATH");
-      int len;
-      struct stat statbuf;
-
-      if (path == NULL)
-	path = "/bin:/usr/bin";
-
-      tryname = (char *) alloca (strlen (path) + strlen (shell_file) + 2);
-      for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
-	{
-	  p1 = strchr (p, ':');
-	  if (p1 != NULL)
-	    len = p1 - p;
-	  else
-	    len = strlen (p);
-	  strncpy (tryname, p, len);
-	  tryname[len] = '\0';
-	  strcat (tryname, "/");
-	  strcat (tryname, shell_file);
-	  if (access (tryname, X_OK) < 0)
-	    continue;
-	  if (stat (tryname, &statbuf) < 0)
-	    continue;
-	  if (!S_ISREG (statbuf.st_mode))
-	    /* We certainly need to reject directories.  I'm not quite
-	       as sure about FIFOs, sockets, etc., but I kind of doubt
-	       that people want to exec() these things.  */
-	    continue;
-	  break;
-	}
-      if (p == NULL)
-	/* Not found.  This must be an error rather than merely passing
-	   the file to execlp(), because execlp() would try all the
-	   exec()s, causing GDB to get confused.  */
-	error (_("procfs:%d -- Can't find shell %s in PATH"),
-	       __LINE__, shell_file);
-
-      shell_file = tryname;
-    }
-
   pid = fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
-		       NULL, NULL, shell_file, NULL);
+		       NULL, NULL, NULL, NULL);
 
   /* We have something that executes now.  We'll be running through
      the shell at this point (if startup-with-shell is true), but the