[Bug driver/44049] New: Empty dependencies left may cause invalid builds

eric dot estievenart at free dot fr gcc-bugzilla@gcc.gnu.org
Sun May 9 17:24:00 GMT 2010


Gcc lefts empty dependency files around if
the preprocessor exits with an error.
In some cases, when used in conjunction with gnu make,
(and probably other tools), this can lead to inconsistent
builds.
The following shows a build succeeding where it should have failed,
thus potentially resulting to an invalid executable (or whatever).

Consider the following legitimate (GNU) makefile:
------- Makefile ---------
all: x.o

x.d:    # Generate dependency file
        gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null

x.o:    # and compile
        gcc -c x.c

include x.d   # Include dep file, to have it generated and used
-------- end of Makefile ---------

-------- x.c -------------
#include "myheader.h"
-------- end of x.c ------------

-------- myheader.h (empty) -----------
-------- end of myheader.h -----------

Now run the following commands:
$ make
Makefile:8: x.d: No such file or directory       # OK, expected (could have
used -include to avoid the warning)
gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null  # Make builds x.d before
including it
gcc -c x.c                                       # And compiles x.c without
error

$ rm myheader.h      # just say the file was moved...
$ rm x.d             # someone suspected a problem with the dependencies
$ make
Makefile:8: x.d: No such file or directory       # OK, expected as previously
gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null
x.c:1:22: error: myheader.h: No such file or directory  # OK, expected
make: *** [x.d] Error 1                                 # OK, gcc returned
non-zero

$ ls -l x.d
-rw-r--r-- 1 steve steve 0  9 mai   18:19 x.d    # BAD: Strange 0-sized file !!

$ make
make: Nothing to be done for `all'.              # ERROR: should have failed
!!!
(because make included the empty x.d, and considered the previously generated
x.o as
up-to-date....)

This can be illustrated by the following script, without using make,
which I hope could easily be integrated as a unit test:
------- test.sh - exit 0 if working as expected -----
#! /bin/sh

# setup files: x.c includes iexist.h
rm x.* # cleanup
echo "#include \"myheader.h\"" > x.c
rm -f myheader.h

# gcc must exit non-zero
gcc -E x.c -MP -MMD -MF x.d -MT x.o > /dev/null
if [ "$?" -eq "0" ]; then
  echo "failed(1): gcc should have exited non-zero"
  exit 1;
fi
# but x.d must not exist
if test -f x.d; then
  ls -l x.d
  echo "failed(2): x.d should not exist"; exit 2
fi
echo "test passed"; exit 0 # ok
---------- end of test.sh ---------------------

Illustration:
$ ./test.sh
x.c:1:22: error: myheader.h: No such file or directory
-rw-r--r-- 1 steve steve 0  9 mai   18:57 x.d
failed(2): x.d should not exist


========== Additional notes ============
This is related to following bugs:
#9517 (fixed) states that if the compiler fails,
  the .d file should not be deleted if the .o file is kept.
  (In that case the error was triggered by the compiler, not the preprocessor)
#35697 (enhancement) asking for .d files to be created atomically.

In the current case, we are just considering the preprocessor,
which lefts incoherent files around, even if it is not interrupted.
Solving #35697 will solve that bug, but the discussion is still open.

I will also consider filing a bug on Gnu make after investigating
a bit more its strange behaviour.

Sincerely


-- 
           Summary: Empty dependencies left may cause invalid builds
           Product: gcc
           Version: 4.4.4
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: driver
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: eric dot estievenart at free dot fr
 GCC build triplet: 4.4.4 (Debian 4.4.4-1)
  GCC host triplet: i686 debian GNU/Linux
GCC target triplet: i486-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44049



More information about the Gcc-bugs mailing list