delete twice会导致throw bad_alloc.
首先感叹下c++内存问题的复杂。昨晚同事发现了纠结的问题,一用lsocket(自己封装的socket),在数据库模块就发生bad_alloc,位置还相对固定;当时首先怀疑数据库
1.new的size太大,结果pdb看参数没有
2.怀疑堆栈破坏,看数据库模块看了半天,确实有一些c99的堆栈上分配,改之仍然不行
第二天想到可能确实是内存耗尽,但是因为逻辑层用的是内存池并且用的是malloc,所以逻辑层不会crash;而只有数据库在分配内存。但是如果不用lsocket就没有问题,看来症结还是在lsocket上,反复一次次尝试精确定位到了close lsocket上,相反一直连着没事
1。lsocket耗尽了内存就不像,因为dump只有300M
2。怀疑lsocket越界写了,我认为越界写的那么准——刚好破坏libc++.so的内存链表不大像,根据我的经验10次怀疑越界写结果一次都不是。
3。怀疑是new出来delete之后再次写了这个内存,导致c++的freelist的数据被破坏无法往下继续
那么仔细看lsocket的代码即可。发现close时某个指针delete两次,按照c++的说明delete两次是undefined behavior,结果这个undefined behavior导致了接下来的某个new会throw bad_alloc真是没有想到(注明:在64位freebsd上)。
这说明找bug第一让他容易重现,容易重现的bug才能解决;第二大胆怀疑严密推理,使用排除法;第三找关联,现场灯光下找不到就找上游;第四有个人在旁边聊下可以开拓思路,我就起了该作用;最后积累经验,当时确实想不到delete twice会导致throw bad_alloc.还补充一点,能用debug版本重现最好用,根据我的经验,在debug版本delete twice会直接抛异常,岂不早早的发现该错误了。