Bug 106102 - gcc/cp/mapper-resolver.cc fails to build against musl: musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
Summary: gcc/cp/mapper-resolver.cc fails to build against musl: musl-1.2.3-dev/include...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: 12.2
Assignee: Sergei Trofimovich
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-06-27 10:05 UTC by Sergei Trofimovich
Modified: 2022-07-02 15:30 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2022-06-27 10:05:36 UTC
For build errors like 'error: attempt to use poisoned "calloc"': is it a gcc bug or libc bug?

At least on musl libc gcc marks calloc() as '#pragma GCC poison' but later stumbles on '#define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))' from musl's own sched.h.

Here is an example failure on this week's gcc:

/build/build/./prev-gcc/xg++ -B/build/build/./prev-gcc/ -B/<<NIX>>/gcc-13.0.0/x86_64-unknown-linux-musl/bin/ -nostdinc++ -B/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/src/.libs -B/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/libsupc++/.libs  -I/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl  -I/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include  -I/build/gcc-13-20220626/libstdc++-v3/libsupc++ -L/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/src/.libs -L/build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/libsupc++/.libs  -fno-PIE -c  -DIN_GCC_FRONTEND -O2 -I/<<NIX>>/musl-1.2.3-dev/include -B/<<NIX>>/musl-1.2.3/lib/ -idirafter /<<NIX>>/musl-1.2.3-dev/include -idirafter /<<NIX>>/bootstrap-tools/lib/gcc/x86_64-unknown-linux-musl/7.3.0/include-fixed -Wl,-rpath,/<<NIX>>/gcc-13.0.0-lib/lib -Wl,-L/<<NIX>>/musl-1.2.3/lib -Wl,-rpath -Wl,/<<NIX>>/musl-1.2.3/lib -Wl,-dynamic-linker=/<<NIX>>/musl-1.2.3/lib/ld-musl-x86_64.so.1 -fno-checking -gtoggle -DIN_GCC     -fno-exceptions -fno-rtti -fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -Werror -fno-common  -DHAVE_CONFIG_H -I. -Icp -I../../gcc-13-20220626/gcc -I../../gcc-13-20220626/gcc/cp -I../../gcc-13-20220626/gcc/../include -I../../gcc-13-20220626/gcc/../libcpp/include -I../../gcc-13-20220626/gcc/../libcody -I/<<NIX>>/gmp-with-cxx-6.2.1-dev/include -I/<<NIX>>/mpfr-4.1.0-dev/include -I/<<NIX>>/libmpc-1.2.1/include  -I../../gcc-13-20220626/gcc/../libdecnumber -I../../gcc-13-20220626/gcc/../libdecnumber/bid -I../libdecnumber -I../../gcc-13-20220626/gcc/../libbacktrace -I/<<NIX>>/isl-0.20/include  -o cp/mapper-resolver.o -MT cp/mapper-resolver.o -MMD -MP -MF cp/.deps/mapper-resolver.TPo ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc
In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr-default.h:35,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr.h:148,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/ext/atomicity.h:35,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/bits/shared_ptr_base.h:61,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/bits/shared_ptr.h:53,
                 from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/memory:77,
                 from ../../gcc-13-20220626/gcc/../libcody/cody.hh:24,
                 from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.h:25,
                 from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.cc:23,
                 from ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc:32:
/<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
   84 | void *calloc(size_t, size_t);
      |       ^
/<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
  124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
      |                                    ^
make[3]: *** [Makefile:1143: cp/mapper-resolver.o] Error 1
make[3]: *** Waiting for unfinished jobs....
rm fsf-funding.pod lto-dump.pod gfdl.pod gpl.pod cpp.pod gcc.pod gcov-tool.pod gcov.pod gcov-dump.pod
make[3]: Leaving directory '/build/build/gcc'
make[2]: *** [Makefile:5000: all-stage2-gcc] Error 2
make[2]: Leaving directory '/build/build'
make[1]: *** [Makefile:24628: stage2-bubble] Error 2
make[1]: Leaving directory '/build/build'
make: *** [Makefile:24840: bootstrap] Error 2

gcc is configured as:

./configure --prefix=/<<NIX>>/gcc-13.0.0 --with-gmp-include=/<<NIX>>/gmp-with-cxx-6.2.1-dev/include --with-gmp-lib=/<<NIX>>/gmp-with-cxx-6.2.1/lib --with-mpfr-include=/<<NIX>>/mpfr-4.1.0-dev/include --with-mpfr-lib=/<<NIX>>/mpfr-4.1.0/lib --with-mpc=/<<NIX>>/libmpc-1.2.1 --with-libelf=/<<NIX>>/libelf-0.8.13 --with-native-system-header-dir=/<<NIX>>/musl-1.2.3-dev/include --program-prefix= --enable-lto --disable-libstdcxx-pch --without-included-gettext --with-system-zlib --enable-static --enable-languages=c\,c++ --disable-multilib --enable-plugin --with-isl=/<<NIX>>/isl-0.20 --disable-libmpx --disable-libsanitizer --disable-symvers libat_cv_have_ifunc=no --disable-gnu-indirect-function --build=x86_64-unknown-linux-musl --host=x86_64-unknown-linux-musl --target=x86_64-unknown-linux-musl
Comment 1 Sam James 2022-06-27 10:10:51 UTC
See also bug 104799.
Comment 2 Richard Biener 2022-06-27 10:51:47 UTC
The failure can only happen if system headers are included after gcc posioning. All system headers need to be included from system.h for this reason.

I think gcc/cp/mapper-resolver.cc needs to arrange the ../../c++tools/resolver.cc code from not including anything.
Comment 3 Sergei Trofimovich 2022-06-27 12:03:56 UTC
Aha, that makes sense.

In this case include chain is:
- c++tools/resolver.cc
 -> c++tools/resolver.h
  -> libcody/cody.hh
    -> libstdc++-v3/include/memory
      -> libstdc++-v3/include/bits/shared_ptr.h
        -> ...
          -> libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr-default.h
           -> musl-1.2.3-dev/include/pthread.h
             -> musl-1.2.3-dev/include/sched.h [uses calloc()]

AFAIU libstdc++-v3/include are all user-facing libraries and are expected to include system headers like <pthread.h>.

It's a bit worrying that resolver.cc depends on <pthread.h> in such an indirect way.

Would it be fair to say "system.h" needs to include <memory> for this case and be done with it?

Does gcc do any system header wrapping by chance to minimize such leaks? I'm only asking because I noticed musl has different include order from glibc: https://github.com/NixOS/nixpkgs/issues/142066#issuecomment-1159568114. I tried to make include order alone closer to glibc and it did not fix the issue.
Comment 4 Sergei Trofimovich 2022-06-27 14:50:48 UTC
Posted my naive attempt: https://gcc.gnu.org/pipermail/gcc-patches/2022-June/597353.html
Comment 5 GCC Commits 2022-06-27 22:22:38 UTC
The master branch has been updated by Sergei Trofimovich <slyfox@gcc.gnu.org>:

https://gcc.gnu.org/g:3b21c21f3f5726823e19728fdd1571a14aae0fb3

commit r13-1311-g3b21c21f3f5726823e19728fdd1571a14aae0fb3
Author: Sergei Trofimovich <siarheit@google.com>
Date:   Mon Jun 27 13:27:24 2022 +0100

    c++: avoid <memory> poisoning on musl [PR106102]
    
    On musl <pthread.h> uses calloc() (via <sched.h>). <memory> includes
    it indirectly and exposes use of poisoned calloc() when module code
    is built:
    
        /build/build/./prev-gcc/xg++ ... ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc
            In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
                     from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr-default.h:35,
                     ....
                     from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/memory:77,
                     from ../../gcc-13-20220626/gcc/../libcody/cody.hh:24,
                     from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.h:25,
                     from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.cc:23,
                     from ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc:32:
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
           84 | void *calloc(size_t, size_t);
              |       ^
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
          124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
              |                                    ^
    
    gcc/cp/
    
            PR c++/106102
            * mapper-client.cc: Include <memory> via "system.h".
            * mapper-resolver.cc: Ditto.
            * module.cc: Ditto.
    
    libcc1/
    
            PR c++/106102
            * libcc1plugin.cc: Include <memory> via "system.h".
            * libcp1plugin.cc: Ditto.
Comment 6 Sergei Trofimovich 2022-06-27 23:00:26 UTC
Also found a closely related jit build failure, but there <pthread.h> is used directly.

Proposed the change to move <pthread.h> before poisoning step as: https://gcc.gnu.org/pipermail/gcc-patches/2022-June/597379.html
Comment 7 GCC Commits 2022-06-29 18:17:24 UTC
The master branch has been updated by Sergei Trofimovich <slyfox@gcc.gnu.org>:

https://gcc.gnu.org/g:49d508065bdd36fb1a9b6aad9666b1edb5e06474

commit r13-1350-g49d508065bdd36fb1a9b6aad9666b1edb5e06474
Author: Sergei Trofimovich <siarheit@google.com>
Date:   Mon Jun 27 23:42:44 2022 +0100

    jit: avoid calloc() poisoning on musl [PR106102]
    
    On musl <pthread.h> uses calloc() (via <sched.h>). jit/ includes
    it directly and exposes use of poisoned calloc():
    
        /build/build/./prev-gcc/xg++ ... ../../gcc-13-20220626/gcc/jit/jit-playback.cc
        make[3]: *** [Makefile:1143: jit/libgccjit.o] Error 1
        make[3]: *** Waiting for unfinished jobs....
        In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
                         from ../../gcc-13-20220626/gcc/jit/jit-playback.cc:44:
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
           84 | void *calloc(size_t, size_t);
              |       ^
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
          124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
              |                                    ^
    
    The change moves <pthread.h> inclusion to "system.h" under new
    INCLUDE_PTHREAD_H guard and uses this mechanism in libgccjit.
    
    gcc/
    
            PR c++/106102
            * system.h: Introduce INCLUDE_PTHREAD_H macros to include <pthread.h>.
    
    gcc/jit/
    
            PR c++/106102
            * jit-playback.cc: Include <pthread.h> via "system.h" to avoid calloc()
            poisoning.
            * jit-recording.cc: Ditto.
            * libgccjit.cc: Ditto.
Comment 8 GCC Commits 2022-07-02 15:22:11 UTC
The releases/gcc-12 branch has been updated by Sergei Trofimovich <slyfox@gcc.gnu.org>:

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

commit r12-8539-gde6f402a54f7e6a3f8a79d723a25724e6274cc3e
Author: Sergei Trofimovich <siarheit@google.com>
Date:   Mon Jun 27 13:27:24 2022 +0100

    c++: avoid <memory> poisoning on musl [PR106102]
    
    On musl <pthread.h> uses calloc() (via <sched.h>). <memory> includes
    it indirectly and exposes use of poisoned calloc() when module code
    is built:
    
        /build/build/./prev-gcc/xg++ ... ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc
            In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
                     from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/x86_64-unknown-linux-musl/bits/gthr-default.h:35,
                     ....
                     from /build/build/prev-x86_64-unknown-linux-musl/libstdc++-v3/include/memory:77,
                     from ../../gcc-13-20220626/gcc/../libcody/cody.hh:24,
                     from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.h:25,
                     from ../../gcc-13-20220626/gcc/cp/../../c++tools/resolver.cc:23,
                     from ../../gcc-13-20220626/gcc/cp/mapper-resolver.cc:32:
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
           84 | void *calloc(size_t, size_t);
              |       ^
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
          124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
              |                                    ^
    
    gcc/cp/
    
            PR c++/106102
            * mapper-client.cc: Include <memory> via "system.h".
            * mapper-resolver.cc: Ditto.
            * module.cc: Ditto.
    
    libcc1/
    
            PR c++/106102
            * libcc1plugin.cc: Include <memory> via "system.h".
            * libcp1plugin.cc: Ditto.
    
    (cherry picked from commit 3b21c21f3f5726823e19728fdd1571a14aae0fb3)
Comment 9 GCC Commits 2022-07-02 15:22:16 UTC
The releases/gcc-12 branch has been updated by Sergei Trofimovich <slyfox@gcc.gnu.org>:

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

commit r12-8540-gad5d760b815b3d491bdb5d97f6e053d60d6991b9
Author: Sergei Trofimovich <siarheit@google.com>
Date:   Mon Jun 27 23:42:44 2022 +0100

    jit: avoid calloc() poisoning on musl [PR106102]
    
    On musl <pthread.h> uses calloc() (via <sched.h>). jit/ includes
    it directly and exposes use of poisoned calloc():
    
        /build/build/./prev-gcc/xg++ ... ../../gcc-13-20220626/gcc/jit/jit-playback.cc
        make[3]: *** [Makefile:1143: jit/libgccjit.o] Error 1
        make[3]: *** Waiting for unfinished jobs....
        In file included from /<<NIX>>/musl-1.2.3-dev/include/pthread.h:30,
                         from ../../gcc-13-20220626/gcc/jit/jit-playback.cc:44:
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:84:7: error: attempt to use poisoned "calloc"
           84 | void *calloc(size_t, size_t);
              |       ^
        /<<NIX>>/musl-1.2.3-dev/include/sched.h:124:36: error: attempt to use poisoned "calloc"
          124 | #define CPU_ALLOC(n) ((cpu_set_t *)calloc(1,CPU_ALLOC_SIZE(n)))
              |                                    ^
    
    The change moves <pthread.h> inclusion to "system.h" under new
    INCLUDE_PTHREAD_H guard and uses this mechanism in libgccjit.
    
    gcc/
    
            PR c++/106102
            * system.h: Introduce INCLUDE_PTHREAD_H macros to include <pthread.h>.
    
    gcc/jit/
    
            PR c++/106102
            * jit-playback.cc: Include <pthread.h> via "system.h" to avoid calloc()
            poisoning.
            * jit-recording.cc: Ditto.
            * libgccjit.cc: Ditto.
    
    (cherry picked from commit 49d508065bdd36fb1a9b6aad9666b1edb5e06474)
Comment 10 Sergei Trofimovich 2022-07-02 15:26:36 UTC
Pulled fixes as is to gcc-12.

Not going to pull it in to gcc-11 and lower as it depends on larger headers reshuffle like commit b8f7ff76d6f0b7fdffc314a19425423606b5e296.