On 06/11/2025 00:32, Bruno Haible wrote:
Pádraig Brady wrote:
Solaris 11.4, SPARC-M8, 1 coreutils fail  (cfarm216)
...
Putting truss in the test shows the failure after vfork:

vforkx(0)                                       = 26169
lwp_sigmask(SIG_SETMASK, 0x00000000, 0x00000000, 0x00000000, 0x00000000) = 
0xFFBFFEFF [0xFFFFFFFF]
      Incurred fault #5, FLTACCESS  %pc = 0x100022468
        siginfo: SIGBUS BUS_ADRALN addr=0xFFFF2F682F68772C
      Received signal #10, SIGBUS [default]
        siginfo: SIGBUS BUS_ADRALN addr=0xFFFF2F682F68772C

Trouble with vfork on SPARC: not surprising. The "sliding register window"
of the SPARC architecture is a beast to get correctly implemented in
the kernel and in setjmp/longjmp. After vfork, the parent and the child
are supposed to
   - share the memory,
   - but have distinct register sets.
In other architectures this works reasonably, because the child process
does only minimal changes to the memory contents before it exec()s.
But on SPARC, due to the register window that can cause memory writes
simply at subroutine invocation or return, this is very hairy.

   * If I force ifdef out the VFORK call in gnulib's spawni it's OK
   * If I force the use of the system posix_spawnp it's Ok. Tested with:
     ./configure gl_cv_func_posix_spawnp_secure_exec=yes --quiet && gmake -j8
     gmake TESTS=tests/install/basic-1.sh SUBDIRS=. check

Interesting... I'll take a look.

Alternatively coreutils could force gnulib not to use vfork at all

I would limit the workaround to SPARC, because of the discussion above.

Note I also get the same error on another sparc machine with Linux.
I.e cfarm220 with Debian on Niagra (UltraSparc T5),
if I force the use of gnulib's posix_spawnp like:

  ./configure gl_cv_func_posix_spawnp_secure_exec=no --quiet
  make -j $(nproc)
  make TESTS=tests/install/basic-1.sh SUBDIRS=. check

I've not had time to look into this any further today,
but might something like the following be appropriate for now at least?
The test passes with that unsurprisingly.

cheers,
Padraig

diff --git a/lib/spawni.c b/lib/spawni.cindex a1f3f84a98..d2d2f2078b 100644
--- a/lib/spawni.c
+++ b/lib/spawni.c
@@ -882,7 +882,8 @@ __spawni (pid_t *pid, const char *file,
   (void) &flags;

   /* Generate the new process.  */
-#if HAVE_VFORK
+  /* Avoid vfork on Sparc as its use has more constraints there.  */
+#if HAVE_VFORK && ! defined __sparc__ && ! defined __sparc64___
   if ((flags & POSIX_SPAWN_USEVFORK) != 0
       /* If no major work is done, allow using vfork.  Note that we
          might perform the path searching.  But this would be done by


Reply via email to