一、前言
对于C/C++程序员来说,关于内存问题真是让人头痛不已,尤其是内存泄露、使用未初始化的局部变量进行跳转或移动等隐形问题。要求程序员养成良好的编码习惯确实很重要,但是人总会出现稀里糊涂的时候,遇到内存泄露等问题还是在所难免,好在有了众多的内存检测工具,真是帮了程序员的大忙啊。下面将介绍一款强大的Linux开源工具Valgrind,非常棒,内存检测工具中的瑞士军刀。
二、简介
Valgrind 是一款 Linux下C/C++程序的内存检测工具,一个显著的特点是无需重新编译,可以直接对debug版本的程序进行分析测试。
目前,最新的版本valgrind-3.8.1支持X86/Linux, AMD64/Linux, ARM/Linux, PPC32/Linux, PPC64/Linux,
S390X/Linux, MIPS/Linux, ARM/Android (2.3.x and later), X86/Android (4.0 and later), X86/Darwin and AMD64/Darwin (Mac OS X 10.6 and 10.7, with limited support for 10.8)。
相关资料:
1、http://valgrind.org/ (官网,资料全面,很详实,但全是英文,全力推荐)
2、http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/ (IBM的中文资料,很详细,全力推荐)
3、http://blog.csdn.net/yanghao23/article/details/7514587 (网友的总结体会,写得好)
三、快速入门
1、下载与安装
上官网下载最新版本:valgrind-3.8.1,按如下步骤在解压并进行默认安装:
tar xvf valgrind-3.8.1.tar.bz2 cd valgrind-3.8.1/ ./configure make make install
2、快速使用(对Linux系统的程序“ls”进行检测)
valgrind ls / (快速进行默认Memcheck检测)
valgrind --leak-check=full --track-origins=yes -v ls / (进行Memcheck检测,并打印详细的结果,不过速度慢了很多,这个我用得更多)
root@root:/media/workspace/# valgrind ls /
==20361== Memcheck, a memory error detector
==20361== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==20361== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==20361== Command: ls /
==20361==
bin cdrom dev gnome-terminal.desktop initrd.img lib lib64 media opt root selinux swap tftpboot tmp var vmlinuz.old
boot data etc home initrd.img.old lib32 lost+found mnt proc sbin srv sys tftpboot.bak usr vmlinuz
==20361==
==20361== HEAP SUMMARY:
==20361== in use at exit: 33,197 bytes in 38 blocks
==20361== total heap usage: 567 allocs, 529 frees, 97,898 bytes allocated
==20361==
==20361== LEAK SUMMARY:
==20361== definitely lost: 120 bytes in 1 blocks 【哎呦,居然有内存泄露,奇怪,系统的问题,咱管不了它的代码,skip it】
==20361== indirectly lost: 0 bytes in 0 blocks
==20361== possibly lost: 0 bytes in 0 blocks
==20361== still reachable: 33,077 bytes in 37 blocks
==20361== suppressed: 0 bytes in 0 blocks
==20361== Rerun with --leak-check=full to see details of leaked memory
==20361==
==20361== For counts of detected and suppressed errors, rerun with: -v
==20361== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 【哦哦,还好,没有其它错误】
root@root:/media/workspace/#
==20361== Memcheck, a memory error detector
==20361== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==20361== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==20361== Command: ls /
==20361==
bin cdrom dev gnome-terminal.desktop initrd.img lib lib64 media opt root selinux swap tftpboot tmp var vmlinuz.old
boot data etc home initrd.img.old lib32 lost+found mnt proc sbin srv sys tftpboot.bak usr vmlinuz
==20361==
==20361== HEAP SUMMARY:
==20361== in use at exit: 33,197 bytes in 38 blocks
==20361== total heap usage: 567 allocs, 529 frees, 97,898 bytes allocated
==20361==
==20361== LEAK SUMMARY:
==20361== definitely lost: 120 bytes in 1 blocks 【哎呦,居然有内存泄露,奇怪,系统的问题,咱管不了它的代码,skip it】
==20361== indirectly lost: 0 bytes in 0 blocks
==20361== possibly lost: 0 bytes in 0 blocks
==20361== still reachable: 33,077 bytes in 37 blocks
==20361== suppressed: 0 bytes in 0 blocks
==20361== Rerun with --leak-check=full to see details of leaked memory
==20361==
==20361== For counts of detected and suppressed errors, rerun with: -v
==20361== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4) 【哦哦,还好,没有其它错误】
root@root:/media/workspace/#
root@root:/media/workspace# valgrind --leak-check=full --track-origins=yes -v
ls /
==21828== Memcheck, a memory error detector
==21828== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==21828== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==21828== Command: ls /
==21828==
--21828-- Valgrind options:
--21828-- --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
--21828-- --leak-check=full
--21828-- --track-origins=yes
--21828-- -v
--21828-- Contents of /proc/version:
--21828-- Linux version 2.6.32-45-generic (buildd@batsu) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) ) #101-Ubuntu SMP Mon Dec 3 15:39:38 UTC 2012
--21828-- Arch and hwcaps: AMD64, amd64-sse3-cx16
--21828-- Page sizes: currently 4096, max supported 4096
--21828-- Valgrind library directory: /usr/lib/valgrind
--21828-- Reading syms from /bin/ls (0x400000)
--21828-- Reading debug info from /bin/ls ..
--21828-- .. CRC mismatch (computed d5468613 wanted 88b6ebd9)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/ld-2.11.1.so (0x4000000)
--21828-- Reading debug info from /lib/ld-2.11.1.so ..
--21828-- .. CRC mismatch (computed f7ae097b wanted a9b86b80)
--21828-- Reading debug info from /usr/lib/debug/lib/ld-2.11.1.so ..
--21828-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux (0x38000000)
--21828-- object doesn't have a dynamic symbol table
--21828-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
--21828-- Reading suppressions file: /usr/lib/valgrind/default.supp
--21828-- REDIR: 0x40183b0 (strlen) redirected to 0x380402d7 (vgPlain_amd64_linux_REDIR_FOR_strlen)
--21828-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so (0x4a22000)
--21828-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so (0x4c24000)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x040183b0 (strlen ) R-> 0x04c28710 strlen
--21828-- REDIR: 0x4018220 (index) redirected to 0x4c28320 (index)
--21828-- REDIR: 0x40182a0 (strcmp) redirected to 0x4c28cf0 (strcmp)
--21828-- Reading syms from /lib/librt-2.11.1.so (0x4e2d000)
--21828-- Reading debug info from /lib/librt-2.11.1.so ..
--21828-- .. CRC mismatch (computed 8fbc67b2 wanted c6419430)
--21828-- Reading debug info from /usr/lib/debug/lib/librt-2.11.1.so ..
--21828-- Reading syms from /lib/libselinux.so.1 (0x5035000)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/libacl.so.1.1.0 (0x5253000)
--21828-- Reading debug info from /lib/libacl.so.1.1.0 ..
--21828-- .. CRC mismatch (computed c1ea3c04 wanted 297d6d26)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/libc-2.11.1.so (0x545b000)
--21828-- Reading debug info from /lib/libc-2.11.1.so ..
--21828-- .. CRC mismatch (computed 6b23738b wanted c0dae497)
--21828-- Reading debug info from /usr/lib/debug/lib/libc-2.11.1.so ..
--21828-- Reading syms from /lib/libpthread-2.11.1.so (0x57e1000)
--21828-- Reading debug info from /lib/libpthread-2.11.1.so ..
--21828-- .. CRC mismatch (computed d460a184 wanted 81aea168)
--21828-- Reading debug info from /usr/lib/debug/lib/libpthread-2.11.1.so ..
--21828-- Reading syms from /lib/libdl-2.11.1.so (0x59fe000)
--21828-- Reading debug info from /lib/libdl-2.11.1.so ..
--21828-- .. CRC mismatch (computed 06532688 wanted 2f6eef4b)
--21828-- Reading debug info from /usr/lib/debug/lib/libdl-2.11.1.so ..
--21828-- Reading syms from /lib/libattr.so.1.1.0 (0x5c02000)
--21828-- Reading debug info from /lib/libattr.so.1.1.0 ..
--21828-- .. CRC mismatch (computed aa603317 wanted 08b26063)
--21828-- object doesn't have a symbol table
--21828-- REDIR: 0x54e1100 (__GI_strrchr) redirected to 0x4c28140 (__GI_strrchr)
--21828-- REDIR: 0x54d8b20 (malloc) redirected to 0x4c27426 (malloc)
--21828-- REDIR: 0x54e1810 (memchr) redirected to 0x4c28d90 (memchr)
--21828-- REDIR: 0x54e3290 (memcpy) redirected to 0x4c28dc0 (memcpy)
--21828-- REDIR: 0x54ddb50 (__GI_strchr) redirected to 0x4c28220 (__GI_strchr)
--21828-- REDIR: 0x54da410 (free) redirected to 0x4c27036 (free)
--21828-- REDIR: 0x54e10d0 (rindex) redirected to 0x4a225dc (_vgnU_ifunc_wrapper)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x054e1100 (__GI_strrchr ) R-> 0x04c28110 rindex
--21828-- REDIR: 0x54ddc10 (__GI_strcmp) redirected to 0x4c28ca0 (__GI_strcmp)
--21828-- REDIR: 0x54df640 (__GI_strlen) redirected to 0x4c286d0 (__GI_strlen)
--21828-- REDIR: 0x54df850 (__GI_strncmp) redirected to 0x4c28be0 (__GI_strncmp)
--21828-- REDIR: 0x54e4870 (strchrnul) redirected to 0x4c29a10 (strchrnul)
--21828-- REDIR: 0x54e29b0 (mempcpy) redirected to 0x4c29a80 (mempcpy)
--21828-- REDIR: 0x54da5c0 (realloc) redirected to 0x4c274d7 (realloc)
--21828-- REDIR: 0x54df690 (strnlen) redirected to 0x4c28630 (strnlen)
--21828-- REDIR: 0x54e2ff0 (__GI_stpcpy) redirected to 0x4c296c0 (__GI_stpcpy)
--21828-- REDIR: 0x54df090 (__GI_strcpy) redirected to 0x4c28800 (__GI_strcpy)
--21828-- REDIR: 0x54e4820 (__GI___rawmemchr) redirected to 0x4c29a60 (__GI___rawmemchr)
--21828-- REDIR: 0x54df610 (strlen) redirected to 0x4a225dc (_vgnU_ifunc_wrapper)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x054df640 (__GI_strlen ) R-> 0x04c286b0 strlen
--21828-- REDIR: 0x54e1cc0 (memmove) redirected to 0x4c299a0 (memmove)
bin cdrom dev gnome-terminal.desktop initrd.img lib lib64 media opt root selinux swap tftpboot tmp var vmlinuz.old
boot data etc home initrd.img.old lib32 lost+found mnt proc sbin srv sys tftpboot.bak usr vmlinuz
==21828==
==21828== HEAP SUMMARY:
==21828== in use at exit: 33,197 bytes in 38 blocks
==21828== total heap usage: 567 allocs, 529 frees, 97,898 bytes allocated
==21828==
==21828== Searching for pointers to 38 not-freed blocks
==21828== Checked 144,976 bytes
==21828==
==21828== 120 bytes in 1 blocks are definitely lost in loss record 3 of 8
==21828== at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==21828== by 0x54C5748: getdelim (iogetdelim.c:68)
==21828== by 0x5041EB2: ??? (in /lib/libselinux.so.1)
==21828== by 0x504A465: ??? (in /lib/libselinux.so.1)
==21828== by 0x503A2D2: ??? (in /lib/libselinux.so.1)
==21828== by 0x7FF0007CD: ???
==21828== by 0x207C3D4E45504F52: ???
==21828== by 0x6E69622F7273752E: ???
==21828== by 0x7069707373656C2E: ???
==21828== by 0x4E414C0073252064: ???
==21828== by 0x687A3D4547415546: ???
==21828== by 0x5500687A3A4E435E: ???
==21828==
==21828== LEAK SUMMARY:
==21828== definitely lost: 120 bytes in 1 blocks
==21828== indirectly lost: 0 bytes in 0 blocks
==21828== possibly lost: 0 bytes in 0 blocks
==21828== still reachable: 33,077 bytes in 37 blocks
==21828== suppressed: 0 bytes in 0 blocks
==21828== Reachable blocks (those to which a pointer was found) are not shown.
==21828== To see them, rerun with: --leak-check=full --show-reachable=yes
==21828==
==21828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
--21828--
--21828-- used_suppression: 2 dl-hack3-cond-1
--21828-- used_suppression: 2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
==21828==
==21828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
root@root:/media/workspace#
==21828== Memcheck, a memory error detector
==21828== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==21828== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==21828== Command: ls /
==21828==
--21828-- Valgrind options:
--21828-- --suppressions=/usr/lib/valgrind/debian-libc6-dbg.supp
--21828-- --leak-check=full
--21828-- --track-origins=yes
--21828-- -v
--21828-- Contents of /proc/version:
--21828-- Linux version 2.6.32-45-generic (buildd@batsu) (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) ) #101-Ubuntu SMP Mon Dec 3 15:39:38 UTC 2012
--21828-- Arch and hwcaps: AMD64, amd64-sse3-cx16
--21828-- Page sizes: currently 4096, max supported 4096
--21828-- Valgrind library directory: /usr/lib/valgrind
--21828-- Reading syms from /bin/ls (0x400000)
--21828-- Reading debug info from /bin/ls ..
--21828-- .. CRC mismatch (computed d5468613 wanted 88b6ebd9)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/ld-2.11.1.so (0x4000000)
--21828-- Reading debug info from /lib/ld-2.11.1.so ..
--21828-- .. CRC mismatch (computed f7ae097b wanted a9b86b80)
--21828-- Reading debug info from /usr/lib/debug/lib/ld-2.11.1.so ..
--21828-- Reading syms from /usr/lib/valgrind/memcheck-amd64-linux (0x38000000)
--21828-- object doesn't have a dynamic symbol table
--21828-- Reading suppressions file: /usr/lib/valgrind/debian-libc6-dbg.supp
--21828-- Reading suppressions file: /usr/lib/valgrind/default.supp
--21828-- REDIR: 0x40183b0 (strlen) redirected to 0x380402d7 (vgPlain_amd64_linux_REDIR_FOR_strlen)
--21828-- Reading syms from /usr/lib/valgrind/vgpreload_core-amd64-linux.so (0x4a22000)
--21828-- Reading syms from /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so (0x4c24000)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x040183b0 (strlen ) R-> 0x04c28710 strlen
--21828-- REDIR: 0x4018220 (index) redirected to 0x4c28320 (index)
--21828-- REDIR: 0x40182a0 (strcmp) redirected to 0x4c28cf0 (strcmp)
--21828-- Reading syms from /lib/librt-2.11.1.so (0x4e2d000)
--21828-- Reading debug info from /lib/librt-2.11.1.so ..
--21828-- .. CRC mismatch (computed 8fbc67b2 wanted c6419430)
--21828-- Reading debug info from /usr/lib/debug/lib/librt-2.11.1.so ..
--21828-- Reading syms from /lib/libselinux.so.1 (0x5035000)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/libacl.so.1.1.0 (0x5253000)
--21828-- Reading debug info from /lib/libacl.so.1.1.0 ..
--21828-- .. CRC mismatch (computed c1ea3c04 wanted 297d6d26)
--21828-- object doesn't have a symbol table
--21828-- Reading syms from /lib/libc-2.11.1.so (0x545b000)
--21828-- Reading debug info from /lib/libc-2.11.1.so ..
--21828-- .. CRC mismatch (computed 6b23738b wanted c0dae497)
--21828-- Reading debug info from /usr/lib/debug/lib/libc-2.11.1.so ..
--21828-- Reading syms from /lib/libpthread-2.11.1.so (0x57e1000)
--21828-- Reading debug info from /lib/libpthread-2.11.1.so ..
--21828-- .. CRC mismatch (computed d460a184 wanted 81aea168)
--21828-- Reading debug info from /usr/lib/debug/lib/libpthread-2.11.1.so ..
--21828-- Reading syms from /lib/libdl-2.11.1.so (0x59fe000)
--21828-- Reading debug info from /lib/libdl-2.11.1.so ..
--21828-- .. CRC mismatch (computed 06532688 wanted 2f6eef4b)
--21828-- Reading debug info from /usr/lib/debug/lib/libdl-2.11.1.so ..
--21828-- Reading syms from /lib/libattr.so.1.1.0 (0x5c02000)
--21828-- Reading debug info from /lib/libattr.so.1.1.0 ..
--21828-- .. CRC mismatch (computed aa603317 wanted 08b26063)
--21828-- object doesn't have a symbol table
--21828-- REDIR: 0x54e1100 (__GI_strrchr) redirected to 0x4c28140 (__GI_strrchr)
--21828-- REDIR: 0x54d8b20 (malloc) redirected to 0x4c27426 (malloc)
--21828-- REDIR: 0x54e1810 (memchr) redirected to 0x4c28d90 (memchr)
--21828-- REDIR: 0x54e3290 (memcpy) redirected to 0x4c28dc0 (memcpy)
--21828-- REDIR: 0x54ddb50 (__GI_strchr) redirected to 0x4c28220 (__GI_strchr)
--21828-- REDIR: 0x54da410 (free) redirected to 0x4c27036 (free)
--21828-- REDIR: 0x54e10d0 (rindex) redirected to 0x4a225dc (_vgnU_ifunc_wrapper)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x054e1100 (__GI_strrchr ) R-> 0x04c28110 rindex
--21828-- REDIR: 0x54ddc10 (__GI_strcmp) redirected to 0x4c28ca0 (__GI_strcmp)
--21828-- REDIR: 0x54df640 (__GI_strlen) redirected to 0x4c286d0 (__GI_strlen)
--21828-- REDIR: 0x54df850 (__GI_strncmp) redirected to 0x4c28be0 (__GI_strncmp)
--21828-- REDIR: 0x54e4870 (strchrnul) redirected to 0x4c29a10 (strchrnul)
--21828-- REDIR: 0x54e29b0 (mempcpy) redirected to 0x4c29a80 (mempcpy)
--21828-- REDIR: 0x54da5c0 (realloc) redirected to 0x4c274d7 (realloc)
--21828-- REDIR: 0x54df690 (strnlen) redirected to 0x4c28630 (strnlen)
--21828-- REDIR: 0x54e2ff0 (__GI_stpcpy) redirected to 0x4c296c0 (__GI_stpcpy)
--21828-- REDIR: 0x54df090 (__GI_strcpy) redirected to 0x4c28800 (__GI_strcpy)
--21828-- REDIR: 0x54e4820 (__GI___rawmemchr) redirected to 0x4c29a60 (__GI___rawmemchr)
--21828-- REDIR: 0x54df610 (strlen) redirected to 0x4a225dc (_vgnU_ifunc_wrapper)
==21828== WARNING: new redirection conflicts with existing -- ignoring it
--21828-- new: 0x054df640 (__GI_strlen ) R-> 0x04c286b0 strlen
--21828-- REDIR: 0x54e1cc0 (memmove) redirected to 0x4c299a0 (memmove)
bin cdrom dev gnome-terminal.desktop initrd.img lib lib64 media opt root selinux swap tftpboot tmp var vmlinuz.old
boot data etc home initrd.img.old lib32 lost+found mnt proc sbin srv sys tftpboot.bak usr vmlinuz
==21828==
==21828== HEAP SUMMARY:
==21828== in use at exit: 33,197 bytes in 38 blocks
==21828== total heap usage: 567 allocs, 529 frees, 97,898 bytes allocated
==21828==
==21828== Searching for pointers to 38 not-freed blocks
==21828== Checked 144,976 bytes
==21828==
==21828== 120 bytes in 1 blocks are definitely lost in loss record 3 of 8
==21828== at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==21828== by 0x54C5748: getdelim (iogetdelim.c:68)
==21828== by 0x5041EB2: ??? (in /lib/libselinux.so.1)
==21828== by 0x504A465: ??? (in /lib/libselinux.so.1)
==21828== by 0x503A2D2: ??? (in /lib/libselinux.so.1)
==21828== by 0x7FF0007CD: ???
==21828== by 0x207C3D4E45504F52: ???
==21828== by 0x6E69622F7273752E: ???
==21828== by 0x7069707373656C2E: ???
==21828== by 0x4E414C0073252064: ???
==21828== by 0x687A3D4547415546: ???
==21828== by 0x5500687A3A4E435E: ???
==21828==
==21828== LEAK SUMMARY:
==21828== definitely lost: 120 bytes in 1 blocks
==21828== indirectly lost: 0 bytes in 0 blocks
==21828== possibly lost: 0 bytes in 0 blocks
==21828== still reachable: 33,077 bytes in 37 blocks
==21828== suppressed: 0 bytes in 0 blocks
==21828== Reachable blocks (those to which a pointer was found) are not shown.
==21828== To see them, rerun with: --leak-check=full --show-reachable=yes
==21828==
==21828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
--21828--
--21828-- used_suppression: 2 dl-hack3-cond-1
--21828-- used_suppression: 2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a
==21828==
==21828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
root@root:/media/workspace#