_M_find_before_node coredump分析
写在前面
工作中遇到的core问题,网上搜了下这个core栈信息_M_find_before_node,仍然没有找到思路,分享下最后的解决方法,欢迎交流讨论
gdb分析core文件
core时信息
提示程序出现了段错误,具体信息如下:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000c6dd22 in std::_Hashtable<int, std::pair<int const, bool>, std::allocator<std::pair<int const, bool> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node (this=0x7fffffffbdd0, __n=__n@entry=0, __k=@0x28b2320: 0, __code=0)
at /usr/local/include/c++/4.9.2/bits/hashtable.h:1442
1442 for (__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);;
core时堆栈信息
根据堆栈信息,core在了unordered_map执行find函数,调用底层函数_M_find_before_node时,具体信息如下:
(gdb) bt
#0 0x0000000000c6dd22 in std::_Hashtable<int, std::pair<int const, bool>, std::allocator<std::pair<int const, bool> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node (this=0x7fffffffbdd0, __n=__n@entry=0, __k=@0x28b2320: 0, __code=0)
at /usr/local/include/c++/4.9.2/bits/hashtable.h:1442
#1 0x0000000000c6e62f in _M_find_node (__c=0, __key=<optimized out>, __bkt=0, this=<optimized out>)
at /usr/local/include/c++/4.9.2/bits/hashtable.h:625
#2 find (__k=@0x28b2320: 0, this=<optimized out>) at /usr/local/include/c++/4.9.2/bits/hashtable.h:1304
#3 find (__x=<optimized out>, this=<optimized out>) at /usr/local/include/c++/4.9.2/bits/unordered_map.h:574
core时栈顶帧信息
对栈顶帧信息分析,查看当前map的size,即_M_element_count的值,发现是0,而实际上,此前这个map已经insert过元素,size不应该是0,由此可怀疑,当前的map的内存出了问题,具体信息如下:
(gdb) f 0
#0 0x0000000000c6dd22 in std::_Hashtable<int, std::pair<int const, bool>, std::allocator<std::pair<int const, bool> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_find_before_node (this=0x7fffffffbdd0, __n=__n@entry=0, __k=@0x28b2320: 0, __code=0)
at /usr/local/include/c++/4.9.2/bits/hashtable.h:1442
1442 for (__node_type* __p = static_cast<__node_type*>(__prev_p->_M_nxt);;
(gdb) p this->_M_element_count
$1 = 0
代码分析
全局指针所指向的对象,由于作用域的问题,已经发生了析构,示例代码如下:
#include <unordered_map>
#include <iostream>
std::unordered_map<int, bool>* global_v = nullptr;
int main() {
{
std::unordered_map<int, bool> tmp;
tmp[0] = true;
global_v = &tmp;
}
{
auto iter = global_v->find(0);
if (iter != global_v->end()) {
std::cout << "find success" << std::endl;
}
}
return 0;
}
其它排查思路
如果通过core文件和代码分析,仍然没有定位带原因,可尝试使用-lasan进行编译,指令如下:
g++ test.cpp -fsanitize=address -g1 -lasan -o test
core时可看到如下信息:
$./test
=================================================================
==329967==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffd8741e658 at pc 0x0000004023cf bp 0x7ffd8741e410 sp 0x7ffd8741e400
READ of size 8 at 0x7ffd8741e658 thread T0
#0 0x4023ce in std::_Hashtable<int, std::pair<int const, bool>, std::allocator<std::pair<int const, bool> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::_M_bucket_index(int const&, unsigned long) const /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/hashtable.h:631
#1 0x40207a in std::_Hashtable<int, std::pair<int const, bool>, std::allocator<std::pair<int const, bool> >, std::__detail::_Select1st, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, false, true> >::find(int const&) /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/hashtable.h:1421
#2 0x401ab4 in std::unordered_map<int, bool, std::hash<int>, std::equal_to<int>, std::allocator<std::pair<int const, bool> > >::find(int const&) /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/unordered_map.h:923
#3 0x40146d in main /home/liyuan65/jdcloud_cfs/CodePractice/test.cpp:13
#4 0x7fc6b1695b14 in __libc_start_main (/lib64/libc.so.6+0x21b14)
#5 0x401158 (/export/jdcloud_cfs/liyuan65/CodePractice/test+0x401158)