bugmake - Bugs: bug #57022, Error 127 executing a script with...


bug #57022: Error 127 executing a script with no #!

Submitted by:  Martin Dorey <mdorey>
Submitted on:  Wed 09 Oct 2019 12:29:37 AM UTC  
Severity:  3 - Normal Item Group:  Bug
Status:  Fixed Privacy:  Public
Assigned to:  Paul D. Smith <psmith> Open/Closed:  Closed
Component Version:  4.3 Operating System:  POSIX-Based
Fixed Release:  4.3 Triage Status:  None

Add a New Comment (Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


( Jump to the original submission)

Fri 27 Dec 2019 06:44:58 AM UTC, comment #7: 

Fixed by adding a config test based on Martin's test.  Also added regression tests based on Dmitry's tests.


Paul D. Smith <psmith>
Project AdministratorIn charge of this item.
Tue 15 Oct 2019 02:33:10 AM UTC, comment #6: 

Submitted a new test features/exec which reproduces this bug.


Dmitry Goncharov <dgoncharov>
Fri 11 Oct 2019 06:09:39 PM UTC, comment #5: 

Argh, all those hours fighting autoconf to now see Dmitry had already sent a similar patch.  I see Paul didn't like the cross-compilation issue.  That was when it just looked like an ENOENT problem, which he could sensibly solve at runtime, before the ENOEXEC aspect came up.  I intended my patch to leave posix_spawn enabled in the cross-compilation case, which is perhaps more in line with Paul's forward-looking preference.  I leaked a copy of the filename because I'm really a C++ programmer, whose string literals are const.  Dmitry's use of '\0' for a char* seemed a bit odd to me.  His patch generated the right value for USE_POSIX_SPAWN in src/config.h for me on both my test systems.

(file #47652)

Martin Dorey <mdorey>
Fri 11 Oct 2019 01:25:01 AM UTC, comment #4: 

1. gmake posix_spawn's dodgy
2. fork inside posix_spawn succeeds and posix_spawn returns 0.
3. gmake skips fallback to /bin/sh because posix_spawn's return code is not enoexec.
4. posix_spawn's child proceeds to exec dodgy and fails
5. posix_spawn does not have a fallback to /bin/sh and the child exits with 127.

The reason dodgy succeeds with SHELL=/bin/bash is gmake spawning /bin/bash and passing as a parameter to /bin/bash via argv.
The reason dodgy fails with SHELL=/bin/sh is gmake treats SHELL=/bin/sh as if no shell was explicitly specified in the makefile and again spawns dodgy.

Having configure disable posix_spawn was discussed here

It is possible have gmake always spawn a shell (subject to configure test). This solution'd cause gmake spawn a shell even when no shell is needed.

Paul, what about replacing --disable-posix-spawn with --enable-posix-spawn?

regards, Dmitry

Dmitry Goncharov <dgoncharov>
Thu 10 Oct 2019 05:39:03 AM UTC, comment #3: 

> SHELL = /bin/bash


> the bug does not show up).

Good spot, thanks Denis.  I see the same.  I see a "goto slow" code path in the source when the shell isn't /bin/sh.

I don't suppose you had a chance to try my attached configure.ac patch?

Martin Dorey <mdorey>
Wed 09 Oct 2019 02:50:57 PM UTC, comment #2: 

I forgot to say that
SHELL = /bin/sh
does not work, you have to use
SHELL = /bin/bash

Denis Excoffier.

Wed 09 Oct 2019 02:40:24 PM UTC, comment #1: 

I add that if the Makefile contains the line
SHELL = /bin/bash
the behaviour of make-4.2.92 is iaw make-4.2.1 (that is the bug does not show up).

This is perhaps not enough explicit in the original bug report.

In other words, to be able to run your Makefile under make-4.2.92, you have three options:
- recompile with --disable-posix-spawn (which is not the default)
- add an appropriate 1st line to your scripts that don't start with #!
- add "SHELL = /bin/bash" as 1st line to your Makefile

Wed 09 Oct 2019 12:29:37 AM UTC, original submission:  

Here's a test case running against glibc 2.19 on 2015's Debian Jessie showing that /usr/local/bin/make, which is 4.2.92, has regressed over /usr/bin/make, which is 4.0 and (not shown) 4.2.1, in that executing a script with no #! line fails with no diagnostic more informative than "Error 127":

martind@swiftboat:~/playpen/make-2019-10-08$ cat > Makefile
all: ; ./dodgy
martind@swiftboat:~/playpen/make-2019-10-08$ cat > dodgy
martind@swiftboat:~/playpen/make-2019-10-08$ chmod +x dodgy
martind@swiftboat:~/playpen/make-2019-10-08$ make
make: *** [Makefile:1: all] Error 127
martind@swiftboat:~/playpen/make-2019-10-08$ /usr/bin/make
martind@swiftboat:~/playpen/make-2019-10-08$ strace -f make 2>&1 | grep execve
execve("/usr/local/bin/make", ["make"], [/* 209 vars */]) = 0
[pid 21223] execve("./dodgy", ["./dodgy"], [/* 212 vars */]) = -1 ENOEXEC (Exec format error)
martind@swiftboat:~/playpen/make-2019-10-08$ strace -f /usr/bin/make 2>&1 | grep execve
execve("/usr/bin/make", ["/usr/bin/make"], [/* 209 vars */]) = 0
[pid 21247] execve("./dodgy", ["./dodgy"], [/* 212 vars */]) = -1 ENOEXEC (Exec format error)
[pid 21247] execve("/bin/sh", ["/bin/sh", "./dodgy"], [/* 212 vars */]) = 0

ltrace -f showed I was using posix_spawn.


make: *** [Makefile:1: all] Error 127

... is the same obtuse error message as Paul reported as applying not just to old libc but also to Mac OS in a bug-make email thread regarding ENOENT rather than ENOEXEC:

Handling posix_spawn for non-existent binaries

I foolishly reanimated the issue today on the still older thread:

ENOEXEC from exec*() functions...?

The Make source moved on since both of those threads under:

[SV 56834] Support local PATH search with posix_spawnp

... in that we now just use posix_spawn rather than posix_spawnp and Paul added a call to findprog-in, which is perhaps why I can no longer reproduce his ENOENT problem.  Paul also added ENOEXEC handling, but that doesn't work when the failures are asynchronously notified, which I've now found was addressed in glibc 2.24 under:

posix_spawn does not return correctly upon failure to execute

That's the version shipped with 2017's Debian Stretch, currently "oldstable", so you have to be quite out of date to see the problem on Linux.

So I did:

./configure --disable-posix-spawn
make -j8 MAKE_CFLAGS=

MAKE_CFLAGS= is Paul's recommendation in README.git to get round -Wformat-signedness -Wduplicated-cond not being supported and:

src/job.c:2267:7: error: variable ‘fderr’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]

... then I'm good.  I've contrived a patch for the configury which seemed to .  It's my first non-trivial autotools code, so it's probably cargo cult nonsense.  The test would better reveal the intention if it explicitly looked for ENOEXEC, but that would be a little more code.

Martin Dorey <mdorey>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Attached Files
file #47652:  dmitry.patch added by mdorey (1KiB - text/x-patch)


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by psmith (Posted a comment)
  • -email is unavailable- added by dgoncharov (Posted a comment)
  • -email is unavailable- added by mdorey (Submitted the item)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.




    Follow 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-12-27 psmith StatusNone => Fixed
        Assigned toNone => psmith
        Open/ClosedOpen => Closed
        Fixed ReleaseNone => 4.3
    2019-10-11 mdorey Attached File- => Added dmitry.patch, #47652
    2019-10-09 mdorey Attached File- => Added automatically-disable-posix-spawn.patch, #47629

    Back to the top

    Powered by Savane 3.7