On Fri, Nov 10, 2023 at 12:01 PM Prathamesh Kulkarni
<prathamesh.kulka...@linaro.org> wrote:
>
> On Thu, 5 Oct 2023 at 00:00, Brendan Shanks <bsha...@codeweavers.com> wrote:
> >
> > Hi,
> >
> > This patch implements pex_unix_exec_child using posix_spawn when
> > available.
> >
> > This should especially benefit recent macOS (where vfork just calls
> > fork), but should have equivalent or faster performance on all
> > platforms.
> > In addition, the implementation is substantially simpler than the
> > vfork+exec code path.
> >
> > Tested on x86_64-linux.
> Hi Brendan,
> It seems this patch caused the following regressions on aarch64:
>
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++17  at line 3 (test for
> errors, line )
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++17 (test for excess errors)
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++2a  at line 3 (test for
> errors, line )
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++2a (test for excess errors)
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++2b  at line 3 (test for
> errors, line )
> FAIL: g++.dg/modules/bad-mapper-1.C -std=c++2b (test for excess errors)
>
> Looking at g++.log:
> /home/tcwg-buildslave/workspace/tcwg_gnu_2/abe/snapshots/gcc.git~master/gcc/testsuite/g++.dg/modules/bad-mapper-1.C:
> error: failed posix_spawnp mapper 'this-will-not-work'
> In module imported at
> /home/tcwg-buildslave/workspace/tcwg_gnu_2/abe/snapshots/gcc.git~master/gcc/testsuite/g++.dg/modules/bad-mapper-1.C:2:1:
> unique1.bob: error: failed to read compiled module: No such file or directory
> unique1.bob: note: compiled module file is 'gcm.cache/unique1.bob.gcm'
> unique1.bob: note: imports must be built before being imported
> unique1.bob: fatal error: returning to the gate for a mechanical issue
> compilation terminated.
>
> Link to log files:
> https://ci.linaro.org/job/tcwg_gcc_check--master-aarch64-build/1159/artifact/artifacts/00-sumfiles/
> Could you please investigate ?

The testcase needs adjustment, it looks for

// { dg-error "-:failed (exec|CreateProcess).*mapper.*
.*this-will-not-work" "" { target { ! { *-*-darwin[89]* *-*-darwin10*
} } } 0 }

adding |posix_spawnp probably works

>
> Thanks,
> Prathamesh
> >
> > v2: Fix error handling (previously the function would be run twice in
> > case of error), and don't use a macro that changes control flow.
> >
> > v3: Match file style for error-handling blocks, don't close
> > in/out/errdes on error, and check close() for errors.
> >
> > libiberty/
> >         * configure.ac (AC_CHECK_HEADERS): Add spawn.h.
> >         (checkfuncs): Add posix_spawn, posix_spawnp.
> >         (AC_CHECK_FUNCS): Add posix_spawn, posix_spawnp.
> >         * configure, config.in: Rebuild.
> >         * pex-unix.c [HAVE_POSIX_SPAWN] (pex_unix_exec_child): New function.
> >
> > Signed-off-by: Brendan Shanks <bsha...@codeweavers.com>
> > ---
> >  libiberty/configure.ac |   8 +-
> >  libiberty/pex-unix.c   | 168 +++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 173 insertions(+), 3 deletions(-)
> >
> > diff --git a/libiberty/configure.ac b/libiberty/configure.ac
> > index 0748c592704..2488b031bc8 100644
> > --- a/libiberty/configure.ac
> > +++ b/libiberty/configure.ac
> > @@ -289,7 +289,7 @@ AC_SUBST_FILE(host_makefile_frag)
> >  # It's OK to check for header files.  Although the compiler may not be
> >  # able to link anything, it had better be able to at least compile
> >  # something.
> > -AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h 
> > string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h 
> > sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h 
> > machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h 
> > stdio_ext.h process.h sys/prctl.h)
> > +AC_CHECK_HEADERS(sys/file.h sys/param.h limits.h stdlib.h malloc.h 
> > string.h unistd.h strings.h sys/time.h time.h sys/resource.h sys/stat.h 
> > sys/mman.h fcntl.h alloca.h sys/pstat.h sys/sysmp.h sys/sysinfo.h 
> > machine/hal_sysinfo.h sys/table.h sys/sysctl.h sys/systemcfg.h stdint.h 
> > stdio_ext.h process.h sys/prctl.h spawn.h)
> >  AC_HEADER_SYS_WAIT
> >  AC_HEADER_TIME
> >
> > @@ -412,7 +412,8 @@ funcs="$funcs setproctitle"
> >  vars="sys_errlist sys_nerr sys_siglist"
> >
> >  checkfuncs="__fsetlocking canonicalize_file_name dup3 getrlimit getrusage \
> > - getsysinfo gettimeofday on_exit pipe2 psignal pstat_getdynamic 
> > pstat_getstatic \
> > + getsysinfo gettimeofday on_exit pipe2 posix_spawn posix_spawnp psignal \
> > + pstat_getdynamic pstat_getstatic \
> >   realpath setrlimit spawnve spawnvpe strerror strsignal sysconf sysctl \
> >   sysmp table times wait3 wait4"
> >
> > @@ -435,7 +436,8 @@ if test "x" = "y"; then
> >      index insque \
> >      memchr memcmp memcpy memmem memmove memset mkstemps \
> >      on_exit \
> > -    pipe2 psignal pstat_getdynamic pstat_getstatic putenv \
> > +    pipe2 posix_spawn posix_spawnp psignal \
> > +    pstat_getdynamic pstat_getstatic putenv \
> >      random realpath rename rindex \
> >      sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve 
> > spawnvpe \
> >       stpcpy stpncpy strcasecmp strchr strdup \
> > diff --git a/libiberty/pex-unix.c b/libiberty/pex-unix.c
> > index 33b5bce31c2..336799d1125 100644
> > --- a/libiberty/pex-unix.c
> > +++ b/libiberty/pex-unix.c
> > @@ -58,6 +58,9 @@ extern int errno;
> >  #ifdef HAVE_PROCESS_H
> >  #include <process.h>
> >  #endif
> > +#ifdef HAVE_SPAWN_H
> > +#include <spawn.h>
> > +#endif
> >
> >  #ifdef vfork /* Autoconf may define this to fork for us. */
> >  # define VFORK_STRING "fork"
> > @@ -559,6 +562,171 @@ pex_unix_exec_child (struct pex_obj *obj 
> > ATTRIBUTE_UNUSED,
> >    return (pid_t) -1;
> >  }
> >
> > +#elif defined(HAVE_POSIX_SPAWN) && defined(HAVE_POSIX_SPAWNP)
> > +/* Implementation of pex->exec_child using posix_spawn.            */
> > +
> > +static pid_t
> > +pex_unix_exec_child (struct pex_obj *obj ATTRIBUTE_UNUSED,
> > +                    int flags, const char *executable,
> > +                    char * const * argv, char * const * env,
> > +                    int in, int out, int errdes,
> > +                    int toclose, const char **errmsg, int *err)
> > +{
> > +  int ret;
> > +  pid_t pid = -1;
> > +  posix_spawnattr_t attr;
> > +  posix_spawn_file_actions_t actions;
> > +  int attr_initialized = 0, actions_initialized = 0;
> > +
> > +  *err = 0;
> > +
> > +  ret = posix_spawnattr_init (&attr);
> > +  if (ret)
> > +    {
> > +      *err = ret;
> > +      *errmsg = "posix_spawnattr_init";
> > +      goto exit;
> > +    }
> > +  attr_initialized = 1;
> > +
> > +  /* Use vfork() on glibc <=2.24. */
> > +#ifdef POSIX_SPAWN_USEVFORK
> > +  ret = posix_spawnattr_setflags (&attr, POSIX_SPAWN_USEVFORK);
> > +  if (ret)
> > +    {
> > +      *err = ret;
> > +      *errmsg = "posix_spawnattr_setflags";
> > +      goto exit;
> > +    }
> > +#endif
> > +
> > +  ret = posix_spawn_file_actions_init (&actions);
> > +  if (ret)
> > +    {
> > +      *err = ret;
> > +      *errmsg = "posix_spawn_file_actions_init";
> > +      goto exit;
> > +    }
> > +  actions_initialized = 1;
> > +
> > +  if (in != STDIN_FILE_NO)
> > +    {
> > +      ret = posix_spawn_file_actions_adddup2 (&actions, in, STDIN_FILE_NO);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_adddup2";
> > +          goto exit;
> > +        }
> > +
> > +      ret = posix_spawn_file_actions_addclose (&actions, in);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_addclose";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +  if (out != STDOUT_FILE_NO)
> > +    {
> > +      ret = posix_spawn_file_actions_adddup2 (&actions, out, 
> > STDOUT_FILE_NO);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_adddup2";
> > +          goto exit;
> > +        }
> > +
> > +      ret = posix_spawn_file_actions_addclose (&actions, out);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_addclose";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +  if (errdes != STDERR_FILE_NO)
> > +    {
> > +      ret = posix_spawn_file_actions_adddup2 (&actions, errdes, 
> > STDERR_FILE_NO);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_adddup2";
> > +          goto exit;
> > +        }
> > +
> > +      ret = posix_spawn_file_actions_addclose (&actions, errdes);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_addclose";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +  if (toclose >= 0)
> > +    {
> > +      ret = posix_spawn_file_actions_addclose (&actions, toclose);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_addclose";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +  if ((flags & PEX_STDERR_TO_STDOUT) != 0)
> > +    {
> > +      ret = posix_spawn_file_actions_adddup2 (&actions, STDOUT_FILE_NO, 
> > STDERR_FILE_NO);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn_file_actions_adddup2";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +  if ((flags & PEX_SEARCH) != 0)
> > +    {
> > +      ret = posix_spawnp (&pid, executable, &actions, &attr, argv, env ? 
> > env : environ);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawnp";
> > +          goto exit;
> > +        }
> > +    }
> > +  else
> > +    {
> > +      ret = posix_spawn (&pid, executable, &actions, &attr, argv, env ? 
> > env : environ);
> > +      if (ret)
> > +        {
> > +          *err = ret;
> > +          *errmsg = "posix_spawn";
> > +          goto exit;
> > +        }
> > +    }
> > +
> > +exit:
> > +  if (actions_initialized)
> > +    posix_spawn_file_actions_destroy (&actions);
> > +  if (attr_initialized)
> > +    posix_spawnattr_destroy (&attr);
> > +
> > +  if (!*err && in != STDIN_FILE_NO)
> > +    if (close (in))
> > +      *errmsg = "close", *err = errno, pid = -1;
> > +  if (!*err && out != STDOUT_FILE_NO)
> > +    if (close (out))
> > +      *errmsg = "close", *err = errno, pid = -1;
> > +  if (!*err && errdes != STDERR_FILE_NO)
> > +    if (close (errdes))
> > +      *errmsg = "close", *err = errno, pid = -1;
> > +
> > +  return pid;
> > +}
> >  #else
> >  /* Implementation of pex->exec_child using standard vfork + exec.  */
> >
> > --
> > 2.41.0
> >

Reply via email to