A core dump occurred in the business last night. The stack content of the core file in the production environment checked this morning is as follows:
gdb ./appname --core=core.1234 (gdb) bt
The stack content is as follows:
#0 0x00007f5634262734 in std::_Rb_tree_rotate_right () from /usr/lib/libstdc++.so.6#1 0x00007f56342628c1 in std::_Rb_tree_insert_and_rebalance () from /usr/lib/libstdc++.so.6#2 0x00000000004b556c in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_insert_ (this=0x7fff3d253090, __x=0x0, __p=0x12e48f0, __v=@0x7fff3d251350) at /usr/include/c++/4.3/bits/stl_tree.h:854#3 0x00000000004b63d2 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, unsigned int>, std::_Select1st<std::pair<unsigned int const, unsigned int> >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::_M_insert_unique_ (this=0x7fff3d253090, __position={_M_node = 0x7f56182ee260}, __v=@0x7fff3d251350) at /usr/include/c++/4.3/bits/stl_tree.h:1201#4 0x00000000004b65da in std::map<unsigned int, unsigned int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::insert ( this=0x7fff3d253090, __position={_M_node = 0x7f56182ee260}, __x=@0x7fff3d251350) at /usr/include/c++/4.3/bits/stl_map.h:496#5 0x00000000004b6680 in std::map<unsigned int, unsigned int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::operator[] ( this=0x7fff3d253090, __k=@0x7fff3d251508) at /usr/include/c++/4.3/bits/stl_map.h:419
Find the source code for #5:
Mapped_type & operator [] (const key_type & _ k) {// concept requirements _ aggregate (_ defaultconstructibleconcept <mapped_type>) iterator _ I = lower_bound (_ k ); // _ I-> first is greater than or equivalent to _ k. if (_ I = end () | key_comp () (_ k, (* _ I ). first) {_ I = insert (_ I, value_type (_ k, mapped_type (); // problematic statement} return (* _ I ). second ;}
Find the source code for #4:
Iterator insert (iterator _ Position, const value_type & _ x) {return _ M_t. _ m_insert_unique _ (_ Position, _ x); // problematic statement}
Find the source code for #3:
Typename _ rb_tree <_ key, _ Val, _ keyofvalue, _ compare, _ alloc >:: iterator_rb_tree <_ key, _ Val, _ keyofvalue, _ compare, _ alloc> :: _ m_insert_unique _ (const_iterator _ Position, const _ Val & _ v) {// end () If position is end, if (_ position. _ m_node = _ m_end () {If (SIZE ()> 0 & _ m_impl. _ m_key_compare (_ s_key (_ m_rightmost (), _ keyofvalue () (_ V) return _ m_insert _ (0, _ m_rightmost (), _ V ); elsereturn _ m_insert_unique (_ V ). first;} else if (_ m_impl. _ m_key_compare (_ keyofvalue () (_ v), _ s_key (_ position. _ m_node) {// first, try before... const_iterator _ before = _ position; if (_ position. _ m_node = _ m_leftmost () // begin () {return _ m_insert _ (_ m_leftmost (), _ m_leftmost (), _ V );} else if (_ m_impl. _ m_key_compare (_ s_key (-- _ before ). _ m_node), _ keyofvalue () (_ V) {If (_ s_right (_ before. _ m_node) = 0) {return _ m_insert _ (0, _ before. _ m_node, _ V); // problematic statement
From the analysis, we can see that the IF (_ position. _ m_node = _ m_end () Branch, but to else if (...). Indicates that the key value already exists in the map. The result of this insertion is to change the value corresponding to the key. The log in the production environment shows that the key value has been dropped. If it is inserted, it should go through the first if branch.
Therefore, there is only one case, that is, data inconsistency caused by multithreading. Add:
boost::recursive_mutex::scoped_lock lock(m_mutex);
Where m_mutex is:
boost::recursive_mutex m_mutex;