valgrind
这个厉害!比如其中的memcheck工具,跑一遍告诉你哪里越界访问了!yyds!gdb
细粒度跟踪(这个超级牛啊)- 可以不断确定要在哪里打断点,然后
r
,带着已经打的断点重新观察
经验
malloc abort 或者 delete报错(说二次释放可是其实没有)
heap is corrupt
:被程序写了不该写的地方,比如在数组/vector长度后面写东西
std::vector<VertexIdType> new_vps(problem_num*2);
//...
for(...)
new_vps[pos++] = vps[2 * i]; // 如果这里越界写,可能就会把heap搞坏
//下面这里可能就会abort
VertexIdType *ranges = new VertexIdType[batch_num * 2];
这个通常可以通过检查所有new来的原始数组的写入 是否有越界
来找原因,通常这个“所有数组”是 “在delete abort发生的数组 之前new申请的数组
”(这些数组都在堆上,如果这些数组写越界了,把后面申请的数组也写了,由于俩数组可能元素类型不一样,所以会出现heap crupt的问题)(说通常是因为,堆分配不一定是后面分配的地址在前面分配的后面,不过数组本身确实是连续内存)
或者是内存不够
delete or delete[]
Type* p = new Type;
如果是delete[] p
,会把p当做数组首地址去释放,这个数组的长度undefined,如果不是1的话会释放多次且是释放数组首地址+sizeof(数组元素)的地址
奇怪的段错误
比如某个向量奇怪的段错误:gdb检查下这个向量的entry(尤其头尾),看下是否有被写入junk(比如一些很大的数字)
如果被写入junk了,那么很可能是在“这个向量一切正常”的地方-“这个向量异常”的地方之间、写入的某个数组或向量等越界了
注意,数组和向量越界都不会有内置的告警!!!
future wait
用future wait框架写的,里面会生成个线程来跑你的异步程序,注意你的程序中可能部分异常不会有提示而是直接安静退出!
调试奇妙的程序终止时建议把future框架暂时去掉,让你的程序不是在future生成的线程里面跑