help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: msys2: Resource temporarily unavailable


From: thutt
Subject: Re: msys2: Resource temporarily unavailable
Date: Thu, 28 Apr 2016 12:11:03 -0700

Paul Smith writes:
 > On Thu, 2016-04-28 at 10:36 -0700, David Boyce wrote:
 > > I think these replies are all a bit wrong. Msys2 is really just a fork of
 > > Cygwin as I understand it and these fork errors are a very well known
 > > problem (though mostly solved nowadays) in Cygwin. The very short version
 > > is that the Cygwin fork emulation has to guess where each dll will be
 > > mapped to in the child and sometimes it guesses wrong resulting a collision
 > > and one of these fork failures. In Cygwin the solution is to rebase the
 > > entire installation using a script provided (modern Cygwin installs
 > > actually do auto-rebasing so that isn't usually needed). I don't know how
 > > much of the fix has made it into msys2. If you google "Cygwin fork errors"
 > > or similar you'll see plenty of data about it.
 >
 > Thanks David.
 >
 > Just to add to that: the Cygwin port of GNU make (at least the last time
 > I checked) has a number of patches applied, etc.  So it's probably best
 > to ask about that port on the Cygwin help forums and lists first,
 > especially if it's an issue that appears to happen only there and not in
 > the other GNU make ports.
 >
 > ISTR there was some effort to reduce the changes needed but I'm not sure
 > where that effort stands right now.

 Thanks everyone.  We're fully aware of the meaning of EAGAIN, and we
 weren't actually asking what causes this failure, but rather how
 handles it.  A little experimentation on Linux with LD_PRELOAD gave
 enough information, but revealed an inconsistency in Make's
 generation of a failure, and a difference between 3.81 and 4.1.

 Consider the following simple C code:

    /* A simple program to fake a fork() error for Make.
     */
    #include <errno.h>
    #include <stdio.h>
    #include <unistd.h>

    pid_t fork(void)
    {
       printf("In my fork\n");
       errno = EAGAIN;
       return -1;
    }

And, the following simple Makefile:

    fork.so:        fork.c
            $(CC) -shared -fPIC $< -o $@


    nested-preload:
            $(MAKE) -f Makefile preload

    preload:        fork.so
            LD_PRELOAD=./fork.so $(MAKE) -f Makefile echoer

    generic:        fork.so
            (export LD_PRELOAD=./fork.so; tar --help|head -3)
            echo "****** $@ success";

    echoer:         fork.so
            ls /tmp

    indirect-failure:       fork.so
            $(MAKE) -f Makefile failure

    failure:        fork.so
            if false; then echo "False!" ; else echo "True!"; false; fi;


  nested-preload        : Expect: "Resource temporarily unavailable",
                          return code 2
  preload               : Expect: "Resource temporarily unavailable",
                          return code 2

  generic               : Expect: "Resource temporarily unavailable",
                          return code 2
  echoer                : success
  indirect-failure      : expect failure, return code 2
  failure               : expect failure, return code 2
  LD_PRELOAD make echoer: expect failure message, return code 2

  The first observation is that the handling of fork() is different in
  3.81 and 4.1.  It's not a problem, just an observation.  3.81
  doesn't show the same failures that 4.1 shows when EAGAIN is
  encountered.

  The second observation is that an error occurs related to the OS
  (such as EAGAIN) in the top-level Makefile, Gnu Make prints the
  diagnostic:

    make: fork: Resource temporarily unavailable

  And then summarily exits with return code of two.

  If the same error occurs in a nested Makefile, then Gnu Make is much
  chattier about the failure, providing a path of target failures all
  the way back up to the top level Makefile.

  Interestingly, this lack of information seems to only apply when the
  failure is induced because of an external force (such as EAGAIN)


--- >8 ------ >8 ------ >8 (cut here)

  make 3.81:

    make nested-preload
    make -f Makefile preload
    make[1]: Entering directory `/work/sources/futzing/preload'
    LD_PRELOAD=./fork.so make -f Makefile echoer
    make[2]: Entering directory `/work/sources/futzing/preload'
    ls /tmp/a
    /tmp/a
    make[2]: Leaving directory `/work/sources/futzing/preload'
    make[1]: Leaving directory `/work/sources/futzing/preload'


    make preload
    LD_PRELOAD=./fork.so make -f Makefile echoer
    make[1]: Entering directory `/work/sources/futzing/preload'
    ls /tmp/a
    /tmp/a
    make[1]: Leaving directory `/work/sources/futzing/preload'


    make generic
    (export LD_PRELOAD=./fork.so; tar --help|head -3)
    Usage: tar [OPTION...] [FILE]...
    GNU `tar' saves many files together into a single tape or disk archive, and 
can
    restore individual files from the archive.
    echo "****** generic success";
    ****** generic success


    make echoer
    ls /tmp/a
    /tmp/a


    make indirect-failure
    make -f Makefile failure
    make[1]: Entering directory `/work/sources/futzing/preload'
    if false; then echo "False!" ; else echo "True!"; false; fi;
    True!
    make[1]: *** [failure] Error 1
    make[1]: Leaving directory `/work/sources/futzing/preload'
    make: *** [indirect-failure] Error 2


    make failure
    if false; then echo "False!" ; else echo "True!"; false; fi;
    True!
    make: *** [failure] Error 1


    LD_PRELOAD=./fork.so make echoer
    ls /tmp/a
    /tmp/a
    echo $?
    0

  make 4.1

    make nested-preload
    make -f Makefile preload
    make[1]: Entering directory '/work/sources/futzing/preload'
    LD_PRELOAD=./fork.so make -f Makefile echoer
    make[2]: Entering directory '/work/sources/futzing/preload'
    ls /tmp/a
    In my fork
    make[2]: fork: Resource temporarily unavailable
    make[2]: Leaving directory '/work/sources/futzing/preload'
    Makefile:11: recipe for target 'preload' failed
    make[1]: *** [preload] Error 2
    make[1]: Leaving directory '/work/sources/futzing/preload'
    Makefile:8: recipe for target 'nested-preload' failed
    make: *** [nested-preload] Error 2


    make preload
    LD_PRELOAD=./fork.so make -f Makefile echoer
    make[1]: Entering directory '/work/sources/futzing/preload'
    ls /tmp/a
    In my fork
    make[1]: fork: Resource temporarily unavailable
    make[1]: Leaving directory '/work/sources/futzing/preload'
    Makefile:11: recipe for target 'preload' failed
    make: *** [preload] Error 2


    make generic
    (export LD_PRELOAD=./fork.so; tar --help|head -3)
    Usage: tar [OPTION...] [FILE]...
    GNU `tar' saves many files together into a single tape or disk archive, and 
can
    restore individual files from the archive.
    echo "****** generic success";
    ****** generic success


    make echoer
    ls /tmp/a
    /tmp/a


    make indirect-failure
    make -f Makefile failure
    make[1]: Entering directory '/work/sources/futzing/preload'
    if false; then echo "False!" ; else echo "True!"; false; fi;
    True!
    Makefile:24: recipe for target 'failure' failed
    make[1]: *** [failure] Error 1
    make[1]: Leaving directory '/work/sources/futzing/preload'
    Makefile:21: recipe for target 'indirect-failure' failed
    make: *** [indirect-failure] Error 2


    make failure
    if false; then echo "False!" ; else echo "True!"; false; fi;
    True!
    Makefile:24: recipe for target 'failure' failed
    make: *** [failure] Error 1

    LD_PRELOAD=./fork.so make echoer
    ls /tmp/a
    In my fork
    make: fork: Resource temporarily unavailable
    echo $?
    2

thutt
--
The sixth Sheik's sixth sick sheep died of hoof and mouth disease.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]