MEMWATCH

下载地址: ​​memwatch​​​
MEMWATCH 支持ANSIC,它提供结果日志纪录,能检测双重释放(double-free)、错误释放(erroneous free)、没有释放的内存(unfreedmemory)、溢出和下溢等等。

#include <stdlib.h>
#include <stdio.h>
#include "memwatch.h"
int main(void)
{
char *ptr1;
char *ptr2;
ptr1 = malloc(512);
ptr2 = malloc(512);
ptr2 = ptr1;
free(ptr2);
free(ptr1);
}
使用的时候只要添加头文件"memwatch.h",然后使用gcc编译的时候添加-DMEMWATCH -DMW_STDIO
gcc -DMEMWATCH -DMW_STDIO test1.c memwatch.c -o test1

当运行程序./test1的时候会生成一个关于泄漏的内存的报告memwatch.log。

MEMWATCH 2.67 Copyright (C) 1992-1999 Johan Lindh
...
double-free: <4> test1.c(15), 0x80517b4 was freed from test1.c(14)
...
unfreed: <2> test1.c(11), 512 bytes at 0x80519e4
{FE FE FE FE FE FE FE FE FE FE FE FE ..............}
Memory usage statistics (global):
N)umber of allocations made: 2
L)argest memory usage : 1024
T)otal of all alloc() calls: 1024
U)nfreed bytes totals : 512

YAMD


efence

#include <stdio.h>  
#include <stdlib.h>
int main()
{
char *ptr = (char *) malloc(1024);
ptr[0] = 0;
/* Now write beyond the block */
ptr[1024] = 0;
exit(0);
}

测试方式1,​​gcc -o test test.c -lefence -lpthread​​​
run command ./test and the result is below:
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
段错误(吐核)

测试方式2,加上-g选项打印信息更加详细,​​gcc -g -o test test.c -lefence -lpthread​​​
run command gdb ./test then input commandrun the result as below :
Starting program: /home/test
[Thread debugging using libthread_db enabled]
Using host libthread_db library “/lib/libthread_db.so.1”.
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
Program received signal SIGSEGV, Segmentation fault.
0x0804889d in main () at test.c:8
8 ptr[1024] = 0;
Missing separate debuginfos, use: debuginfo-install glibc-2.14.90-24.fc16.9.i686
这里就可以看出来内存越界了。


valgrind

Valgrind是一款基于模拟linux下的程序调试器和剖析器的软件套件,可以运行于x86, amd64和ppc32架构上。valgrind包含一个核心,它提供一个虚拟的CPU运行程序,还有一系列的工具,它们完成调试,剖析和一些类似的任务。valgrind是高度模块化的,所以开发人员或者用户可以给它添加新的工具而不会损坏己有的结构。
valgrind的官方网址是:​​​http://valgrind.org​​​
你可以在它的网站上下载到最新的valgrind,它是开放源码和免费的。

valgrind包含几个标准的工具,它们是:
1、memcheck
memcheck探测程序中内存管理存在的问题。它检查所有对内存的读/写操作,并截取所有的malloc/new/free/delete调用。因此memcheck工具能够探测到以下问题:
1)使用未初始化的内存
2)读/写已经被释放的内存
3)读/写内存越界
4)读/写不恰当的内存栈空间
5)内存泄漏
6)使用malloc/new/new[]和free/delete/delete[]不匹配。

2、cachegrind
cachegrind是一个cache剖析器。它模拟执行CPU中的L1, D1和L2 cache,因此它能很精确的指出代码中的cache未命中。如果你需要,它可以打印出cache未命中的次数,内存引用和发生cache未命中的每一行代码,每一个函数,每一个模块和整个程序的摘要。如果你要求更细致的信息,它可以打印出每一行机器码的未命中次数。在x86和amd64上, cachegrind通过CPUID自动探测机器的cache配置,所以在多数情况下它不再需要更多的配置信息了。

3、helgrind
helgrind查找多线程程序中的竞争数据。helgrind查找内存地址,那些被多于一条线程访问的内存地址,但是没有使用一致的锁就会被查出。这表示这些地址在多线程间访问的时候没有进行同步,很可能会引起很难查找的时序问题。

valgrind被设计成非侵入式的,它直接工作于可执行文件上,因此在检查前不需要重新编译、连接和修改你的程序。要检查一个程序很简单,只需要执行下面的命令就可以了
valgrind –tool=tool_name program_name
比如我们要对ls -l命令做内存检查,只需要执行下面的命令就可以了
valgrind –tool=memcheck ls -l
不管是使用哪个工具,valgrind在开始之前总会先取得对你的程序的控制权,从可执行关联库里读取调试信息。然后在valgrind核心提供的虚拟CPU上运行程序,valgrind会根据选择的工具来处理代码,该工具会向代码中加入检测代码,并把这些代码作为最终代码返回给valgrind核心,最后valgrind核心运行这些代码。
如果要检查内存泄漏,只需要增加–leak-check=yes就可以了,命令如下
valgrind –tool=memcheck –leak-check=yes ls -l
不同工具间加入的代码变化非常的大。在每个作用域的末尾,memcheck加入代码检查每一片内存的访问和进行值计算,代码大小至少增加12倍,运行速度要比平时慢25到50倍。
valgrind模拟程序中的每一条指令执行,因此,检查工具和剖析工具不仅仅是对你的应用程序,还有对共享库,GNU C库,X的客户端库都起作用。

具体使用见参考文章3


参考文章

  1. ​​Linux内核调试方法总结​​
  2. ​​利用efence调试内存泄漏​​
  3. ​防止内存泄露 Linux下用Valgrind做检查​