由于 MemorySanitizer 警告,使用 MemorySanitizer 工具构建 libc++ 失败

Dan*_*iel 7 llvm llvm-clang libc++ msan

我正在尝试使用 MemorySanitizer 工具构建 libc++,以便我可以使用 MemorySanitizer 构建自己的项目。我在 Ubuntu 16.04 上使用 Clang 8.01。

我按照此处给出的说明进行操作,但构建最初因链接器错误而失败。我通过使用 lld 而不是默认链接器更正了链接器错误。然而,由于 MemorySanitizer 警告,构建失败了:

[  0%] Built target LLVMDemangle
[  4%] Built target LLVMSupport
[  4%] Built target LLVMTableGen
[  5%] Built target obj.llvm-tblgen
[  5%] Built target llvm-tblgen
[  5%] Building AttributesCompatFunc.inc...
==6384==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x51ee14 in _M_lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:1940:7
    #1 0x51ee14 in find /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:2566
    #2 0x51ee14 in find /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_map.h:1194
    #3 0x51ee14 in llvm::RecordKeeper::getClass(llvm::StringRef) const /opt/llvm/llvm-801/include/llvm/TableGen/Record.h:1612
    #4 0xa2ff5c in llvm::TGParser::ParseClass() /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:2648:28
    #5 0xa2fceb in llvm::TGParser::ParseObject(llvm::MultiClass*) /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:3010:12
    #6 0xa37c9a in ParseObjectList /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:3022:9
    #7 0xa37c9a in llvm::TGParser::ParseFile() /opt/llvm/llvm-801/lib/TableGen/TGParser.cpp:3030
    #8 0x99fa00 in llvm::TableGenMain(char*, bool (*)(llvm::raw_ostream&, llvm::RecordKeeper&)) /opt/llvm/llvm-801/lib/TableGen/Main.cpp:100:14
    #9 0x8aa738 in main /opt/llvm/llvm-801/utils/TableGen/TableGen.cpp:253:10
    #10 0x7f11477df82f in __libc_start_main /build/glibc-LK5gWL/glibc-2.23/csu/../csu/libc-start.c:291
    #11 0x297028 in _start (/opt/llvm/llvm-801-msan/bin/llvm-tblgen+0x297028)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:1940:7 in _M_lower_bound
Exiting
lib/IR/CMakeFiles/AttributeCompatFuncTableGen.dir/build.make:93: recipe for target 'lib/IR/AttributesCompatFunc.inc' failed
make[2]: *** [lib/IR/AttributesCompatFunc.inc] Error 77
CMakeFiles/Makefile2:1628: recipe for target 'lib/IR/CMakeFiles/AttributeCompatFuncTableGen.dir/all' failed
make[1]: *** [lib/IR/CMakeFiles/AttributeCompatFuncTableGen.dir/all] Error 2
Makefile:151: recipe for target 'all' failed
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)

由于说明建议构建主干,因此我尝试构建最新的版本标签(8.01),但这会生成完全相同的警告。问题似乎出在 GCC 的标头中,所以也许我需要针对不同的标准库标头进行编译?

我也尝试按照此处的基本步骤进行操作,但出现了相同的错误。

Kev*_*inL 4

libcxx我在尝试使用 MemorySanitizer (MSAN)构建LLVM 15.0.1 时看到了一个非常相似的问题libcxxabi

自从该设置最近被弃用以来,我一直在遵循libcxx 的引导构建说明。失败的命令集是:LLVM_ENABLE_PROJECTS="libcxx;libcxxabi"

# I had previously built clang from source and set my CC and CXX
# environment variables appropriately. We are still in the llvm-project
# root of that source checkout.
cmake -G Ninja -S llvm -B msan_out \
    -DCMAKE_BUILD_TYPE=Release \
    -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
    -DLLVM_USE_SANITIZER=MemoryWithOrigins

ninja -C msan_out cxx cxxabi
Run Code Online (Sandbox Code Playgroud)

这是(无意中)做的是使用llvm-tblgenMSAN 仪器构建(可能还有其他工具),然后使用它来编译libcxx,这导致了误报,因为我没有使用仪器libcxx(因为我还没有构建它)。

我不需要执行引导命令,而只需要libcxx 的默认构建指令至关重要的是,我必须从运行时子文件夹而不是llvm 子文件夹开始构建。注意不同的-S参数:

# This still only works because my CC and CXX environment variables
# are set to the freshly built clang 15 binaries.
cmake -G Ninja -S runtimes -B msan_out \
    -DCMAKE_BUILD_TYPE=Release \
    -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
    -DLLVM_USE_SANITIZER=MemoryWithOrigins

ninja -C msan_out cxx cxxabi
Run Code Online (Sandbox Code Playgroud)

除了不崩溃之外,这还更快,因为编译器要做的事情更少。

感谢对OP最初问题的评论,引导我走向正确的方向。