Your message dated Mon, 11 Apr 2016 21:38:58 -0700
with message-id <87h9f78mql....@golden-gryphon.com>
and subject line Re: Bug#820658: make: filesystem timestamp race: outdated
target does not get updated if a missing dependency gets created with the same
timestamp
has caused the Debian Bug report #820658,
regarding make: filesystem timestamp race: outdated target does not get updated
if a missing dependency gets created with the same timestamp
to be marked as done.
This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.
(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact ow...@bugs.debian.org
immediately.)
--
820658: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=820658
Debian Bug Tracking System
Contact ow...@bugs.debian.org with problems
--- Begin Message ---
Package: make
Version: 3.81-8.2
Severity: grave
Justification: renders package unusable
Control: block 725629 with -1
Hi,
consider this Makefile:
----- Makefile/Makefile.in -----
all:
do_something
foo:
echo '# foo' > $@
Makefile: Makefile.in foo
cat Makfile.in foo > $@
----- -----
If 'foo' does not exist, any execution of the 'all' target should first
create 'foo' and recreate 'Makefile'. This works fine, unless foo is
created with the same timestamp as the existing Makefile.
Attached is a slightly more advanced proof-of-concept Makefile.in, run
it as
time make -f Makefile.in loop
It should run forever, but on all machines where I tried it, it
terminated after some time because Makefile was not updated:
$ time make -f Makefile.in loop
make clean
make[1]: Entering directory '/home/andreas/725629'
rm -f blah
cp Makefile.in Makefile
make[1]: Leaving directory '/home/andreas/725629'
set -x ; while make test ; do make clean ; done
+ make test
make[1]: Entering directory '/home/andreas/725629'
echo 'foobar:' >blah
echo ' @echo FOOBAR' >>blah
cat Makefile.in blah > Makefile
if ! grep -q ^foobar: Makefile ; then echo FAIL ; ls -lart
--time-style=full-iso Makefile* blah ; exit 1 ; else echo OK ; fi
OK
make[1]: Leaving directory '/home/andreas/725629'
+ make clean
make[1]: Entering directory '/home/andreas/725629'
rm -f blah
cp Makefile.in Makefile
make[1]: Leaving directory '/home/andreas/725629'
[... skipped some iterations ...]
+ make test
make[1]: Entering directory '/home/andreas/725629'
echo 'foobar:' >blah
echo ' @echo FOOBAR' >>blah
cat Makefile.in blah > Makefile
if ! grep -q ^foobar: Makefile ; then echo FAIL ; ls -lart
--time-style=full-iso Makefile* blah ; exit 1 ; else echo OK ; fi
OK
make[1]: Leaving directory '/home/andreas/725629'
+ make clean
make[1]: Entering directory '/home/andreas/725629'
rm -f blah
cp Makefile.in Makefile
make[1]: Leaving directory '/home/andreas/725629'
+ make test
make[1]: Entering directory '/home/andreas/725629'
echo 'foobar:' >blah
echo ' @echo FOOBAR' >>blah
if ! grep -q ^foobar: Makefile ; then echo FAIL ; ls -lart
--time-style=full-iso Makefile* blah ; exit 1 ; else echo OK ; fi
FAIL
-rw-r--r-- 1 andreas andreas 377 2016-04-11 03:03:37.588201637 +0200 Makefile.in
-rw-r--r-- 1 andreas andreas 22 2016-04-11 03:40:50.757214074 +0200 blah
-rw-r--r-- 1 andreas andreas 377 2016-04-11 03:40:50.757214074 +0200 Makefile
Makefile:2: recipe for target 'test' failed
make[1]: *** [test] Error 1
make[1]: Leaving directory '/home/andreas/725629'
real 0m0.152s
user 0m0.012s
sys 0m0.016s
It terminates even faster on a filesystem with one-second-resolution:
anbe@exodar:~/725629$ time make -f Makefile.in loop
make clean
make[1]: Entering directory '/home/anbe/725629'
rm -f blah
cp Makefile.in Makefile
make[1]: Leaving directory '/home/anbe/725629'
set -x ; while make test ; do make clean ; done
+ make test
make[1]: Entering directory '/home/anbe/725629'
echo 'foobar:' >blah
echo ' @echo FOOBAR' >>blah
if ! grep -q ^foobar: Makefile ; then echo FAIL ; ls -lart
--time-style=full-iso Makefile* blah ; exit 1 ; else echo OK ; fi
FAIL
-rw-r--r-- 1 anbe anbe 266 2016-04-11 02:45:46.000000000 +0200 Makefile.in.old
-rw-r--r-- 1 anbe anbe 377 2016-04-11 03:08:04.000000000 +0200 Makefile.in
-rw-r--r-- 1 anbe anbe 22 2016-04-11 03:09:25.000000000 +0200 blah
-rw-r--r-- 1 anbe anbe 377 2016-04-11 03:09:25.000000000 +0200 Makefile
Makefile:2: recipe for target 'test' failed
make[1]: *** [test] Error 1
make[1]: Leaving directory '/home/anbe/725629'
real 0m0.080s
user 0m0.000s
sys 0m0.000s
I could reproduce this on different architectures, with different
filesystems (ppc64el/ext4, hurd-i386/ext2 amd64/xfs,tmpfs) and with
the make packages from wheezy, jessie and stretch.
An example where this bug (non-deterministically) breaks the build process
on some architectures, is #725629.
Andreas
test: Makefile
if ! grep -q ^foobar: Makefile ; then echo FAIL ; ls -lart
--time-style=full-iso Makefile* blah ; exit 1 ; else echo OK ; fi
Makefile: Makefile.in blah
cat Makefile.in blah > $@
blah:
echo 'foobar:' >$@
echo ' @echo FOOBAR' >>$@
clean:
rm -f blah
cp Makefile.in Makefile
loop: Makefile
make clean
set -x ; while make test ; do make clean ; done
--- End Message ---
--- Begin Message ---
On Mon, Apr 11 2016, Andreas Beckmann wrote:
> Package: make
> Version: 3.81-8.2
> Severity: grave
> Justification: renders package unusable
> Control: block 725629 with -1
> Hi,
>
> consider this Makefile:
>
> ----- Makefile/Makefile.in -----
> all:
> do_something
> foo:
> echo '# foo' > $@
> Makefile: Makefile.in foo
> cat Makfile.in foo > $@
> ----- -----
>
> If 'foo' does not exist, any execution of the 'all' target should first
> create 'foo' and recreate 'Makefile'. This works fine, unless foo is
> created with the same timestamp as the existing Makefile.
Yes, you are running into a race condition. But this is
documented make behaviour:
Next: Reading, Prev: Overview, Up: Overview
Preparing and Running Make
==========================
The 'make' program
uses the makefile data base and the last-modification times of the files
to decide which of the files need to be updated. For each of those
files, it issues the recipes recorded in the data base.
If the timestamps are the same, then the target foo is not newer
than the target Makefile, and is thus not remade. Looking the
other way, Makefile is not out of date compared to foo, so it
does not need to be refreshed. You could easily add a delay if
you want to avoid the race condition.
manoj
--
Opportunities are usually disguised as hard work, so most people don't
recognize them.
Manoj Srivastava <sriva...@acm.org> <http://www.golden-gryphon.com/>
4096R/C5779A1C E37E 5EC5 2A01 DA25 AD20 05B6 CF48 9438 C577 9A1C
smime.p7s
Description: S/MIME cryptographic signature
--- End Message ---