程序定义了一个unordered_map对象来保存一些信息,运行起来coredump了,gdb看堆栈,很莫名其妙,coredump的地方是在调用标准库unordered_map的find函数:
Program terminated with signal 11, Segmentation fault.
#0 0x000000000042a517 in std::_Hashtablestring, std::pairstring const, Channel*>, std::allocatorstring const, Channel*> >, std::__detail::_Select1st, std::equal_tostring>, std::hashstring>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_before_node (this=this@entry=0x1c996e0,
__n=1510, __k=..., __code=2278699879894225472) at /usr/include/c++/4.8.2/bits/hashtable.h:1159
1159 __node_base* __prev_p = _M_buckets[__n];
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64 libgcc-4.8.5-16.el7.x86_64 libstdc++-4.8.5-16.el7.x86_64
(gdb) bt
#0 0x000000000042a517 in std::_Hashtablestring, std::pairstring const, Channel*>, std::allocatorstring const, Channel*> >, std::__detail::_Select1st, std::equal_tostring>, std::hashstring>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::_M_find_before_node (this=this@entry=0x1c996e0,
__n=1510, __k="chen_kaish_flv", __code=2278699879894225472) at /usr/include/c++/4.8.2/bits/hashtable.h:1159
#1 0x000000000042a5e4 in _M_find_node (__c=out>, __key="chen_kaish_flv", __bkt=out>, this=0x1c996e0)
at /usr/include/c++/4.8.2/bits/hashtable.h:604
#2 std::_Hashtablestring, std::pairstring const, Channel*>, std::allocatorstring const, Channel*> >, std::__detail::_Se
lect1st, std::equal_tostring>, std::hashstring>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >::find (this=this@entry=0x1c996e0, __k="chen_kaish_flv")
at /usr/include/c++/4.8.2/bits/hashtable.h:1025
#3 0x0000000000427741 in find (__x="chen_kaish_flv", this=0x1c996e0) at /usr/include/c++/4.8.2/bits/unordered_map.h:543
#4 StrategyManager::AddChannel (this=0x1c996e0, channel="chen", domain="kaish", type="flv", ip="127.0.0.1", port=@0x7f610cdee6fe: 9090)
at ./src/strategy.cpp:371
#5 0x000000000040b61a in MainSoWork::AddChannel (this=0x1c98e80,
msg=0x7f6114694148 "{\"ip\":\"127.0.0.1\", \"port\":9090,\"channels\":[{\"channelid\":\"chen\",\"domain\":\"kaish\",\"videotype\":\"flv\"}]}", len=103) at ./src/MainSoWork.cpp:689
这个奇怪的地方是,程序中unordered_map对象已经构造,本身并不存在多线程并发访问这个对象,更不存在迭代器失效的操作。find导致coredump,有点理解不了。思来想去,觉得不太可能是stl中的find的原因。最后怀疑到可能是内存越界或者其他地方改变了unordered_map对象中相关的内存地址,导致find的时候操作错误的内存地址。用valgrind跑起来,没有提示有内存越界。最后就只能将代码版本前后对比,找到最新修改的地方,仔细阅读,果真找到了问题所在,原来是在某个地方声明了一个临时对象指针,没有置为NULL,也没有指向某个对象,然后在某个地方不小心对这个指针做了赋值操作,比如:
A *p;
p->data = 1;
p->next = p1;
以上这个操作,p虽然是在栈中的临时变量,但是没有初始化,p指向的地址(*p)是未知的,可能指向堆中其他地址。p->data、p->next的赋值,改变了一个未知地址的值,肯定会导致其他地方的内存错乱。我的这个例子中就是这个原因导致的。