Trying to debug a memory corruption with address sanitizer. It detects error, read after free. Read gives me a meaningful stack trace which makes sense, but then for the place were memory was allegedly freed i get weird one:
#0 0xf793ba08 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cc:165
ing<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >*, unsigned int) /usr/include/c++/9/ext/new_allocator.h:128
#2 0xa0217ef in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> > > >::deallocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> > >&, std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >*, unsigned int) /usr/include/c++/9/bits/alloc_traits.h:469
#3 0xa0217ef 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, task::my_task_stats>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >, 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, task::my_task_stats> > >::_M_put_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >*) /usr/include/c++/9/bits/stl_tree.h:584
#4 0xa0217ef 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, task::my_task_stats>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >, 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, task::my_task_stats> > >::_M_drop_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >*) /usr/include/c++/9/bits/stl_tree.h:651
#5 0xa0217ef 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, task::my_task_stats>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >, 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, task::my_task_stats> > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >*) /usr/include/c++/9/bits/stl_tree.h:1920
#6 0xa0217ef 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, task::my_task_stats>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, task::my_task_stats> >, 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, task::my_task_stats> > >::~_Rb_tree() /usr/include/c++/9/bits/stl_tree.h:1000
#7 0xa0217ef in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, task::my_task_stats, 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, task::my_task_stats> > >::~map() /usr/include/c++/9/bits/stl_map.h:300
#8 0xf6e46f05 (/lib/i386-linux-gnu/libc.so.6+0x33f05)
What do I make of the destructor being called straight from libc? What makes it stranger is that this map that is being deleted is a static field in a class. Does this mean that the error happened when process was terminating? How would i figure out why it is terminating?
By not making any global
C++objects with non-trivial destructors.That is one valid solution. Often you don't need the
std::once_flagat all, e.g.No, it will not. Any leak detector worth using makes a distinction between "leaked" (you've lost the pointer and couldn't
free/deleteeven if you wanted to) and "still allocated at exit" (you couldfree, but haven't bothered to).