源自尝试构建使用内存清理程序检测的 libcxx 时的 llvm 错误
我正在尝试使用使用 MemorySanitizer (Msan) 检测的 libcxx 和 libcxxabi 项目构建 LLVM,以调试 C++ 应用程序中未初始化的内存使用情况。 但是,我在构建过程中遇到了错误。
采取的步骤
首先,我成功执行了以下CMake命令:
cmake -GNinja ../llvm \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_USE_SANITIZER=MemoryWithOrigins
运行命令后,我尝试使用 Ninja 构建 LLVM:
ninja -C ~/llvm-project/build -j2
错误输出 也许,我收到了以下 MemorySanitizer 错误输出:
#7 0x555f2def5c9c in llvm::RecordKeeper::addClass(std::unique_ptr<llvm::Record, std::default_delete<llvm::Record> >) /home/j/llvm-project/llvm/include/llvm/TableGen/Record.h:2027:24
#8 0x555f2def3f4 in llvm::TGParser::ParseClass() /home/j/llvm-project/llvm/lib/TableGen/TGParser.cpp:4008:13
#9 0x555f2def0bd7 in llvm::TGParser::ParseObject(llvm::MultiClass*) /home/j/llvm-project/llvm/lib/TableGen/TGParser.cpp:4377:12
#10 0x555f2df00c6a in ParseObjectList /home/j/llvm-project/llvm/lib/TableGen/TGParser.cpp:4389:9
#11 0x555f2df00c6a in llvm::TGParser::ParseFile() /home/j/llvm-project/llvm/lib/TableGen/TGParser.cpp:4398:7
#12 0x555f2ddb4772 in llvm::TableGenMain(char const*, std::function<bool (llvm::raw_ostream&, llvm::RecordKeeper const&)>) /home/j/llvm-project/llvm/lib/TableGen/Main.cpp:127:14
#13 0x555f2db78c32 in main /home/j/llvm-project/llvm/utils/TableGen/TableGen.cpp:81:10
#14 0x7ff357429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_tree.h:1336:4 in _M_lower_bound_tr<llvm::StringRef, void>
Exiting
ninja: build stopped: subcommand failed.
使用 MemorySanitizer 进行构建的目的
我使用 -DLLVM_USE_SANITIZER=MemoryWithOrigins 行构建 LLVM 的唯一原因是修复 MemorySanitizer 问题,因为它会因使用未初始化的值而引发错误。根据 MemorySanitizer GitHub 页面,使用此标志构建 LLVM 是必要的。当我禁用此标志时,构建会成功完成,但我失去了诊断未初始化内存问题的能力。
问题
如何在启用 MemorySanitizer 的情况下成功构建 LLVM,而不会遇到这些错误?有什么我应该尝试的特定标志或配置吗?经过几个小时的努力,对我有用的是: 1.新安装的Ubuntu Jammy
apt-get update && apt-get install -y \
build-essential \
ninja-build \
clang \
libunwind-dev \
git \
wget \
&& rm -rf /var/lib/apt/lists/*
cd /tmp
wget https://github.com/Kitware/CMake/releases/download/v3.24.0/cmake-3.24.0-linux-x86_64.tar.gz && \
tar -zxvf cmake-3.24.0-linux-x86_64.tar.gz --strip-components=1 -C /usr/local
cd /llvm-project
git clone --depth=1 https://github.com/llvm/llvm-project.git .
cd /llvm-project/build
RUN mkdir -p /llvm-project/build && cd /llvm-project/build && \
CC=clang CXX=clang++ cmake -G Ninja \
-DLLVM_ENABLE_PROJECTS="clang" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \
-DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_LIBUNWIND=ON \
-DCMAKE_BUILD_TYPE=Release \
../llvm && \
ninja
我可以说,这确实是用户讲述的硬核方式。 所有组件必须符合我们正在安装的特定 llvm->clang 此外,关于 Sanitizer GitHub 和 LLVM 主页的指南也缺少重要部分: CC=clang CXX=clang++ 这完全改变了游戏规则!