原文出处:http://blog.csdn.net/skdkjzz/article/details/21737081
valgrind:
valgrind --tool=memcheck --leak-check=full ./x86_joseph_qrcode
#include <stdio.h>
#include <stdlib.h>
void main()
{
char *p = malloc(20);
sprintf(p, "%s", "test");
fprintf(stderr, "p:%s/n", p);
}
==26512== LEAK SUMMARY:
==26512== definitely lost: 20 bytes in 1 blocks.
==26512== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==26512== malloc/free: in use at exit: 20 bytes in 1 blocks.
==26512== malloc/free: 1 allocs, 0 frees, 20 bytes allocated.
void main()
{
char p[] = "hello";
fprintf(stderr, "p:%s/n", p);
free(p);
}
==26786== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==26786== malloc/free: in use at exit: 0 bytes in 0 blocks.
==26786== malloc/free: 0 allocs, 1 frees, 0 bytes allocated.
==26786== Invalid free() / delete / delete[]
==26786== at 0x402265C: free (vg_replace_malloc.c:323)
==26786== by 0x804841F: main (in /home/yutao/test/a.out)
void main()
{
char p[8] = "hello"; //p在栈上, "hello"在常量区
fprintf(stderr, "p10:%c/n", p[10]);
}
==27452== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 1)
==27452== malloc/free: in use at exit: 0 bytes in 0 blocks.
==27452== malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
void main()
{
char *p = malloc(8);
fprintf(stderr, "p10:%c/n", p[10]);
free(p);
}
==27744== Invalid read of size 1
==27744== at 0x804842A: main (in /home/yutao/test/a.out)
==27744== Address 0x4190032 is 2 bytes after a block of size 8 alloc'd
==27744== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==27744== by 0x8048420: main (in /home/yutao/test/a.out)
==27744==
==27744== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 1)
==27744== malloc/free: in use at exit: 0 bytes in 0 blocks.
==27744== malloc/free: 1 allocs, 1 frees, 8 bytes allocated.
void main()
{
char p[8] = "hello";
p[10]='a';
}
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0x412d138]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0x412d0f0]
./a.out[0x80483d6]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0x4056450]
./a.out[0x8048331]
======= Memory map: ========
04000000-0401a000 r-xp 00000000 08:06 682589 /lib/ld-2.7.so
==27918== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 13 from 1)
==27918== malloc/free: in use at exit: 892 bytes in 5 blocks.
==27918== malloc/free: 5 allocs, 0 frees, 892 bytes allocated.
==27918== LEAK SUMMARY:
==27918== definitely lost: 0 bytes in 0 blocks.
==27918== possibly lost: 0 bytes in 0 blocks.
==27918== still reachable: 892 bytes in 5 blocks.
==27918== Invalid read of size 4
==27918== at 0x40151F3: (within /lib/ld-2.7.so)
==27918== by 0x4005C69: (within /lib/ld-2.7.so)
==27918== by 0x4007A97: (within /lib/ld-2.7.so)
==27918== by 0x4011543: (within /lib/ld-2.7.so)
==27918== by 0x400D5D5: (within /lib/ld-2.7.so)
==27918== by 0x4010F5D: (within /lib/ld-2.7.so)
==27918== by 0x414E291: (within /lib/tls/i686/cmov/libc-2.7.so)
==27918== by 0x400D5D5: (within /lib/ld-2.7.so)
==27918== by 0x414E454: __libc_dlopen_mode (in /lib/tls/i686/cmov/libc-2.7.so)
==27918== by 0x412A4D8: (within /lib/tls/i686/cmov/libc-2.7.so)
==27918== by 0x412A4D8: (within /lib/tls/i686/cmov/libc-2.7.so)
==27918== by 0x412A669: backtrace (in /lib/tls/i686/cmov/libc-2.7.so)
==27918== by 0x40A3B91: (within /lib/tls/i686/cmov/libc-2.7.so)
==27918== Address 0x4190038 is 16 bytes inside a block of size 19 alloc'd
void main()
{
char *p = malloc(8);
p[10]='a';
free(p);
}
==28351== Invalid write of size 1
==28351== at 0x80483CA: main (in /home/yutao/test/a.out)
==28351== Address 0x4190032 is 2 bytes after a block of size 8 alloc'd
==28351== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==28351== by 0x80483C0: main (in /home/yutao/test/a.out
Valgrind 是一款 Linux下(支持 x86、x86_64和ppc32)程序的内存调试工具,它可以对编译后的二进制程序进行内存使用监测(C语言中的malloc和free,以及C++中的new和delete),找出内存泄漏问题。
Valgrind 中包含的 Memcheck 工具可以检查以下的程序错误:
使用未初始化的内存 (Use of uninitialised memory)
使用已经释放了的内存 (Reading/writing memory after it has been free’d)
使用超过malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)
对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)
申请的空间是否有释放 (Memory leaks – where pointers to malloc’d blocks are lost forever)
malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)
重复free
1、编译安装 Valgrind:
2、使用示例:对“ls”程序进程检查,返回结果中的“definitely lost: 0 bytes in 0 blocks.”表示没有内存泄漏。
3、使用示例:对一个使用libevent库编写的“httptest”程序进程检查,返回结果中的“definitely lost: 255 bytes in 5 blocks.”表示发生内存泄漏。
检查httptest程序,发现有一处“char *decode_uri = evhttp_decode_uri(evhttp_request_uri(req));”中的“decode_uri”没有被free,再程序处理完成后加上“free(decode_uri);”后,再使用Valgrind检查,结果已经是“definitely lost: 0 bytes in 0 blocks.”。
mtrace:
所有使用动态内存分配(dynamic memory allocation)的程序都有机会遇上内存泄露(memory leakage)问题,在Linux里有三种常用工具来检测内存泄露的情況,包括:
mtrace是三款工具之中是最简单易用的,mtrace是一个C函數,在<mcheck.h>里声明及定义,函数原型为:
其实mtrace是类似malloc_hook的 malloc handler,只不过mtrace的handler function已由系统为你写好,但既然如此,系统又怎么知道你想将malloc/free的记录写在哪里呢?为此,调用mtrace()前要先设置 MALLOC_TRACE环境变量:
「output_file_name」就是储存检测结果的文件的名称。
但是检测结果的格式是一般人无法理解的,而只要有安装mtrace的话,就会有一名为mtrace的Perl script,在shell输入以下指令:
就会将output_file_name的內容转化成能被理解的语句,例如「No memory leaks」,「0x12345678 Free 10 was never alloc」诸如此类。
例如以下有一函数:(暂且放下single entry single exit的原则)
执行后,再用mtrace 将结果输出:
最后一行标明有一个大小为1 byte的内存尚未释放,大概是指「hello」吧。
若我们把该段内存释放:结果如下:
mtrace的原理是记录每一对malloc-free的执行,若每一个malloc都有相应的free,则代表没有内存泄露,对于任何非malloc/free情況下所发生的内存泄露问题,mtrace并不能找出来。