Building libc++ with MemorySanitizer instrumentation fails due to MemorySanitizer warning
Asked Answered
I

1

7

I'm trying to build libc++ with MemorySanitizer instrumentation so that I can build my own projects with MemorySanitizer. I am using Clang 8.01 on Ubuntu 16.04.

I followed the instructions given here, but the build initially failed with a linker error. I corrected the linker error by using lld instead of the default linker. However, the build then failed due to a MemorySanitizer warning:

[  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

Since the instructions suggest to build the trunk, I tried building the latest release tag instead (8.01), but this generates the exact same warning. The problem appears to be in GCC's headers, so maybe I need to compile against different standard library headers?

I have also tried following the basic steps here, but the same error occurs.

Infusible answered 5/6, 2019 at 3:51 Comment(4)
include/c++/9/bits/stl_tree.h is a libstdc++ file, not a libc++ file.Kalikow
I have the same problem described by OP. Was any solution found? I tried this command cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=Memory -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_CXX_FLAGS="-stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-lc++abi" -G "Ninja" and got a memory sanitize error in #0 0x555728037204 in llvm::StringRef::split(llvm::SmallVectorImpl<llvm::StringRef>&, char, int, bool) const /home/antonin/llvm-project-llvmorg-8.0.0/llvm/lib/Support/StringRef.cpp:349:3Marginalia
You're building llvm-tblgen with msan instrumentation and it is throwing up false positives. You need to use the llvm-tblgen built without -DLLVM_USE_SANITIZER=Memory. Assuming it was built to /my-build/bin/llvm-tblgan, pass -DLLVM_TABLEGEN="/my-build/bin/llvm-tblgan" to cmake.Testudo
In case anyone still has these problems, the build instructions at the link I originally mentioned in my post (github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo) have been updated and now work! It seems like the problem was that the original instructions given explained how to build ALL OF LLVM with MSAN instrumentation turned on, but really, we just needed to build libc++, which the instructions now do.Infusible
P
8

I saw a very similar issue trying to building libcxx and libcxxabi from LLVM 15.0.1 using MemorySanitizer (MSAN).

I had been following the bootstrapping build instructions for libcxx since the LLVM_ENABLE_PROJECTS="libcxx;libcxxabi" setting was recently deprecated. The failing set of commands was:

# 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

What this was (unintentionally) doing was building llvm-tblgen (and probably other tools) with MSAN instrumentation and then using it to compile libcxx, which caused a false positive because I wasn't using the instrumented libcxx (because I hadn't built it yet).

Instead of doing the bootstrapping commands, I needed just the default build instructions for libcxx. Crucially, I had to start the build from the runtimes subfolder, not the llvm subfolder. Note the different -S parameter:

# 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

In addition to not crashing, this also went faster because the compiler had to do less.

Shoutout to comments on OP's initial question for guiding me in the right direction.

Presently answered 23/9, 2022 at 11:37 Comment(2)
The only place on Internet which explains how to build Msan prerequisites. Thanks!Powwow
I was following llvm's own instructions and couldn't get it to compile. I thought I was going crazy. Your solution worked, but I also had to add libunwind to the LLVM_ENABLE_RUNTIMES definition.Ammons

© 2022 - 2024 — McMap. All rights reserved.