之前介绍过利用valgrind来定位内存泄漏(慢性病, 会导致程序在某个不确定的时刻异常), 本文我们来简要介绍利用valgrind来定位内存的重复释放(急性病, 会报纸程序崩溃)。 看程序:
#include <stdio.h> #include <stdlib.h> #include <memory.h> int main() { char *p = (char *)malloc(30); free(p); free(p); return 0; } 我们用valgrind来检测一下: [root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==18229== Memcheck, a memory error detector ==18229== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==18229== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==18229== Command: ./a.out ==18229== ==18229== Invalid free() / delete / delete[] / realloc() ==18229== at 0x4C27300: free (vg_replace_malloc.c:446) ==18229== by 0x400611: main (test.cpp:9) ==18229== Address 0x5d84040 is 0 bytes inside a block of size 30 free'd ==18229== at 0x4C27300: free (vg_replace_malloc.c:446) ==18229== by 0x400605: main (test.cpp:8) ==18229== ==18229== ==18229== HEAP SUMMARY: ==18229== in use at exit: 0 bytes in 0 blocks ==18229== total heap usage: 1 allocs, 2 frees, 30 bytes allocated ==18229== ==18229== All heap blocks were freed -- no leaks are possible ==18229== ==18229== For counts of detected and suppressed errors, rerun with: -v ==18229== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6) [root@xxx ~/valgrind-3.8.1/bin]#很容易看到, 第9行错误释放(重复释放)。 如果直接执行a.out程序, 会出现什么问题呢? 程序直接崩溃了, abort了, 如下:
[root@xxx ~/valgrind-3.8.1/bin]# ./a.out *** glibc detected *** ./a.out: double free or corruption (fasttop): 0x00000000011b1010 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x75e66)[0x7f9877755e66] ./a.out[0x400612] /lib64/libc.so.6(__libc_start_main+0xfd)[0x7f98776fed5d] ./a.out[0x400529] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 fd:01 562221 /root/valgrind-3.8.1/bin/a.out 00600000-00601000 rw-p 00000000 fd:01 562221 /root/valgrind-3.8.1/bin/a.out 011b1000-011d2000 rw-p 00000000 00:00 0 [heap] 7f98772bf000-7f98772d6000 r-xp 00000000 fd:01 309668 /lib64/libpthread-2.12.so 7f98772d6000-7f98774d6000 ---p 00017000 fd:01 309668 /lib64/libpthread-2.12.so 7f98774d6000-7f98774d7000 r--p 00017000 fd:01 309668 /lib64/libpthread-2.12.so 7f98774d7000-7f98774d8000 rw-p 00018000 fd:01 309668 /lib64/libpthread-2.12.so 7f98774d8000-7f98774dc000 rw-p 00000000 00:00 0 7f98774dc000-7f98774de000 r-xp 00000000 fd:01 309538 /lib64/libdl-2.12.so 7f98774de000-7f98776de000 ---p 00002000 fd:01 309538 /lib64/libdl-2.12.so 7f98776de000-7f98776df000 r--p 00002000 fd:01 309538 /lib64/libdl-2.12.so 7f98776df000-7f98776e0000 rw-p 00003000 fd:01 309538 /lib64/libdl-2.12.so 7f98776e0000-7f987786a000 r-xp 00000000 fd:01 309509 /lib64/libc-2.12.so 7f987786a000-7f9877a6a000 ---p 0018a000 fd:01 309509 /lib64/libc-2.12.so 7f9877a6a000-7f9877a6e000 r--p 0018a000 fd:01 309509 /lib64/libc-2.12.so 7f9877a6e000-7f9877a6f000 rw-p 0018e000 fd:01 309509 /lib64/libc-2.12.so 7f9877a6f000-7f9877a74000 rw-p 00000000 00:00 0 7f9877a74000-7f9877a8a000 r-xp 00000000 fd:01 309558 /lib64/libgcc_s-4.4.6-20110824.so.1 7f9877a8a000-7f9877c89000 ---p 00016000 fd:01 309558 /lib64/libgcc_s-4.4.6-20110824.so.1 7f9877c89000-7f9877c8a000 rw-p 00015000 fd:01 309558 /lib64/libgcc_s-4.4.6-20110824.so.1 7f9877c8a000-7f9877d0d000 r-xp 00000000 fd:01 309608 /lib64/libm-2.12.so 7f9877d0d000-7f9877f0c000 ---p 00083000 fd:01 309608 /lib64/libm-2.12.so 7f9877f0c000-7f9877f0d000 r--p 00082000 fd:01 309608 /lib64/libm-2.12.so 7f9877f0d000-7f9877f0e000 rw-p 00083000 fd:01 309608 /lib64/libm-2.12.so 7f9877f0e000-7f9877ff6000 r-xp 00000000 fd:01 171070 /usr/lib64/libstdc++.so.6.0.13 7f9877ff6000-7f98781f6000 ---p 000e8000 fd:01 171070 /usr/lib64/libstdc++.so.6.0.13 7f98781f6000-7f98781fd000 r--p 000e8000 fd:01 171070 /usr/lib64/libstdc++.so.6.0.13 7f98781fd000-7f98781ff000 rw-p 000ef000 fd:01 171070 /usr/lib64/libstdc++.so.6.0.13 7f98781ff000-7f9878214000 rw-p 00000000 00:00 0 7f9878214000-7f9878234000 r-xp 00000000 fd:01 309485 /lib64/ld-2.12.so 7f987830f000-7f9878314000 rw-p 00000000 00:00 0 7f9878322000-7f9878323000 rw-p 00000000 00:00 0 7f9878323000-7f9878326000 r-xp 00000000 fd:01 309900 /lib64/libonion_security.so.1.0.13 7f9878326000-7f9878426000 ---p 00003000 fd:01 309900 /lib64/libonion_security.so.1.0.13 7f9878426000-7f9878427000 rw-p 00003000 fd:01 309900 /lib64/libonion_security.so.1.0.13 7f9878427000-7f9878433000 rw-p 00000000 00:00 0 7f9878433000-7f9878434000 r--p 0001f000 fd:01 309485 /lib64/ld-2.12.so 7f9878434000-7f9878435000 rw-p 00020000 fd:01 309485 /lib64/ld-2.12.so 7f9878435000-7f9878436000 rw-p 00000000 00:00 0 7fffc2f9b000-7fffc2fbc000 rw-p 00000000 00:00 0 [stack] 7fffc2ffe000-7fffc3000000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted [root@xxx ~/valgrind-3.8.1/bin]#如果是这种程序呢?
#include <stdio.h> #include <stdlib.h> #include <memory.h> int main() { char szTest[100] = {0}; char *p = szTest; free(p); return 0; } 编译运行一下: [root@xxx ~/valgrind-3.8.1/bin]# g++ -g test.cpp [root@xxx ~/valgrind-3.8.1/bin]# ./a.out Segmentation fault [root@xxx ~/valgrind-3.8.1/bin]# ulimit -c unlimited [root@xxx ~/valgrind-3.8.1/bin]# ./a.out Segmentation fault (core dumped) [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# [root@xxx ~/valgrind-3.8.1/bin]# ./valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out ==22452== Memcheck, a memory error detector ==22452== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==22452== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==22452== Command: ./a.out ==22452== ==22452== Invalid free() / delete / delete[] / realloc() ==22452== at 0x4C27300: free (vg_replace_malloc.c:446) ==22452== by 0x4005DC: main (test.cpp:9) ==22452== Address 0x7ff000470 is on thread 1's stack ==22452== ==22452== ==22452== HEAP SUMMARY: ==22452== in use at exit: 0 bytes in 0 blocks ==22452== total heap usage: 0 allocs, 1 frees, 0 bytes allocated ==22452== ==22452== All heap blocks were freed -- no leaks are possible ==22452== ==22452== For counts of detected and suppressed errors, rerun with: -v ==22452== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6) [root@xxx ~/valgrind-3.8.1/bin]# 可以看到, 程序直接崩溃, segment fault了, 如果打开core开关, 看可以看到core dump的文件。 在这种情况下, 我们也可以利用valgrind来检测。
OK, 先说这么多。
涛歌依旧 认证博客专家 排名第一 点链接学人工智能 公众号免费领资料 ❤️零基础入门进阶人工智能 ❤️欢迎关注涛哥公众号,免费领海量学习资料。涛哥:毕业后就职于华为和腾讯。微信:ai_taogeyijiu