Linux C程序内存泄露检测

对于程序员来说,最痛苦的就是内存的申请与释放。内存泄露也是程序中经常遇到的问题。为了更好的定位内存泄露问题,我们有必要熟悉一些内存泄露的检测工具。今天主要找到了以下四个内存检测工具,使用起来都比较方便。

valgrind

 安装valgrind,执行下列程序

#include <stdlib.h>

void func()
{
        int *p = malloc(10*sizeof(int));
        p[10] = 0;
}

int main()
{
        func();
        return 0;
}

编译:
 gcc -g -o valgrindtst valgrindtst.c

执行内存检测:

valgrind --tool=memcheck -leak-check=full ./valgrindtst

内存检测结果:

==19896== Memcheck, a memory error detector
==19896== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==19896== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==19896== Command: ./valgrindtst
==19896==
==19896== Invalid write of size 4
==19896==    at 0x80483DF: func (valgrindtst.c:6)
==19896==    by 0x80483F1: main (valgrindtst.c:11)
==19896==  Address 0x401a050 is 0 bytes after a block of size 40 alloc'd
==19896==    at 0x40072D5: malloc (vg_replace_malloc.c:291)
==19896==    by 0x80483D5: func (valgrindtst.c:5)
==19896==    by 0x80483F1: main (valgrindtst.c:11)
==19896==
==19896==
==19896== HEAP SUMMARY:
==19896==     in use at exit: 40 bytes in 1 blocks
==19896==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==19896==
==19896== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==19896==    at 0x40072D5: malloc (vg_replace_malloc.c:291)
==19896==    by 0x80483D5: func (valgrindtst.c:5)
==19896==    by 0x80483F1: main (valgrindtst.c:11)
==19896==
==19896== LEAK SUMMARY:
==19896==    definitely lost: 40 bytes in 1 blocks
==19896==    indirectly lost: 0 bytes in 0 blocks
==19896==      possibly lost: 0 bytes in 0 blocks
==19896==    still reachable: 0 bytes in 0 blocks
==19896==         suppressed: 0 bytes in 0 blocks
==19896==
==19896== For counts of detected and suppressed errors, rerun with: -v
==19896== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 12 from 8)

检测到内存泄露与数组越界的错误

mtrace

 libc提供的内存检测工具。一般系统中都自带该工具。

#include <stdlib.h>
#include <mcheck.h>

void func()
{
        int *p = (int*)malloc(100*sizeof(int));
}

int main()
{
        setenv("MALLOC_TRACE", "logfile",1);
        mtrace();
        func();
        return 0;
}

编译:gcc -g -o mtracetst mtracetst.c
执行程序后,生成logfile文件,内容如下:

= Start
@ ./mtracetst:[0x8048436] + 0x8a35428 0x190
@ /lib/libc.so.6:(clearenv+0x7c)[0x26a87c] - 0x8a35008
@ /lib/libc.so.6:(tdestroy+0x47)[0x318747] - 0x8a35080
@ /lib/libc.so.6:(tdestroy+0x4f)[0x31874f] - 0x8a350a0

内容不太好理解,使用perl语言实现的bin程序mtrace可以将这些内容转换为可读内容,如下:

[root@localhost test]# mtrace logfile
$* is no longer supported at /usr/bin/mtrace line 2.
- 0x0000000008a35008 Free 3 was never alloc'd 0x26a87c
- 0x0000000008a35080 Free 4 was never alloc'd 0x318747
- 0x0000000008a350a0 Free 5 was never alloc'd 0x31874f

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000008a35428    0x190  at 0x8048436

memwatch

 A memory leak detection tool. Basically, you add a header file to your souce code files, and compile with MEMWATCH defined or not. The header file MEMWATCH.H contains detailed instructions. This is a list of some of the features present in version 2.71:
- ANSI C
- Logging to file or user function using TRACE() macro
- Fault tolerant, can repair it’s own data structures
- Detects double-frees and erroneous free’s
- Detects unfreed memory
- Detects overflow and underflow to memory buffers
- Can set maximum allowed memory to allocate, to stress-test app
- ASSERT(expr) and VERIFY(expr) macros
- Can detect wild pointer writes
- Support for OS specific address validation to avoid GP’s (segmentation faults)
- Collects allocation statistics on application, module or line level
- Rudimentary support for threads (see FAQ for details)
- Rudimentary support for C++ (disabled by default, use with care!)

 

下载,解压,在解压目录中,写如下测试程序:

#include <stdlib.h>
#include "memwatch.h"

int main()
{
        char *p1 = NULL, *p2 = NULL;
        p1 = malloc(100*sizeof(char));
        p2 = malloc(1000*sizeof(char));
        free(p2);
}


编译: gcc -g -o memwatchtst -DMEMWATCH -DMEMWATCH_STDIO memwatchtst.c memwatch.c执行结果:

[root@localhost memwatch-2.71]# ./memwatchtst
MEMWATCH detected 1 anomalies
在当前目录下生成memwatch.log文件,打开,内容如下:

============= MEMWATCH 2.71 Copyright (C) 1992-1999 Johan Lindh =============

Started at Wed Jan 15 01:30:01 2014

Modes: __STDC__ 64-bit mwDWORD==(unsigned long)
mwROUNDALLOC==8 sizeof(mwData)==32 mwDataSize==32


Stopped at Wed Jan 15 01:30:01 2014

unfreed: <1> memwatchtst.c(7), 100 bytes at 0x9ea11f0   {FE FE FE FE 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      : 1100
 T)otal of all alloc() calls: 1100
 U)nfreed bytes totals      : 100

gc

垃圾回收器、内存泄露检测

安装gc,然后可以执行下列测试程序

#include <gc.h>
#include <stdio.h>
#include <stdlib.h>
#include <gc/leak_detector.h>
void test()
{
        int i;
        char *p;
        for(i=0; i < 10000; i++)
        {
                p = GC_malloc(100000*sizeof(int));
                if(NULL == p)
                {
                        printf("NO memory\n");
                        break;
                }
        }

}

void chkmem()
{
        int *p[10];
        int i;
        GC_find_leak = 1;
        for(i=0; i < 10; i++)
        {
                p[i] = (int *)malloc(sizeof(int)+i);
        }
        for(i=0; i<7;i++)
        {
                free(p[i]);
        }
        for(i=3; i < 10; i++)
        {
                 p[i] = (int *)malloc(sizeof(int)+i);
        }
        CHECK_LEAKS();
}
int main()
{
        test();
        chkmem();
}

编译:

 export export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

 gcc -g -o gctst gctst.c -lgc

执行结果:

[root@localhost test]# ./gctst
Leaked composite object at start: 0x93d2000, appr. length: 400008
Leaked composite object at start: 0x93b2fa0, appr. length: 16
Leaked composite object at start: 0x93b2fb0, appr. length: 16
Leaked composite object at start: 0x93b2fc0, appr. length: 16
Leaked composite object at start: 0x94f8000, appr. length: 400008
Leaked composite object at start: 0x9496000, appr. length: 400008
Leaked composite object at start: 0x9434000, appr. length: 400008
[root@localhost test]#
注:test函数说明gc有自动回收内存的机制;chkmem函数说明,gc可以检测内存泄露

 

valgrind和memwatch的输出信息比较适合我们的阅读习惯,可以很容易定位内存泄露的位置。

gc有垃圾内存回收机制。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值