Valgrind是一款用于内存调试、检测内存泄露、分析程序性能的工具。Valgrind工作在Linux环境下。Valgrind的官方网站是: http://valgrind.org。
在Linux系统下,可以用命令wget http://valgrind.org/downloads/valgrind-3.7.0.tar.bz2来下载valgrind。
Valgrind语法是:
valgrind [valgrind options] your_program [your_program options]
一些启动参数的意义:
-h --help 帮助信息
-q --quiet 安静模式
--version 显示版本
-v --verbose 显示详细信息
--trace-children=<yes|no> 是否追踪子进程[默认no]
--log-file=<filename> 将输出打印到文件
--xml=<yes|no> 以xml格式输出
--leak-check=<no|summary|full> 是否进行内存泄露检查[默认summary]
--xml-file=<filename> 制定xml输出文件
--vgdb=<no|yes|full> 是否使用gdb调试
valgrind会将一个库函数,比如malloc、new等重新定位为valgrind内部的函数,来检查内存使用情况。当valgrind监测到内存使用问题时,会立即输出结果,而不是像gprof那样,在程序调正常退出时才输出结果。当使用valgrind运行程序时,如果使用了--vgdb=yes或者--vgdb=full,可以使用GDB来调试程序。方法如下:
valgrind --vgdb=yes ./your_program
gdb your_program
(gdb) target remote | vgdb --pid=YOUR_PROGRAM_PID
其中,--pid部分不是必须的,但如果有多个your_program在运行,必须使用这个参数时vgdb找到正确的进程。
valgrind可以检测内存泄露、非法指针、未初始化变量、非法释放。valgrind不检查静态数组的访问越界。
下面给出一个例子:
/*
* ValgrindSample.cpp
*
* g++ -g -o ValgrindSample ValgrindSample.cpp
* valgrind --leak-check=full --log-file=ValgrindSample.report ./ValgrindSample
*/
#include <cstdlib>
#include <new>
void memoryLeak(void);
void invalidPointer(void);
void uninitializedVariable(void);
void invalidRelease(void);
void outOfRange(void);
int main(void){
memoryLeak();
invalidPointer();
uninitializedVariable();
invalidRelease();
outOfRange();
return 0;
}
void memoryLeak(void){
void *p = malloc(10);
int *pi = new int(0);
}
void invalidPointer(void){
char *pc = (char *)malloc(10);
pc[10] = 'a';
}
void uninitializedVariable(void){
int x;
int y;
if (x != 0){
y = x + 1;
}
}
void invalidRelease(void){
void *p =malloc(10);
free(p);
free(p);
int *pi = new int(0);
delete pi;
delete pi;
}
void outOfRange(void){
char x[10];
x[11] = 'a';
}
valgrind输出:
==8349== Memcheck, a memory error detector
==8349== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8349== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8349== Command: ./a.out
==8349== Parent PID: 7943
==8349==
==8349== Invalid write of size 1
==8349== at 0x4006A6: invalidPointer() (ValgrindSample.cpp:35)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349== Address 0x4c200ea is 0 bytes after a block of size 10 alloc'd
==8349== at 0x4A0776F: malloc (vg_replace_malloc.c:263)
==8349== by 0x400699: invalidPointer() (ValgrindSample.cpp:34)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349==
==8349== Conditional jump or move depends on uninitialised value(s)
==8349== at 0x400670: uninitializedVariable() (ValgrindSample.cpp:42)
==8349== by 0x40073A: main (ValgrindSample.cpp:21)
==8349==
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006FF: invalidRelease() (ValgrindSample.cpp:50)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20130 is 0 bytes inside a block of size 10 free'd
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006F6: invalidRelease() (ValgrindSample.cpp:49)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349==
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x400725: invalidRelease() (ValgrindSample.cpp:54)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20180 is 0 bytes inside a block of size 4 free'd
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x40071C: invalidRelease() (ValgrindSample.cpp:53)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349==
==8349==
==8349== HEAP SUMMARY:
==8349== in use at exit: 24 bytes in 3 blocks
==8349== total heap usage: 5 allocs, 4 frees, 38 bytes allocated
==8349==
==8349== LEAK SUMMARY:
==8349== definitely lost: 24 bytes in 3 blocks
==8349== indirectly lost: 0 bytes in 0 blocks
==8349== possibly lost: 0 bytes in 0 blocks
==8349== still reachable: 0 bytes in 0 blocks
==8349== suppressed: 0 bytes in 0 blocks
==8349== Rerun with --leak-check=full to see details of leaked memory
==8349==
==8349== For counts of detected and suppressed errors, rerun with: -v
==8349== Use --track-origins=yes to see where uninitialised values come from
==8349== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)
参考资料:
valgrind官方网站:www.valgrind.org
一份valgrind --help的翻译:http://www.cppblog.com/Wealth/archive/2008/06/04/52118.html
通过例子介绍valgrind用法:http://www.cprogramming.com/debugging/valgrind.html
valgrind用法简介:http://www.cnblogs.com/napoleon_liu/articles/2001802.html
http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/
http://www.redhat.com/magazine/015jan06/features/valgrind/
http://www.stlinux.com/devel/debug/mudflap
http://rdc.taobao.com/blog/cs/?p=455
在Linux系统下,可以用命令wget http://valgrind.org/downloads/valgrind-3.7.0.tar.bz2来下载valgrind。
Valgrind语法是:
valgrind [valgrind options] your_program [your_program options]
一些启动参数的意义:
-h --help 帮助信息
-q --quiet 安静模式
--version 显示版本
-v --verbose 显示详细信息
--trace-children=<yes|no> 是否追踪子进程[默认no]
--log-file=<filename> 将输出打印到文件
--xml=<yes|no> 以xml格式输出
--leak-check=<no|summary|full> 是否进行内存泄露检查[默认summary]
--xml-file=<filename> 制定xml输出文件
--vgdb=<no|yes|full> 是否使用gdb调试
valgrind会将一个库函数,比如malloc、new等重新定位为valgrind内部的函数,来检查内存使用情况。当valgrind监测到内存使用问题时,会立即输出结果,而不是像gprof那样,在程序调正常退出时才输出结果。当使用valgrind运行程序时,如果使用了--vgdb=yes或者--vgdb=full,可以使用GDB来调试程序。方法如下:
valgrind --vgdb=yes ./your_program
gdb your_program
(gdb) target remote | vgdb --pid=YOUR_PROGRAM_PID
其中,--pid部分不是必须的,但如果有多个your_program在运行,必须使用这个参数时vgdb找到正确的进程。
valgrind可以检测内存泄露、非法指针、未初始化变量、非法释放。valgrind不检查静态数组的访问越界。
下面给出一个例子:
/*
* ValgrindSample.cpp
*
* g++ -g -o ValgrindSample ValgrindSample.cpp
* valgrind --leak-check=full --log-file=ValgrindSample.report ./ValgrindSample
*/
#include <cstdlib>
#include <new>
void memoryLeak(void);
void invalidPointer(void);
void uninitializedVariable(void);
void invalidRelease(void);
void outOfRange(void);
int main(void){
memoryLeak();
invalidPointer();
uninitializedVariable();
invalidRelease();
outOfRange();
return 0;
}
void memoryLeak(void){
void *p = malloc(10);
int *pi = new int(0);
}
void invalidPointer(void){
char *pc = (char *)malloc(10);
pc[10] = 'a';
}
void uninitializedVariable(void){
int x;
int y;
if (x != 0){
y = x + 1;
}
}
void invalidRelease(void){
void *p =malloc(10);
free(p);
free(p);
int *pi = new int(0);
delete pi;
delete pi;
}
void outOfRange(void){
char x[10];
x[11] = 'a';
}
valgrind输出:
==8349== Memcheck, a memory error detector
==8349== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8349== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8349== Command: ./a.out
==8349== Parent PID: 7943
==8349==
==8349== Invalid write of size 1
==8349== at 0x4006A6: invalidPointer() (ValgrindSample.cpp:35)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349== Address 0x4c200ea is 0 bytes after a block of size 10 alloc'd
==8349== at 0x4A0776F: malloc (vg_replace_malloc.c:263)
==8349== by 0x400699: invalidPointer() (ValgrindSample.cpp:34)
==8349== by 0x400735: main (ValgrindSample.cpp:20)
==8349==
==8349== Conditional jump or move depends on uninitialised value(s)
==8349== at 0x400670: uninitializedVariable() (ValgrindSample.cpp:42)
==8349== by 0x40073A: main (ValgrindSample.cpp:21)
==8349==
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006FF: invalidRelease() (ValgrindSample.cpp:50)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20130 is 0 bytes inside a block of size 10 free'd
==8349== at 0x4A07384: free (vg_replace_malloc.c:427)
==8349== by 0x4006F6: invalidRelease() (ValgrindSample.cpp:49)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349==
==8349== Invalid free() / delete / delete[] / realloc()
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x400725: invalidRelease() (ValgrindSample.cpp:54)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349== Address 0x4c20180 is 0 bytes inside a block of size 4 free'd
==8349== at 0x4A07096: operator delete(void*) (vg_replace_malloc.c:457)
==8349== by 0x40071C: invalidRelease() (ValgrindSample.cpp:53)
==8349== by 0x40073F: main (ValgrindSample.cpp:22)
==8349==
==8349==
==8349== HEAP SUMMARY:
==8349== in use at exit: 24 bytes in 3 blocks
==8349== total heap usage: 5 allocs, 4 frees, 38 bytes allocated
==8349==
==8349== LEAK SUMMARY:
==8349== definitely lost: 24 bytes in 3 blocks
==8349== indirectly lost: 0 bytes in 0 blocks
==8349== possibly lost: 0 bytes in 0 blocks
==8349== still reachable: 0 bytes in 0 blocks
==8349== suppressed: 0 bytes in 0 blocks
==8349== Rerun with --leak-check=full to see details of leaked memory
==8349==
==8349== For counts of detected and suppressed errors, rerun with: -v
==8349== Use --track-origins=yes to see where uninitialised values come from
==8349== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)
参考资料:
valgrind官方网站:www.valgrind.org
一份valgrind --help的翻译:http://www.cppblog.com/Wealth/archive/2008/06/04/52118.html
通过例子介绍valgrind用法:http://www.cprogramming.com/debugging/valgrind.html
valgrind用法简介:http://www.cnblogs.com/napoleon_liu/articles/2001802.html
http://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/
http://www.redhat.com/magazine/015jan06/features/valgrind/
http://www.stlinux.com/devel/debug/mudflap
http://rdc.taobao.com/blog/cs/?p=455