Search code examples
c++constructorclangglobalmsan

Memory sanitizer reports use-of-uninitialized-value in global object construction


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.


Solution

  • 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.