Daniel
Daniel

Reputation: 406

Building libc++ with MemorySanitizer instrumentation fails due to MemorySanitizer warning

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.

Upvotes: 7

Views: 1198

Answers (1)

kjlubick
kjlubick

Reputation: 1318

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.

Upvotes: 8

Related Questions