Search code examples
gnu-makebazaar

Gnu Make different exit status from script and shell


Basic code:

def make_check(local, master, old_revno, old_revid, future_revno, future_revid,
    tree_delta, future_tree):
    try:
        check_call('make check', shell=True)
    except CalledProcessError as e:
        raise BzrError(e)

Result: bzr: ERROR: Command 'make check' returned non-zero exit status 2

I have a Makefile that includes a "check" target which among other things runs some scripts to check that all the source code has valid syntax.

If I run make check from the console, it exists with a status of 0.

If I run make check from a pre-commit hook in Bazaar, it exists with a status of 2.

I've investigated with some depth including checking environment variables (essentially the same) and running strace against both methods.

In both cases, the output from the scripts is the same, but in the case of the precommit hook, the exit status is 2 without any explanation I can discern since the last process it called on had an exit status of zero and no other external system calls. Is there something I'm overlooking, or perhaps some chance of an internal bug in make?

Console

16436 execve("/usr/bin/make", ["make", "check"], [/* 22 vars */]) = 0
#Big snip
16947 execve("/bin/sh", ["/bin/sh", "-c", "find archive/rpm/6 -name '*.rpm' -printf '%f\\n' | rev | cut -d- -f3- | rev | sort | uniq -c | grep -v '^ *1 ' &&  \\\n{ echo \"ERROR: Found duplicate RPMs in archive.\"; exit 1; } || true"], [/* 35 vars */]) = 0
#Big snip
16948 exit_group(0)                     = ?
16947 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16949
16947 --- SIGCHLD (Child exited) @ 0 (0) ---
16947 rt_sigreturn(0x11)                = 16949
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16948
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16950
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16951
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16952
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16953
16947 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 16954
16947 exit_group(0)                     = ?
16436 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 16947
16436 --- SIGCHLD (Child exited) @ 0 (0) ---
16436 rt_sigreturn(0xffffffff)          = 16947
16436 rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT TERM XCPU XFSZ], NULL, 8) = 0
16436 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
16436 chdir("/code/n/branches/jeff")    = 0
16436 close(1)                          = 0
16436 munmap(0x7f7ed780e000, 4096)      = 0
16436 exit_group(0)

Script

14001 execve("/usr/bin/make", ["make", "check"], [/* 21 vars */]) = 0
#Big snip
14525 execve("/bin/sh", ["/bin/sh", "-c", "find archive/rpm/6 -name '*.rpm' -printf '%f\\n' | rev | cut -d- -f3- | rev | sort | uniq -c | grep -v '^ *1 ' &&  \\\n{ echo \"ERROR: Found duplicate RPMs in archive.\"; exit 1; } || true"], [/* 34 vars */]) = 0
#Big snip
14526 exit_group(0)                     = ?
14525 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14527
14525 --- SIGCHLD (Child exited) @ 0 (0) ---
14525 rt_sigreturn(0x11)                = 14527
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14526
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14528
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14529
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14530
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14531
14525 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 14532
14525 exit_group(0)                     = ?
14001 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 14525
14001 --- SIGCHLD (Child exited) @ 0 (0) ---
14001 rt_sigreturn(0xffffffff)          = 14525
14001 rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT TERM XCPU], NULL, 8) = 0
14001 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
14001 chdir("/code/n/branches/jeff")    = 0
14001 close(1)                          = 0
14001 munmap(0x7f064aa7b000, 4096)      = 0
14001 exit_group(2)                     = ?

Update

I appended the following targets to my Makefile:

.PHONY: foobar

foobar:
        echo "Testing foobar"

This target also causes the make process to exit with an error status of 2 when called through the pre-commit hook script while still succeeding with a manual execution.


Solution

  • This was essentially a Makefile Inception issue. bzr launched make which included lots of Makefiles, some of which were built, one of which depended on a bzr command that couldn't get a lock because another bzr process held it. Since it was kicked off from an include and had a FORCE setting on it, it would always cause a failure for any target when run from bzr, but wasn't obvious because it didn't stop the make command like most errors do.