Bug 106162 - libstdc++v3: bits/largefile-config.h.tmp: No such file or directory race condition
Summary: libstdc++v3: bits/largefile-config.h.tmp: No such file or directory race cond...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: 10.5
Assignee: Jonathan Wakely
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2022-07-01 18:10 UTC by Sergei Trofimovich
Modified: 2022-07-23 17:35 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2022-07-01 00:00:00


Attachments
build.log.xz (62.58 KB, application/x-xz)
2022-07-01 18:11 UTC, Sergei Trofimovich
Details
Add missing prerequisite to generated header (598 bytes, patch)
2022-07-01 21:29 UTC, Jonathan Wakely
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2022-07-01 18:10:21 UTC
There is a race condition when (I speculate) libstdcv++v3 is built in parallel from different 'make' processes. Perhaps for c++98 | c++11 | x++17 instances?

From libstdc++-v3/include/Makefile.am:

  # This header is not installed, it's only used to build libstdc++ itself.
  ${host_builddir}/largefile-config.h: ${CONFIG_HEADER}
        @rm -f $@.tmp
        @-grep 'define _DARWIN_USE_64_BIT_INODE' ${CONFIG_HEADER} >> $@.tmp
        @-grep 'define _FILE_OFFSET_BITS' ${CONFIG_HEADER} >> $@.tmp
        @-grep 'define _LARGE_FILES' ${CONFIG_HEADER} >> $@.tmp
        @mv $@.tmp $@

As a result 'bits/largefile-config.h' rule gets executed in parallel and clobbers temporary file on this week's gcc-13 snapshot:

...
make[3]: Entering directory '/build/build/x86_64-w64-mingw32/libstdc++-v3'
Making all in include
make[4]: Entering directory '/build/build/x86_64-w64-mingw32/libstdc++-v3/include'
echo 1 > stamp-dual-abi
echo 1 > stamp-allocator-new
echo timestamp > stamp-pb
echo 1 > stamp-cxx11-abi
echo 0 > stamp-visibility
echo 1 > stamp-extern-template
echo 0 > stamp-namespace-version
echo 'define _GLIBCXX_USE_FLOAT128 1' > stamp-float128
/nix/store/xsq6y0yn5mbmyazn51c86kz9zkr357xj-bash-5.1-p16/bin/bash: line 1: x86_64-w64-mingw32/bits/largefile-config.h.tmp: No such file or directory
make[4]: [Makefile:1785: x86_64-w64-mingw32/bits/largefile-config.h] Error 1 (ignored) shuffle=1656692854
/nix/store/xsq6y0yn5mbmyazn51c86kz9zkr357xj-bash-5.1-p16/bin/bash: line 1: x86_64-w64-mingw32/bits/largefile-config.h.tmp: No such file or directory
make[4]: [Makefile:1786: x86_64-w64-mingw32/bits/largefile-config.h] Error 1 (ignored) shuffle=1656692854
/nix/store/xsq6y0yn5mbmyazn51c86kz9zkr357xj-bash-5.1-p16/bin/bash: line 1: x86_64-w64-mingw32/bits/largefile-config.h.tmp: No such file or directory
make[4]: [Makefile:1787: x86_64-w64-mingw32/bits/largefile-config.h] Error 1 (ignored) shuffle=1656692854
mv: cannot stat 'x86_64-w64-mingw32/bits/largefile-config.h.tmp': No such file or directory
make[4]: *** [Makefile:1788: x86_64-w64-mingw32/bits/largefile-config.h] Error 1 shuffle=1656692854
make[4]: *** Waiting for unfinished jobs....
make[4]: Leaving directory '/build/build/x86_64-w64-mingw32/libstdc++-v3/include'
make[3]: *** [Makefile:576: all-recursive] Error 1 shuffle=1656692854
make[3]: Leaving directory '/build/build/x86_64-w64-mingw32/libstdc++-v3'
make[2]: *** [Makefile:501: all] Error 2 shuffle=1656692854
make[2]: Leaving directory '/build/build/x86_64-w64-mingw32/libstdc++-v3'
make[1]: *** [Makefile:12287: all-target-libstdc++-v3] Error 2 shuffle=1656692854
make[1]: Leaving directory '/build/build'
make: *** [Makefile:1031: all] Error 2 shuffle=1656692854

Note how 'largefile-config.h.tmp: No such file or directory' is reported 3 times.

Will attach full build.log in case it makes the error cause clearer.
Comment 1 Sergei Trofimovich 2022-07-01 18:11:01 UTC
Created attachment 53235 [details]
build.log.xz
Comment 2 Jonathan Wakely 2022-07-01 20:49:26 UTC
(In reply to Sergei Trofimovich from comment #0)
> There is a race condition when (I speculate) libstdcv++v3 is built in
> parallel from different 'make' processes. Perhaps for c++98 | c++11 | x++17
> instances?

There are no such instances. It is built separately for each multilib, but each of those has its own $host_builddir

> 
> From libstdc++-v3/include/Makefile.am:
> 
>   # This header is not installed, it's only used to build libstdc++ itself.
>   ${host_builddir}/largefile-config.h: ${CONFIG_HEADER}
>         @rm -f $@.tmp
>         @-grep 'define _DARWIN_USE_64_BIT_INODE' ${CONFIG_HEADER} >> $@.tmp
>         @-grep 'define _FILE_OFFSET_BITS' ${CONFIG_HEADER} >> $@.tmp
>         @-grep 'define _LARGE_FILES' ${CONFIG_HEADER} >> $@.tmp
>         @mv $@.tmp $@
> 
> As a result 'bits/largefile-config.h' rule gets executed in parallel and

I don't see how that's possible. It's a prerequisite of c++config.h which is built once per multilib, and parallel make processes will coordinate to only build the prereq once.

Are you 100% sure you didn't actually run multiple make processes yourself, e.g by using & instead of && in a shell command?
Comment 3 Jonathan Wakely 2022-07-01 20:51:09 UTC
I think the errors are actually saying the directory doesn't exist, and are coming from the three shell commands that redirect to that rule using >> $@.tmp
Comment 4 Jonathan Wakely 2022-07-01 20:54:00 UTC
The header target is missing a prerequisite of stamp-${host_alias}
Comment 5 Jonathan Wakely 2022-07-01 21:29:57 UTC
Created attachment 53236 [details]
Add missing prerequisite to generated header

I'm testing this.
Comment 6 Sergei Trofimovich 2022-07-01 21:40:00 UTC
(In reply to Jonathan Wakely from comment #2)
> (In reply to Sergei Trofimovich from comment #0)
> > There is a race condition when (I speculate) libstdcv++v3 is built in
> > parallel from different 'make' processes. Perhaps for c++98 | c++11 | x++17
> > instances?
> 
> There are no such instances. It is built separately for each multilib, but
> each of those has its own $host_builddir

Aha, TIL!

> Are you 100% sure you didn't actually run multiple make processes yourself,
> e.g by using & instead of && in a shell command?

I was running it from a standard build script. Should be just 'make -j16 -l16' (with a small caveat: make is built with --shuffle support to reorder what what is allowed to expose missing depends: https://savannah.gnu.org/bugs/index.php?62100).

(In reply to Jonathan Wakely from comment #5)
> Created attachment 53236 [details]
> Add missing prerequisite to generated header
> 
> I'm testing this.

Thank you! I'll also give it a go locally and will complain if it fails in a similar way.
Comment 7 GCC Commits 2022-07-01 21:43:01 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:8a6ee426c2be3bd4359520e02c00ec60cac2fece

commit r13-1400-g8a6ee426c2be3bd4359520e02c00ec60cac2fece
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jul 1 22:23:43 2022 +0100

    libstdc++: Add missing prerequisite to generated header [PR106162]
    
    The ${host_builddir}/largefile-config.h header can't be written until
    its parent directory has been created, so it needs to have the creation
    of that directory as a prerequisite.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/106162
            * include/Makefile.am (largefile-config.h): Add
            stamp-${host_alias} prerequisite.
            * include/Makefile.in: Regenerate.
Comment 8 Jonathan Wakely 2022-07-01 21:43:34 UTC
Fixed on trunk, but worth backporting to all branches.
Comment 9 GCC Commits 2022-07-07 20:39:46 UTC
The releases/gcc-12 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:ce5b1c3b95f7136c963d31673ca83f7392c40a53

commit r12-8556-gce5b1c3b95f7136c963d31673ca83f7392c40a53
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jul 1 22:23:43 2022 +0100

    libstdc++: Add missing prerequisite to generated header [PR106162]
    
    The ${host_builddir}/largefile-config.h header can't be written until
    its parent directory has been created, so it needs to have the creation
    of that directory as a prerequisite.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/106162
            * include/Makefile.am (largefile-config.h): Add
            stamp-${host_alias} prerequisite.
            * include/Makefile.in: Regenerate.
    
    (cherry picked from commit 8a6ee426c2be3bd4359520e02c00ec60cac2fece)
Comment 10 GCC Commits 2022-07-07 23:33:57 UTC
The releases/gcc-11 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:92f43710bbe5e861d90681ef4691c37b8c70aec6

commit r11-10138-g92f43710bbe5e861d90681ef4691c37b8c70aec6
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jul 1 22:23:43 2022 +0100

    libstdc++: Add missing prerequisite to generated header [PR106162]
    
    The ${host_builddir}/largefile-config.h header can't be written until
    its parent directory has been created, so it needs to have the creation
    of that directory as a prerequisite.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/106162
            * include/Makefile.am (largefile-config.h): Add
            stamp-${host_alias} prerequisite.
            * include/Makefile.in: Regenerate.
    
    (cherry picked from commit 8a6ee426c2be3bd4359520e02c00ec60cac2fece)
Comment 11 Jonathan Wakely 2022-07-07 23:37:42 UTC
Fixed for 11.4 and 12.2
Comment 12 GCC Commits 2022-07-23 11:30:15 UTC
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:01c25003d2a21d199df22548c2c8a8110e755dc7

commit r10-10911-g01c25003d2a21d199df22548c2c8a8110e755dc7
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Fri Jul 1 22:23:43 2022 +0100

    libstdc++: Add missing prerequisite to generated header [PR106162]
    
    The ${host_builddir}/largefile-config.h header can't be written until
    its parent directory has been created, so it needs to have the creation
    of that directory as a prerequisite.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/106162
            * include/Makefile.am (largefile-config.h): Add
            stamp-${host_alias} prerequisite.
            * include/Makefile.in: Regenerate.
    
    (cherry picked from commit 8a6ee426c2be3bd4359520e02c00ec60cac2fece)
Comment 13 Jonathan Wakely 2022-07-23 17:35:24 UTC
Fixed in all active branches now.