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

2

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.

Bingham answered 6/2, 2020 at 14:31 Comment(10)
The canonical answer to this would be "don't use global variables, ever" I suppose.Episode
@idclev463035818 You can reproduce it becasuse of godbolt. coliru reproduces the results: coliru.stacked-crooked.com/a/2f8fbd89d661fb76Ojeda
I'm going to say this is a false positive.Ojeda
@Ojeda I was suspecting that, but wasnt sure.Dictograph
@idclev463035818 I have removed // use gobj. @Ojeda is there any reason why memory sanitizer is producing a false positive?Bingham
Looks like this might answer your question: #47487255Ojeda
@BartekBanachewicz While globals should be avoided, the sanitiser is triggered even if you use a local.Viscount
fwiw, initializing the map instead of using insert yields the same warning: coliru.stacked-crooked.com/a/59958135c0b1f936Dictograph
Sorry, wrong link. See: github.com/catchorg/Catch2/issues/899 also #46931244 also #20618288Ojeda
This shorter example without globals also generates use-of-uninitialized-value warning: coliru.stacked-crooked.com/a/26452112448b24feDissatisfactory
D
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.

Dissatisfactory answered 6/2, 2020 at 15:22 Comment(0)
V
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.

Viscount answered 6/2, 2020 at 14:51 Comment(1)
Not necessarily. For example: #3246508Soporific

© 2022 - 2024 — McMap. All rights reserved.