• Masahiro Yamada's avatar
    fixdep: check return value of printf() and putchar() · 6f9ac9f4
    Masahiro Yamada authored
    When there is not enough space on your storage device, the build will
    fail with 'No space left on device' error message.
    
    The reason is obvious from the message, so you will free up some disk
    space, then you will resume the build.
    
    However, sometimes you may still see a mysterious error message:
    
      unterminated call to function 'wildcard': missing ')'.
    
    If you run out of the disk space, fixdep may end up with generating
    incomplete .*.cmd files.
    
    For example, if the disk-full error occurs while fixdep is running
    print_dep(), the .*.cmd might be truncated like this:
    
       $(wildcard include/config/
    
    When you run 'make' next time, this broken .*.cmd will be included,
    then Make will terminate parsing since it is a wrong syntax.
    
    Once this happens, you need to run 'make clean' or delete the broken
    .*.cmd file manually.
    
    Even if you do not see any error message, the .*.cmd files after any
    error could be potentially incomplete, and unreliable. You may miss
    the re-compilation due to missing header dependency.
    
    If printf() cannot output the string for disk shortage or whatever
    reason, it returns a negative value, but currently fixdep does not
    check it at all. Consequently, fixdep *successfully* generates a
    broken .*.cmd file. Make never notices that since fixdep exits with 0,
    which means success.
    
    Given the intended usage of fixdep, it must respect the return value
    of not only malloc(), but also printf() and putchar().
    
    This seems a long-standing issue since the introduction of fixdep.
    
    In old days, Kbuild tried to provide an extra safety by letting fixdep
    output to a temporary file and renaming it after everything is done:
    
      scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
      rm -f $(depfile);                                                    \
      mv -f $(dot-target).tmp $(dot-target).cmd)
    
    It was no help to avoid the current issue; fixdep successfully created
    a truncated tmp file, which would be renamed to a .*.cmd file.
    
    This problem should be fixed by propagating the error status to the
    build system because:
    
    [1] Since commit 9c2af1c7 ("kbuild: add .DELETE_ON_ERROR special
        target"), Make will delete the target automatically on any failure
        in the recipe.
    
    [2] Since commit 392885ee ("kbuild: let fixdep directly write to
        .*.cmd files"), .*.cmd file is included only when the corresponding
        target already exists.
    Signed-off-by: default avatarMasahiro Yamada <yamada.masahiro@socionext.com>
    6f9ac9f4
fixdep.c 9.89 KB