Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MemorySanitizer complains about unitialized variable in RPC method names #17620

Open
Sjors opened this issue Nov 27, 2019 · 17 comments
Open

MemorySanitizer complains about unitialized variable in RPC method names #17620

Sjors opened this issue Nov 27, 2019 · 17 comments

Comments

@Sjors
Copy link
Member

@Sjors Sjors commented Nov 27, 2019

I'm trying to get --with-sanitizers=memory to work on Ubuntu Bionic, since it might be useful to prevent stuff like #17568 and #17449.

I installed LLVM 9 and clang using the instructions here. I then configured with:

./configure --enable-debug --with-sanitizers=memory CXX=clang++-9 CC=clang-9

I can build just fine, but when I run bitcoind or bitcoin-cli it immediately bails out:

src/bitcoin-cli
Uninitialized bytes in MemcmpInterceptorCommon at offset 0 inside [0x705000000080, 11)
==25188==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55734b322d9e in memcmp (/home/dev/bitcoin/src/bitcoin-cli+0x5ad9e)
    #1 0x7f633267abc7 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x126bc7)
    #2 0x55734b3e1042 in bool std::operator<<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/basic_string.h:6097:20
    #3 0x55734b3e0e13 in bool std::operator<<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_pair.h:455:24
    #4 0x55734b3e05bc in std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >::operator()(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) const /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_function.h:386:20
    #5 0x55734b3e35e7 in std::_Rb_tree<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::_Identity<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::_M_get_insert_unique_pos(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:2038:13
    #6 0x55734b3e2df0 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, bool> std::_Rb_tree<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::_Identity<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::_M_insert_unique<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:2091:4
    #7 0x55734b3db513 in std::set<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::insert(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_set.h:511:9
    #8 0x55734b3d8de9 in CRPCConvertTable::CRPCConvertTable() /home/dev/bitcoin/src/rpc/client.cpp:200:17
    #9 0x55734b30dd8a in __cxx_global_var_init.165 /home/dev/bitcoin/src/rpc/client.cpp:207:25
    #10 0x55734b30de22 in _GLOBAL__sub_I_client.cpp /home/dev/bitcoin/src/rpc/client.cpp
    #11 0x55734b58b10c in __libc_csu_init (/home/dev/bitcoin/src/bitcoin-cli+0x2c310c)
    #12 0x7f63317c2b27 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:266
    #13 0x55734b312cf9 in _start (/home/dev/bitcoin/src/bitcoin-cli+0x4acf9)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/dev/bitcoin/src/bitcoin-cli+0x5ad9e) in memcmp
Exiting

The relevant code (line 200) doesn't look wrong at first glance:

bitcoin/src/rpc/client.cpp

Lines 194 to 205 in d8a6662

CRPCConvertTable::CRPCConvertTable()
{
const unsigned int n_elem =
(sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
for (unsigned int i = 0; i < n_elem; i++) {
members.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramIdx));
membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramName));
}
}

The bitcoind issue seems similar:

src/bitcoind 
==25862==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x56472f55a4e0 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >*, std::_Rb_tree_node_base*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7
    #1 0x56472f55a24b in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::lower_bound(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1187:16
    #2 0x56472f559519 in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::lower_bound(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:1233:21
    #3 0x56472f4ee06d in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:489:17
    #4 0x56472f4e3291 in CRPCTable::CRPCTable() /home/dev/bitcoin/src/rpc/server.cpp:255:9
    #5 0x56472ec17dda in __cxx_global_var_init.44 /home/dev/bitcoin/src/rpc/server.cpp:499:11
    #6 0x56472ec17e9a in _GLOBAL__sub_I_server.cpp /home/dev/bitcoin/src/rpc/server.cpp
    #7 0x564730ad1dac in __libc_csu_init (/home/dev/bitcoin/src/bitcoind+0x1f19dac)
    #8 0x7f4033472b27 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:266
    #9 0x56472ec3b659 in _start (/home/dev/bitcoin/src/bitcoind+0x83659)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vec
Exiting

Relevant code (line 255):

bitcoin/src/rpc/server.cpp

Lines 247 to 257 in d8a6662

CRPCTable::CRPCTable()
{
unsigned int vcidx;
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
{
const CRPCCommand *pcmd;
pcmd = &vRPCCommands[vcidx];
mapCommands[pcmd->name].push_back(pcmd);
}
}

Maybe this is just a wild goose chase, if it turns out this sanitizer gets triggered all over the place. But @practicalswift successfully used it, so maybe theres' a secret sauce?

@Sjors Sjors added the Bug label Nov 27, 2019
@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors

I think you're seeing false positives due to MSAN being used only when compiling a subset of the code.

Of the sanitizers MSAN is the most cumbersome to setup. Note that MSAN requires all code used to be compiled using -fsanitize=memory. That is really all code: including the C++ standard library. I usually link Bitcoin Core against a self-built MSAN-instrumented libc++ when using MSAN.

In short: to get MSAN working without false positives you'll have to make sure -fsanitize=memory is used when building a.) the standard library you're using, b.) all dependencies in use, and c.) Bitcoin Core itself :)

@fanquake fanquake removed the Bug label Nov 27, 2019
@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors

I don't have the time do it myself but if someone volunteers to add a MemorySanitizer build to Travis (we really really need that!) I can probably find time to document how I've gotten Bitcoin Core to work with MemorySanitizer in the past. The process is a bit hacky so it'll require some cleaning up before being integrated in Travis - but at least the required steps will be shown.

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

I agree it's important to catch this class of bugs. Travis aside, it would be useful to document how to do this.

Other than libc++ I suppose I should use /depends and build those with -fsanitize=memory too?

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

Travis aside, it would be useful to document how to do this.

Agreed! I'll try to guide you :)

Start by compiling libc++ with MSAN instrumentation. You'll get some hints here: https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo#instrumented-libc

See if you are able to get Bitcoin Core link to link against the MSAN-instrumented libc++.

After that we can tackle the depends :)

Other than libc++ I suppose I should use /depends and build those with -fsanitize=memory too?

Yes, exactly! Boost will need some hand holding, but we'll get to that.

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

Ironically I'm running into an uninitialized value error while compiling LLVM:

git clone https://github.com/llvm/llvm-project.git
git checkout llvmorg-9.0.0
cd llvm-project
mkdir libcxx_msan && cd libcxx_msan
cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=Memory -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
make -j10

...
Scanning dependencies of target LipoOptsTableGen
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7 in _M_lower_bound
Exiting
tools/llvm-cvtres/CMakeFiles/CvtResTableGen.dir/build.make:93: recipe for target 'tools/llvm-cvtres/Opts.inc' failed
make[2]: *** [tools/llvm-cvtres/Opts.inc] Error 77
CMakeFiles/Makefile2:23514: recipe for target 'tools/llvm-cvtres/CMakeFiles/CvtResTableGen.dir/all' failed
make[1]: *** [tools/llvm-cvtres/CMakeFiles/CvtResTableGen.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 21%] Linking CXX executable ../../bin/not
[ 21%] Building LipoOpts.inc...
==19389==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0xb8b543 in _M_lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7
    #1 0xb8b543 in lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1187:16
    #2 0xb8b543 in lower_bound /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:1233:21
    #3 0xb8b543 in std::map<long, llvm::IntInit*, std::less<long>, std::allocator<std::pair<long const, llvm::IntInit*> > >::operator[](long const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:489:17
    #4 0xb89714 in llvm::IntInit::get(long) /home/dev/src/llvm-project/llvm/lib/TableGen/Record.cpp:463:17
    #5 0xc06ecb in llvm::TGParser::ParseSimpleValue(llvm::Record*, llvm::RecTy*, llvm::TGParser::IDParseMode) /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:1783:27
    #6 0xbf2246 in llvm::TGParser::ParseValue(llvm::Record*, llvm::RecTy*, llvm::TGParser::IDParseMode) /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:2105:18
    #7 0xc0d072 in llvm::TGParser::ParseDeclaration(llvm::Record*, bool) /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:2414:17
    #8 0xc0edd6 in llvm::TGParser::ParseTemplateArgList(llvm::Record*) /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:2537:16
    #9 0xc13e2a in llvm::TGParser::ParseClass() /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:2846:9
    #10 0xc13465 in llvm::TGParser::ParseObject(llvm::MultiClass*) /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:3188:12
    #11 0xc1b3ec in ParseObjectList /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:3200:9
    #12 0xc1b3ec in llvm::TGParser::ParseFile() /home/dev/src/llvm-project/llvm/lib/TableGen/TGParser.cpp:3208:7
    #13 0xb7e4fe in llvm::TableGenMain(char*, bool (*)(llvm::raw_ostream&, llvm::RecordKeeper&)) /home/dev/src/llvm-project/llvm/lib/TableGen/Main.cpp:99:14
    #14 0xa7d445 in main /home/dev/src/llvm-project/llvm/utils/TableGen/TableGen.cpp:263:10
    #15 0x7f02d86e7b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #16 0x425f49 in _start (/home/dev/src/llvm-project/libcxx_msan/bin/llvm-tblgen+0x425f49)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7 in _M_lower_bound
Exiting
tools/llvm-lipo/CMakeFiles/LipoOptsTableGen.dir/build.make:93: recipe for target 'tools/llvm-lipo/LipoOpts.inc' failed
make[2]: *** [tools/llvm-lipo/LipoOpts.inc] Error 77

Should I try an older version?

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors

Try this:

$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
$ (cd llvm/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx)
$ (cd llvm/projects && svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi)
$ mkdir libcxx_msan && cd libcxx_msan
$ cmake ../llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_USE_SANITIZER=Memory -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
$ make cxx -j12

Does that work? :)

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

Subversion, really?

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

I heard the OpenBSD people suggested going with cvs instead :)

@ryanofsky

This comment has been minimized.

Copy link
Contributor

@ryanofsky ryanofsky commented Nov 27, 2019

Subversion, really?

Hey... I used to work on Subversion. Apparently I had 82 commits (https://fisheye.apache.org/committer/subversion/rey4). Even still subversion can work better than git if you have a large codebase.

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors

If you want to use git you can use the new LLVM monorepo (the one you cloned), but then you'll have to opt-in to the specific subprojects you want to build by passing -DLLVM_ENABLE_PROJECTS=libcxx;libcxxabi to cmake.

Does that work better? :)

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

Anyway, the above compiles, but not sure how to get this into ./configure (or depends for that matter)

I tried:

 ./configure --enable-debug --with-incompatible-bdb --without-gui --disable-bench CXXFLAGS="-Werror=unused-variable -I/home/dev/src/libcxx_msan/include -I/home/dev/src/libcxx_msan/include/c++/v1" --with-sanitizers=memory CXX=clang++-9 CC=clang-9

This throws a bunch of rocks at me, e.g.:

configure: error: libdb_cxx headers missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)

Without wallet it gets stuck at Boost (maybe that's where the hand holding comes in?):

configure: error: No working boost sleep implementation found.
@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors

Great that libc++ is instrumented. That is a good start! :)

Oh, we probably need to go with the depends first.

See if you can get depends to build using CFLAGS and CXXFLAGS set to -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fsanitize=memory -nostdinc++ -stdlib=libc++ -L${INSTRUMENTED_LIBCXX}/lib -lc++abi -I${INSTRUMENTED_LIBCXX}include -I${INSTRUMENTED_LIBCXX}/include/c++/v1 -lpthread -Wl,-rpath,${INSTRUMENTED_LIBCXX}/lib.

To get Boost to build with MSAN you'll have to do something along the lines of:

diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk
index d360bb5ba..fcd138f92 100644
--- a/depends/packages/boost.mk
+++ b/depends/packages/boost.mk
@@ -19,7 +19,7 @@ $(package)_config_opts_i686_android=address-model=32
 $(package)_config_opts_aarch64_android=address-model=64
 $(package)_config_opts_x86_64_android=address-model=64
 $(package)_config_opts_armv7a_android=address-model=32
-$(package)_toolset_$(host_os)=gcc
+$(package)_toolset_$(host_os)=clang
 $(package)_archiver_$(host_os)=$($(package)_ar)
 $(package)_toolset_darwin=clang-darwin
 $(package)_config_libraries=chrono,filesystem,system,thread,test
@@ -29,17 +29,17 @@ $(package)_cxxflags_android=-fPIC
 endef

 define $(package)_preprocess_cmds
-  echo "using $(boost_toolset_$(host_os)) : : $($(package)_cxx) : <cxxflags>\"$($(package)_cxxflags) $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\"  <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
+  echo "using clang : : clang++ : <cxxflags>\"$($(package)_cxxflags) -fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fsanitize=memory -nostdinc++ -stdlib=libc++ -LPATH_TO_YOUR_INSTRUMENTED_LIBCXX/lib -lc++abi -IPATH_TO_YOUR_INSTRUMENTED_LIBCXX/include -IPATH_TO_YOUR_INSTRUMENTED_LIBCXX/include/c++/v1 -lpthread -Wl,-rpath,PATH_TO_YOUR_INSTRUMENTED_LIBCXX/lib $($(package)_cppflags)\" <linkflags>\"$($(package)_ldflags)\" <archiver>\"$(boost_archiver_$(host_os))\" <striper>\"$(host_STRIP)\"  <ranlib>\"$(host_RANLIB)\" <rc>\"$(host_WINDRES)\" : ;" > user-config.jam
 endef

 define $(package)_config_cmds
-  ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries)
+  ./bootstrap.sh --without-icu --with-libraries=$(boost_config_libraries) toolset=clang
 endef

 define $(package)_build_cmds
-  ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) stage
+  ./b2 -d2 -j2 -d1 --prefix=$($(package)_staging_prefix_dir) toolset=clang stage $($(package)_config_opts)
 endef

 define $(package)_stage_cmds
-  ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) install
+  ./b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) toolset=clang install $($(package)_config_opts)
 endef

Try make NO_QT=1 NO_ZMQ=1 NO_UPNP=1 NO_WALLET=1 V=1.

Does it build? :)

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

V=1 is a typo? I was able to build depends with your patch and incantation.

But building bitcoind still complains about missing boost sleep:

./configure --prefix=`pwd`/depends/x86_64-pc-linux-gnu --enable-debug --with-sanitizers=memory CXX=clang++-9 CC=clang-9
configure: loading site script /home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/config.site
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
...
checking whether to build Bitcoin Core GUI... no
checking for boostlib >= 1.47.0 (104700) includes in "/home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/../include"... yes
checking for boostlib >= 1.47.0 (104700) lib path in "/home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/../lib/x86_64-linux-gnu"... no
checking for boostlib >= 1.47.0 (104700) lib path in "/home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/../lib64"... no
checking for boostlib >= 1.47.0 (104700) lib path in "/home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/../libx32"... no
checking for boostlib >= 1.47.0 (104700) lib path in "/home/dev/bitcoin/depends/x86_64-pc-linux-gnu/share/../lib"... yes
checking for boostlib >= 1.47.0 (104700)... yes
checking whether the Boost::System library is available... yes
checking for exit in -lboost_system-mt-x64... yes
checking whether the Boost::Filesystem library is available... yes
checking for exit in -lboost_filesystem-mt-x64... yes
checking whether the Boost::Thread library is available... yes
checking for exit in -lboost_thread-mt-x64... yes
checking whether the Boost::Chrono library is available... yes
checking for exit in -lboost_chrono-mt-x64... yes
checking whether the Boost::Unit_Test_Framework library is available... yes
checking for dynamic linked boost test... no
checking for mismatched boost c++11 scoped enums... ok
configure: error: No working boost sleep implementation found.

Maybe related #17478

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors No V=1 is to get the commands executed printed -- V is for verbose :)

Please try:

$ FLAGS="-fno-omit-frame-pointer -g -O1 -fno-optimize-sibling-calls \
    -fsanitize-memory-track-origins=2 -fsanitize=memory -nostdinc++ \
    -stdlib=libc++ -L${INSTRUMENTED_LIBCXX}lib -lc++abi \
    -I${INSTRUMENTED_LIBCXX}include -I${INSTRUMENTED_LIBCXX}include/c++/v1 \
    -lpthread -Wl,-rpath,${INSTRUMENTED_LIBCXX}lib"
$ CC=clang-9 CXX=clang++-9 CFLAGS="${FLAGS}" CXXFLAGS="${FLAGS}" \
    ./configure --with-gui=no --disable-wallet --disable-zmq --disable-asm \
    --with-miniupnpc=no --prefix=$(pwd)/depends/x86_64-pc-linux-gnu

Does that work? :)

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 27, 2019

Configure works now, but build bails out with a huge error, e.g. make src/bitcoin-cli: https://gist.github.com/Sjors/37c5c35eeab351f57891f2e47d9cdf01

@practicalswift

This comment has been minimized.

Copy link
Member

@practicalswift practicalswift commented Nov 27, 2019

@Sjors Could that be due left-overs from a previous build? Can you retry after a make distclean or a new git clone?

@Sjors

This comment has been minimized.

Copy link
Member Author

@Sjors Sjors commented Nov 28, 2019

That worked. Now plowing through false positives... #17627

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.