6

I get use-of-uninitialized-value warning while executing the following program compiled with clang++-9 -fsanitize=memory:

#include <map>

class msan_test
{
  std::map<int, int> m_map;

public:
  msan_test()
  {
    m_map.insert(std::make_pair(1, 1));
    m_map.insert(std::make_pair(2, 2));
  }
};

msan_test gobj; // global object of above class

int main()
{
  return 0;
}

This is the warning I get:

==16598==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x49898f in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_get_insert_unique_pos(int const&) (/home/noname/a.out+0x49898f)
    #1 0x49828e in std::pair<std::_Rb_tree_iterator<std::pair<int const, int> >, bool> std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_emplace_unique<std::pair<int, int> >(std::pair<int, int>&&) (/home/noname/a.out+0x49828e)
    #2 0x497a7e in std::enable_if<is_constructible<std::pair<int const, int>, std::pair<int, int> >::value, std::pair<std::_Rb_tree_iterator<std::pair<int const, int> >, bool> >::type std::map<int, int, std::less<int>, std::allocator<std::pair<int const, int> > >::insert<std::pair<int, int> >(std::pair<int, int>&&) (/home/noname/a.out+0x497a7e)
    #3 0x49785a in msan_test::msan_test() (/home/noname/a.out+0x49785a)
    #4 0x41be52 in __cxx_global_var_init (/home/noname/a.out+0x41be52)
    #5 0x41beb8 in _GLOBAL__sub_I_memsan.cpp (/home/noname/a.out+0x41beb8)
    #6 0x49bcbc in __libc_csu_init (/home/noname/a.out+0x49bcbc)
    #7 0x7f5db517db27 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:266
    #8 0x41bee9 in _start (/home/noname/a.out+0x41bee9)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/noname/a.out+0x49898f) in std::_Rb_tree<int, std::pair<int const, int>, std::_Select1st<std::pair<int const, int> >, std::less<int>, std::allocator<std::pair<int const, int> > >::_M_get_insert_unique_pos(int const&)
Exiting

Is this a false positive or something deep is going on?

Thanks.

ks1322
  • 33,961
  • 14
  • 109
  • 164
  • 1
    The canonical answer to this would be "don't use global variables, ever" I suppose. – Bartek Banachewicz Feb 06 '20 at 14:36
  • 2
    @idclev463035818 You can reproduce it becasuse of godbolt. coliru reproduces the results: http://coliru.stacked-crooked.com/a/2f8fbd89d661fb76 – NathanOliver Feb 06 '20 at 14:42
  • 1
    I'm going to say this is a false positive. – NathanOliver Feb 06 '20 at 14:42
  • @NathanOliver I was suspecting that, but wasnt sure. – 463035818_is_not_an_ai Feb 06 '20 at 14:44
  • @idclev463035818 I have removed `// use gobj`. @NathanOliver is there any reason why memory sanitizer is producing a false positive? – user12852628 Feb 06 '20 at 14:45
  • Looks like this might answer your question: https://stackoverflow.com/questions/47486755/clang-memory-sanitizer-reports-use-of-uninitialized-value – NathanOliver Feb 06 '20 at 14:47
  • 2
    @BartekBanachewicz While globals should be avoided, the sanitiser is triggered even if you use a local. – eerorika Feb 06 '20 at 14:47
  • fwiw, initializing the map instead of using `insert` yields the same warning: http://coliru.stacked-crooked.com/a/59958135c0b1f936 – 463035818_is_not_an_ai Feb 06 '20 at 14:47
  • Sorry, wrong link. See: https://github.com/catchorg/Catch2/issues/899 also https://stackoverflow.com/questions/46930744/using-memory-sanitizer-instrumented-libc also https://stackoverflow.com/questions/20617788/using-memory-sanitizer-with-libstdc – NathanOliver Feb 06 '20 at 14:48
  • 1
    This shorter example without globals also generates `use-of-uninitialized-value` warning: http://coliru.stacked-crooked.com/a/26452112448b24fe – ks1322 Feb 06 '20 at 15:02

2 Answers2

2

This is probably already reported MemorySanitizer bug https://github.com/google/sanitizers/issues/542.

However it was closed with Status WontFix without much explanation.

It seems that you need to build instrumented C++ standard library to avoid false positives. From MemorySanitizer wiki:

If you want MemorySanitizer to work properly and not produce any false positives, you must ensure that all the code in your program and in libraries it uses is instrumented (i.e. built with -fsanitize=memory). In particular, you would need to link against MSan-instrumented C++ standard library. We recommend to use libc++ for that purpose.

ks1322
  • 33,961
  • 14
  • 109
  • 164
0

Is this a false positive or something deep is going on?

Either this is false positive in the sanitiser, or the standard library implementation has a bug.

There is no reading of uninitialised value in the shown program.

eerorika
  • 232,697
  • 12
  • 197
  • 326