问题
运行的程序报错如下:
double free or corruption (fasttop)
从字面意思很容易知道是多次释放同一地址的内存导致的。
问题分析
通过gdb能到确认到出问题的代码行数,仔细分析过相关联的代码,却没有发现代码中存在什么问题。
一般遇到类似的情况,在实在看不出问题的时候,我都会采用逐步去掉不相关代码的方式来定位,但这种方式存在解决问题花费时间较长的问题。
本次尝试使用valgrind来定位,没想到有意想不到的惊喜。
执行valgrind命令
首先要保证代码编译是带上-g参数(集成代码symbol到可执行文件中),其次最好使用-O0或者-O(防止编译器过度优化)
执行命令如下
nohup valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --log-file=Valgrind.0918 [your program] > log &
valrind执行的速度很慢,因此最好后台运行,执行完成后会将扫描结果放到Valgrind.0918文件中
结果分析
首先定位到出现double free的分析日志中,它的基本格式如下:
==25551== Invalid free() / delete / delete[] / realloc()
==25551== [this is the code stack where problem come from]
==25551== Address 0x3a3c8390 is 0 bytes inside a block of size 16 free'd
==25551== at 0x4C2B5E1: operator delete[](void*) (in
==25551== [this is the code stack where the first release from]
它能将double free涉及到的代码段同时打印出来(根据问题情况,有可能是分配内存空间的代码)。
另外中间Address这行也能提供更详尽的信息,它的格式如下:
Address 0x???????? is {x} bytes {inside/before/after} a block of size {y} {alloc’d/free’d}
它表示了释放的地址与一个y
长度块的相对位置关系。如果地址位于块前,则用before
,位于块内则用inside
,块后则是after
。而最后的alloc’d
代表这个y
长度的块处于有效状态,其分配时的栈如下;而free’d
代表y长
度块已删除,其删除时的栈如下。
总结
valgrind能在保证程序不会core的情况,将存在double free的问题代码快速定位。