How can I make this work properly?
You can also unpoison
the memory that's triggering the finding. But its not clear (to me) which variable that is based on the stack trace shown.
Here's how to unpoison the memory, but the example is for memory used with FD_SET
and FD_ZERO
. You will still need to find the name of the variable that's causing it (I'm not sure how well specifying an integral memory address works).
#include <sanitizer/msan_interface.h>
...
__msan_unpoison(&readfds, sizeof(readfds));
__msan_unpoison(&writefds, sizeof(writefds));
UMR in __interceptor_write at offset 0 inside [0x64800000e000, +5)
==9685== WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7f48d0899ae5 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x7bae5)
#1 0x7f48d08d1787 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb3787)
#2 0x7f48d08d21e2 (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb41e2)
#3 0x7f48d08cfd1e (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xb1d1e)
#4 0x7f48d08b1f2d (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x93f2d)
#5 0x7f48d16d60f5 in writeToFile() /home/daniel/programming/test/santest.cpp:10
#6 0x7f48d16d61f4 in main /home/daniel/programming/test/santest.cpp:15
#7 0x7f48d0261de4 (/lib/x86_64-linux-gnu/libc.so.6+0x21de4)
#8 0x7f48d16d5e42 in _start (/home/daniel/programming/test/a.out+0x61e42)
You may be able to get more information about the offenders by running:
./myprog.exe 2>&1 | /usr/bin/asan_symbolize
For example, here's a program I'm trying to test that has output similar to yours:
$ ./cryptest.exe v 2>&1 | /usr/bin/asan_symbolize
==26988== WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7f51903b2ca8 in _ZNSt8_Rb_treeISsSt4pairIKSsPvESt10_Select1stIS3_ESt4lessISsESaIS3_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS3_ESC_RS1_ /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_tree.h:1260 (discriminator 1)
...
If you are up for some punishment, you can pipe the mangled name through c++filt
and get a non-mangled name:
$ echo " _ZNSt8_Rb_treeISsSt4pairIKSsPvESt10_Select1stIS3_ESt4lessISsESaIS3_EE14_M_lower_boundEPSt13_Rb_tree_nodeIS3_ESC_RS1_" | c++filt
std::_Rb_tree<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void*>, std::_Select1st<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void*> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void*> > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void*> >*, std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, void*> >*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
Finally, according to the Msan folks, you really need an instrumented build of the C++ Runtime. They also recommend you use LLVM's libc++
for the purpose. See Memory Sanitizer Libcxx HowTo and How to unpoison a C++ std::string? on the Memory Sanitizer mailing list.
ofstream o("dum");
instead ofo.open("dum");
? – Sklarstdlibc++
- I'm not sure that's a real runtime :) GNU's runtime islibstdc++
. LLVM's runtime islibc++
(sometimes calledlibcxx
). I think the next step for you is to build the LLVM runtime with Msan instrumentation. You can find instructions at Memory Sanitizer Libcxx HowTo. – Montage