为 Linux 构建 Glibc 2.33 导致单元测试失败

Building Glibc 2.33 for Linux results in unit test failures

我目前正在尝试创建 Glibc 2.33 的构建以与默认系统版本并行,但构建过程导致大量单元测试失败。虽然有些失败可以安全地忽略,但大多数看起来像是 legitimate 问题,但我不确定如何修复它们。所需的最终目标系统是 CentOS 7.9,但我目前正在 Ubuntu Desktop 21.04 中测试构建步骤(在 VMware 15 VM) 因为 CentOS 7.9 需要创建一个 bootstrap 工具链(默认工具链太旧)。根据 Glibc 2.33 文档,不再需要 --enable-add-ons 选项(甚至可能不受支持),所以我不确定我可以执行哪些步骤或配置选项不见了。

创建构建 VM 所遵循的步骤

  1. 创建一个“干净”的最小化 Ubuntu 桌面 21.04 VM 安装
  2. 完全更新虚拟机
  3. 安装以下软件包

生成系统的软件版本

Glibc 2.33 构建步骤:

  1. 下载Glibc 2.33源代码

     wget https://ftp.gnu.org/gnu/glibc/glibc-2.33.tar.gz -P ${HOME}/Downloads
    
  2. 创建目录

     rm -rf ${HOME}/Projects/BuildToolchain && mkdir -p ${HOME}/Projects/BuildToolchain/Build
    
  3. 提取Glibc 2.33源代码

     tar -xf ${HOME}/Downloads/glibc-2.33.tar.gz -C ${HOME}/Projects/BuildToolchain
    
  4. 进入(源外)构建目录

     cd ${HOME}/Projects/BuildToolchain/Build
    
  5. 配置Glibc 2.33

     ../glibc-2.33/configure --prefix=${HOME}/Projects/BuildToolchain/Install 2>&1 | tee output-configure.txt
    
  6. 编译 Glibc 2.33

     make -j`nproc` 2>&1 | tee output-make.txt
    
  7. 构建和运行单元测试

     make check 2>&1 | tee output-make-check.txt
    

单元测试结果

以上步骤得到以下单元测试结果,包括 149 个失败的测试。

FAIL: debug/tst-backtrace2
FAIL: debug/tst-backtrace3
FAIL: debug/tst-backtrace4
FAIL: debug/tst-backtrace5
FAIL: debug/tst-backtrace6
FAIL: dlfcn/bug-atexit3
FAIL: elf/check-abi-libc
UNSUPPORTED: elf/tst-audit10
UNSUPPORTED: elf/tst-avx512
UNSUPPORTED: elf/tst-cet-legacy-8
UNSUPPORTED: elf/tst-cet-property-2
FAIL: elf/tst-cpu-features-cpuinfo
FAIL: elf/tst-glibc-hwcaps-prepend-cache
FAIL: elf/tst-ldconfig-ld_so_conf-update
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
FAIL: elf/tst-unwind-main
FAIL: iconv/tst-iconv-mt
FAIL: malloc/tst-malloc-stats-cancellation
FAIL: malloc/tst-malloc-stats-cancellation-mcheck
UNSUPPORTED: math/test-double-libmvec-sincos-avx512
UNSUPPORTED: math/test-float-libmvec-sincosf-avx512
FAIL: misc/tst-gettid-kill
UNSUPPORTED: misc/tst-pkey
FAIL: misc/tst-sigcontext-get_pc
UNSUPPORTED: nptl/test-cond-printers
UNSUPPORTED: nptl/test-condattr-printers
UNSUPPORTED: nptl/test-mutex-printers
UNSUPPORTED: nptl/test-mutexattr-printers
UNSUPPORTED: nptl/test-rwlock-printers
UNSUPPORTED: nptl/test-rwlockattr-printers
FAIL: nptl/tst-basic3
FAIL: nptl/tst-basic4
FAIL: nptl/tst-call-once
FAIL: nptl/tst-cancel-self
FAIL: nptl/tst-cancel-self-cancelstate
FAIL: nptl/tst-cancel-self-canceltype
FAIL: nptl/tst-cancel-self-testcancel
FAIL: nptl/tst-cancel1
FAIL: nptl/tst-cancel10
FAIL: nptl/tst-cancel11
FAIL: nptl/tst-cancel12
FAIL: nptl/tst-cancel13
FAIL: nptl/tst-cancel14
FAIL: nptl/tst-cancel15
FAIL: nptl/tst-cancel16
FAIL: nptl/tst-cancel17
FAIL: nptl/tst-cancel18
FAIL: nptl/tst-cancel2
FAIL: nptl/tst-cancel20
FAIL: nptl/tst-cancel21
FAIL: nptl/tst-cancel22
FAIL: nptl/tst-cancel23
FAIL: nptl/tst-cancel24
FAIL: nptl/tst-cancel25
FAIL: nptl/tst-cancel28
FAIL: nptl/tst-cancel3
FAIL: nptl/tst-cancel4
FAIL: nptl/tst-cancel4_1
FAIL: nptl/tst-cancel4_2
FAIL: nptl/tst-cancel5
FAIL: nptl/tst-cancel6
FAIL: nptl/tst-cancel7
FAIL: nptl/tst-cancel8
FAIL: nptl/tst-cancel9
FAIL: nptl/tst-cancelx10
FAIL: nptl/tst-cancelx11
FAIL: nptl/tst-cancelx12
FAIL: nptl/tst-cancelx13
FAIL: nptl/tst-cancelx14
FAIL: nptl/tst-cancelx15
FAIL: nptl/tst-cancelx16
FAIL: nptl/tst-cancelx17
FAIL: nptl/tst-cancelx18
FAIL: nptl/tst-cancelx2
FAIL: nptl/tst-cancelx20
FAIL: nptl/tst-cancelx21
FAIL: nptl/tst-cancelx3
FAIL: nptl/tst-cancelx4
FAIL: nptl/tst-cancelx5
FAIL: nptl/tst-cancelx6
FAIL: nptl/tst-cancelx7
FAIL: nptl/tst-cancelx8
FAIL: nptl/tst-cancelx9
FAIL: nptl/tst-cleanup0
FAIL: nptl/tst-cleanup0-cmp
FAIL: nptl/tst-cleanup1
FAIL: nptl/tst-cleanup3
FAIL: nptl/tst-cleanup4
FAIL: nptl/tst-cleanupx0
FAIL: nptl/tst-cleanupx1
FAIL: nptl/tst-cleanupx3
FAIL: nptl/tst-cleanupx4
FAIL: nptl/tst-cnd-basic
FAIL: nptl/tst-cnd-broadcast
FAIL: nptl/tst-cnd-timedwait
FAIL: nptl/tst-cond-except
FAIL: nptl/tst-cond22
FAIL: nptl/tst-cond25
FAIL: nptl/tst-cond7
FAIL: nptl/tst-cond8
FAIL: nptl/tst-default-attr
FAIL: nptl/tst-exec5
FAIL: nptl/tst-execstack
FAIL: nptl/tst-exit2
FAIL: nptl/tst-exit3
FAIL: nptl/tst-fini1
FAIL: nptl/tst-join1
FAIL: nptl/tst-join10
FAIL: nptl/tst-join11
FAIL: nptl/tst-join12
FAIL: nptl/tst-join13
FAIL: nptl/tst-join5
FAIL: nptl/tst-join6
FAIL: nptl/tst-join8
FAIL: nptl/tst-join9
FAIL: nptl/tst-key3
FAIL: nptl/tst-minstack-cancel
FAIL: nptl/tst-minstack-exit
FAIL: nptl/tst-minstack-throw
FAIL: nptl/tst-mtx-basic
FAIL: nptl/tst-mtx-timedlock
FAIL: nptl/tst-mtx-trylock
FAIL: nptl/tst-mutex10
FAIL: nptl/tst-mutex8
FAIL: nptl/tst-mutexpi8
FAIL: nptl/tst-once3
FAIL: nptl/tst-once4
FAIL: nptl/tst-oncex3
FAIL: nptl/tst-oncex4
FAIL: nptl/tst-robust1
FAIL: nptl/tst-robust2
FAIL: nptl/tst-robust3
FAIL: nptl/tst-robust4
FAIL: nptl/tst-robust5
FAIL: nptl/tst-robust6
FAIL: nptl/tst-robust7
FAIL: nptl/tst-robustpi1
FAIL: nptl/tst-robustpi2
FAIL: nptl/tst-robustpi3
FAIL: nptl/tst-robustpi4
FAIL: nptl/tst-robustpi5
FAIL: nptl/tst-robustpi6
FAIL: nptl/tst-robustpi7
FAIL: nptl/tst-sem11
FAIL: nptl/tst-sem12
FAIL: nptl/tst-sem16
FAIL: nptl/tst-stack4
FAIL: nptl/tst-thrd-detach
FAIL: nptl/tst-thrd-sleep
FAIL: nptl/tst-thread-exit-clobber
FAIL: nptl/tst-thread_local1
FAIL: nptl/tst-tsd5
FAIL: nptl/tst-tss-basic
FAIL: nptl/tst-unwind-thread
FAIL: nss/tst-cancel-getpwuid_r
FAIL: nss/tst-nss-files-hosts-long
UNSUPPORTED: posix/tst-cet-vfork-1
FAIL: posix/tst-getopt-cancel
UNSUPPORTED: resolv/tst-resolv-ai_idn
UNSUPPORTED: resolv/tst-resolv-ai_idn-latin1
FAIL: rt/tst-cpuclock2
FAIL: rt/tst-mqueue8
FAIL: rt/tst-mqueue8x
FAIL: rt/tst-shm-cancel
FAIL: stdlib/tst-quick_exit
FAIL: stdlib/tst-thread-quick_exit
Summary of test results:
    149 FAIL
   4202 PASS
     16 UNSUPPORTED
     17 XFAIL
      2 XPASS

Select详细的失败测试结果

报告的故障似乎都与 Glibc 2.33 测试工具中的错误和限制有关,外加一个与 VM 相关的错误。

详细的测试失败解释

elf/tst-cpu-features-cpuinfo
由于 VM 软件错误而不是因为 Glibc 2.33,此测试失败。错误日志如下所示,在 VM 中执行构建时可以忽略(尽管应该在主机上执行构建以尽量减少禁用优化的可能性)。

    [snip]
    Checking HAS_CPU_FEATURE (ERMS):
      HAS_CPU_FEATURE (ERMS): 1
      cpuinfo (erms): 0
     *** failure ***
    [snip]
    1 differences between /proc/cpuinfo and glibc code.

https://sourceware.org/bugzilla/show_bug.cgi?id=26823, https://bugzilla.redhat.com/show_bug.cgi?id=1128638https://sourceware.org/bugzilla/show_bug.cgi?id=24080

nptl/tst-mutex10
此测试超时。

剩余147次测试
这些测试失败是由于测试工具中的限制,“当构建配置为非标准前缀时(即不是 /usr)”(参见 bug-atexit3 和 nptl 测试 https://sourceware.org/glibc/wiki/Testing/Testsuite)

部分

解决方法

**** 请注意:可能不应该直接遵循以下说明来创建 Glibc 2.33 的新“独立”构建。相反,这些指导应该纳入构建整个工具链的更大步骤集(GCCBinutilsGlibc, 等等) ****

以下解决方法可用于使用默认编译器在 Ubuntu 21.04 中构建 Glibc 2.33。 (可选)首先,通过将前缀设置为 /usr 来构建 Glibc 2.33 并仅验证 elf/tst-cpu-features-cpuinfo 测试失败(测试只有在虚拟机中构建时才会失败)。然后,使用所需的前缀重建 Glibc 2.33

构建 Glibc 2.33,前缀设置为 /usr

**** 警告:请勿执行 make install 否则系统将损坏 ****

以下构建步骤在 VM 上执行时将导致构建只有一次失败 (elf/tst-cpu-features-cpuinfo),直接执行时应该不会导致失败在主机上(按照问题中的描述配置)。

    wget https://ftp.gnu.org/gnu/glibc/glibc-2.33.tar.gz -P ${HOME}/Downloads
    rm -rf ${HOME}/Projects/BuildToolchainUsr && mkdir -p ${HOME}/Projects/BuildToolchainUsr/Build
    tar -xf ${HOME}/Downloads/glibc-2.33.tar.gz -C ${HOME}/Projects/BuildToolchainUsr
    cd ${HOME}/Projects/BuildToolchainUsr/Build
    ../glibc-2.33/configure --prefix=/usr 2>&1 | tee output-configure.txt
    make -j`nproc` 2>&1 | tee output-make.txt
    make check 2>&1 | tee output-make-check.txt

以上步骤应产生以下测试结果:

    UNSUPPORTED: elf/tst-audit10
    UNSUPPORTED: elf/tst-avx512
    UNSUPPORTED: elf/tst-cet-legacy-8
    UNSUPPORTED: elf/tst-cet-property-2
    FAIL: elf/tst-cpu-features-cpuinfo
    XPASS: elf/tst-protected1a
    XPASS: elf/tst-protected1b
    UNSUPPORTED: math/test-double-libmvec-sincos-avx512
    UNSUPPORTED: math/test-float-libmvec-sincosf-avx512
    UNSUPPORTED: misc/tst-pkey
    UNSUPPORTED: nptl/test-cond-printers
    UNSUPPORTED: nptl/test-condattr-printers
    UNSUPPORTED: nptl/test-mutex-printers
    UNSUPPORTED: nptl/test-mutexattr-printers
    UNSUPPORTED: nptl/test-rwlock-printers
    UNSUPPORTED: nptl/test-rwlockattr-printers
    UNSUPPORTED: posix/tst-cet-vfork-1
    Summary of test results:
          1 FAIL
       4352 PASS
         14 UNSUPPORTED
         17 XFAIL
          2 XPASS

使用所需的前缀构建 Glibc 2.33

然后可以使用以下命令构建

Glibc 2.33 以使用所需的前缀值。虽然有 2 个测试会失败(如果直接在主机上构建则有 1 个),失败是测试工具限制的结果,可以安全地忽略。

详细的解决方法解释

解决方法通过为 libstdc++.so.6libgcc_s.so.1 创建符号链接并执行测试套件两次,在第二次执行之前创建额外的符号链接,解决了除一个前缀相关测试失败之外的所有问题。前两个符号链接确保所有单元测试都能找到 libstdc++.so.6libgcc_s.so.1。当测试套件是第一个 运行 时,会创建一个名为 testroot.pristine 的目录,用于为每个单元测试提供干净的 chroot。在单个单元测试开始时,testroot.pristine 目录被复制到 testroot.root(替换任何现有的 testroot.root 目录)并设置 chroot .单个单元测试可以将特定于测试的文件复制到 testroot.root 目录中。

第一次执行测试套件后,将出现 5 次失败(如果 运行 在 VM 之外则失败 4 次)。其中三个失败是由于单元测试假定前缀始终为 /usr。为了解决这个问题,在 testroot.prestine 目录中创建了第二组符号链接,以确保 3 个单元测试能够找到所需的文件。然后删除 Build 目录中的所有 *.out 文件,因此可以重新 运行 完整的测试套件,而无需重新创建 testroot.prestine 目录。

    rm -rf ${HOME}/Projects/BuildToolchain && mkdir -p ${HOME}/Projects/BuildToolchain/Build
    tar -xf ${HOME}/Downloads/glibc-2.33.tar.gz -C ${HOME}/Projects/BuildToolchain
    cd ${HOME}/Projects/BuildToolchain/Build
    ../glibc-2.33/configure --prefix=${HOME}/Projects/BuildToolchain/Install 2>&1 | tee output-configure.txt
    make -j`nproc` 2>&1 | tee output-make.txt
    ln -s /lib/x86_64-linux-gnu/libstdc++.so.6
    ln -s /lib/x86_64-linux-gnu/libgcc_s.so.1
    TIMEOUTFACTOR=16 make check 2>&1 | tee output-make-checkA.txt
    mkdir testroot.pristine/usr
    ln -s ${HOME#/}/Projects/BuildToolchain/Install/etc testroot.pristine/etc
    ln -s ${HOME#/}/Projects/BuildToolchain/Install/lib testroot.pristine/lib64
    ln -s ${HOME#/}/Projects/BuildToolchain/Install/sbin testroot.pristine/sbin
    ln -s ${HOME#/}/Projects/BuildToolchain/Install/var testroot.pristine/var
    ln -s ..${HOME}/Projects/BuildToolchain/Install/bin testroot.pristine/usr/bin
    ln -s ..${HOME}/Projects/BuildToolchain/Install/include testroot.pristine/usr/include
    ln -s ..${HOME}/Projects/BuildToolchain/Install/lib testroot.pristine/usr/lib
    ln -s ..${HOME}/Projects/BuildToolchain/Install/lib testroot.pristine/usr/lib64
    ln -s ..${HOME}/Projects/BuildToolchain/Install/libexec testroot.pristine/usr/libexec
    ln -s ..${HOME}/Projects/BuildToolchain/Install/sbin testroot.pristine/usr/sbin
    ln -s ..${HOME}/Projects/BuildToolchain/Install/share testroot.pristine/usr/share
    find -name "*.out" -delete
    TIMEOUTFACTOR=16 make check 2>&1 | tee output-make-checkB.txt

注释

TIMEOUTFACTOR:此环境变量用于增加测试工具使用的超时值。

第一个 make check 命令后的预期测试输出:

    FAIL: elf/check-abi-libc
    UNSUPPORTED: elf/tst-audit10
    UNSUPPORTED: elf/tst-avx512
    UNSUPPORTED: elf/tst-cet-legacy-8
    UNSUPPORTED: elf/tst-cet-property-2
    FAIL: elf/tst-cpu-features-cpuinfo
    FAIL: elf/tst-glibc-hwcaps-prepend-cache
    FAIL: elf/tst-ldconfig-ld_so_conf-update
    XPASS: elf/tst-protected1a
    XPASS: elf/tst-protected1b
    UNSUPPORTED: math/test-double-libmvec-sincos-avx512
    UNSUPPORTED: math/test-float-libmvec-sincosf-avx512
    UNSUPPORTED: misc/tst-pkey
    UNSUPPORTED: nptl/test-cond-printers
    UNSUPPORTED: nptl/test-condattr-printers
    UNSUPPORTED: nptl/test-mutex-printers
    UNSUPPORTED: nptl/test-mutexattr-printers
    UNSUPPORTED: nptl/test-rwlock-printers
    UNSUPPORTED: nptl/test-rwlockattr-printers
    FAIL: nss/tst-nss-files-hosts-long
    UNSUPPORTED: posix/tst-cet-vfork-1
    UNSUPPORTED: resolv/tst-resolv-ai_idn
    UNSUPPORTED: resolv/tst-resolv-ai_idn-latin1
    Summary of test results:
          5 FAIL
       4346 PASS
         16 UNSUPPORTED
         17 XFAIL
          2 XPASS

第二个make check命令后的预期测试输出:

    FAIL: elf/check-abi-libc
    UNSUPPORTED: elf/tst-audit10
    UNSUPPORTED: elf/tst-avx512
    UNSUPPORTED: elf/tst-cet-legacy-8
    UNSUPPORTED: elf/tst-cet-property-2
    FAIL: elf/tst-cpu-features-cpuinfo
    XPASS: elf/tst-protected1a
    XPASS: elf/tst-protected1b
    UNSUPPORTED: math/test-double-libmvec-sincos-avx512
    UNSUPPORTED: math/test-float-libmvec-sincosf-avx512
    UNSUPPORTED: misc/tst-pkey
    UNSUPPORTED: nptl/test-cond-printers
    UNSUPPORTED: nptl/test-condattr-printers
    UNSUPPORTED: nptl/test-mutex-printers
    UNSUPPORTED: nptl/test-mutexattr-printers
    UNSUPPORTED: nptl/test-rwlock-printers
    UNSUPPORTED: nptl/test-rwlockattr-printers
    UNSUPPORTED: posix/tst-cet-vfork-1
    UNSUPPORTED: resolv/tst-resolv-ai_idn
    UNSUPPORTED: resolv/tst-resolv-ai_idn-latin1
    Summary of test results:
          2 FAIL
       4349 PASS
         16 UNSUPPORTED
         17 XFAIL
          2 XPASS

详细的测试失败解释

elf/check-abi-libc 此测试失败,因为 _nl_default_dirname 符号存储 locale 文件的路径(请参阅 https://sourceware.org/pipermail/libc-alpha/2012-December/036816.html)。当前缀设置为 /usr 时, locale 文件路径为 /usr/share/locale 但按上述说明,路径为 ${HOME}/Projects/BuildToolchain/Install/share/locale (扩展了 ${HOME} 变量).可以安全地忽略此故障。

    --- ../sysdeps/unix/sysv/linux/x86_64/64/libc.abilist   2021-02-01 12:15:33.000000000 -0500
    +++ /home/sandy/Projects/BuildToolchain/Build/libc.symlist      2021-07-14 18:18:50.040682543 -0400
    @@ -499 +499 @@ GLIBC_2.2.5 _mcount F
    -GLIBC_2.2.5 _nl_default_dirname D 0x12
    +GLIBC_2.2.5 _nl_default_dirname D 0x39