Chinaunix首页 | 论坛 | 博客
  • 博客访问: 822165
  • 博文数量: 132
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2276
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-03 10:50
个人简介

while(!dead) learning++;

文章分类

全部博文(132)

文章存档

2019年(3)

2018年(11)

2017年(12)

2016年(8)

2015年(8)

2014年(4)

2013年(86)

分类: LINUX

2013-04-26 09:44:51

有两种比较好的方法跟踪由于malloc后未free造成的内存泄漏:

一、mtrace工具
mtrace是一个有效的工具来查看有没有内存泄漏。它会将内存出现的异常记录在日志中,而日志的路径是可以指定的。

点击(此处)折叠或打开

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<mcheck.h>
  4. #include<assert.h>

  5. int main(void)
  6. {
  7.     assert(!setenv("MALLOC_TRACE","./malloc.log",1)) ;
  8.     mtrace();

  9.     int *p = malloc(100*sizeof(int));

  10.     return 0;
  11. }
我们看上面的代码,mtrace打开跟踪开关,我们malloc了400个字节的内存空间,但是我们并没有调用free将malloc出来的空间释放掉(当然函数退出也就释放了,但是这种释放不太优雅)。
mtrace会将内存情况记录下来,记录的结果存在什么地方呢?由环境变量MALLOC_TRACE决定。所以实际上有两种设置环境变量的方法,一种情况就是代码中体现的:
1、setenv函数设定环境变量 MALLOC_TRACE 
  • setenv("MALLOC_TRACE","./malloc.log",1)

  • 2、shell设定环境变量MALLOC_TRACE

  • export MALLOC_TRACE=~/program/C/MEM_CHECK/memcheck.log
  •  

    下面是输出情况:

    1. root@libin:~/program/C/mem_bug# gcc -o test test.c -g
    2. root@libin:~/program/C/mem_bug# ./test
    3. root@libin:~/program/C/mem_bug# ll
    4. 总用量 28
    5. drwxr-xr-x 2 root root 4096 2012-04-03 12:17 ./
    6. drwxr-xr-x 36 root root 4096 2012-04-03 12:01 ../
    7. -rw-r--r-- 1 root root 155 2012-04-03 12:17 malloc.log
    8. -rwxr-xr-x 1 root root 8550 2012-04-03 12:17 test*
    9. -rw-r--r-- 1 root root 208 2012-04-03 12:17 test.c
    10. root@libin:~/program/C/mem_bug# mtrace ./test malloc.log
    11. - 0x09a68008 Free 3 was never alloc'd 0x1da8ef
    12. - 0x09a68028 Free 4 was never alloc'd 0x1da8f7

    13. Memory not freed:
    14. -----------------
    15. Address Size Caller
    16. 0x09a683b0 0x190 at /home/libin/program/C/mem_bug/test.c:11

    二、MALLOC_CHECK_宏
    除了mtrace工具之外,MALLOC_CHECK_也是个不错的工具。

    点击(此处)折叠或打开

    1. #include<stdio.h>
    2. #include<stdlib.h>

    3. int free_inside(int * p)
    4. {
    5.     if(p)
    6.         free(p);
    7. }

    8. int main(oid)
    9. {
    10.     int *p = malloc(100*sizeof(int));


    11.     free_inside(p);
    12.     free(p);
    13.     return 0;
    14. }

    我们可以看到,p指向的内存被释放了两次,第二次释放一定会出问题。

    点击(此处)折叠或打开

    1. root@libin:~/program/C/mem_bug# env MALLOC_CHECK_=1 ./test
    2. *** glibc detected *** ./test: free(): invalid pointer: 0x08d22008 ***
    3. root@libin:~/program/C/mem_bug# ./test
    4. *** glibc detected *** ./test: double free or corruption (top): 0x0943e008 ***
    5. ======= Backtrace: =========
    6. /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xba4591]
    7. /lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xba5de8]
    8. /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xba8ecd]
    9. ./test[0x804845e]
    10. /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb4fbd6]
    11. ./test[0x8048381]
    12. ======= Memory map: ========
    13. 00526000-00541000 r-xp 00000000 08:0a 532971 /lib/ld-2.11.1.so
    14. 00541000-00542000 r--p 0001a000 08:0a 532971 /lib/ld-2.11.1.so
    15. 00542000-00543000 rw-p 0001b000 08:0a 532971 /lib/ld-2.11.1.so
    16. 0060e000-0060f000 r-xp 00000000 00:00 0 [vdso]
    17. 00b39000-00c8c000 r-xp 00000000 08:0a 534966 /lib/tls/i686/cmov/libc-2.11.1.so
    18. 00c8c000-00c8d000 ---p 00153000 08:0a 534966 /lib/tls/i686/cmov/libc-2.11.1.so
    19. 00c8d000-00c8f000 r--p 00153000 08:0a 534966 /lib/tls/i686/cmov/libc-2.11.1.so
    20. 00c8f000-00c90000 rw-p 00155000 08:0a 534966 /lib/tls/i686/cmov/libc-2.11.1.so
    21. 00c90000-00c93000 rw-p 00000000 00:00 0
    22. 00eed000-00f0a000 r-xp 00000000 08:0a 524925 /lib/libgcc_s.so.1
    23. 00f0a000-00f0b000 r--p 0001c000 08:0a 524925 /lib/libgcc_s.so.1
    24. 00f0b000-00f0c000 rw-p 0001d000 08:0a 524925 /lib/libgcc_s.so.1
    25. 08048000-08049000 r-xp 00000000 08:0b 1052377 /home/libin/program/C/mem_bug/test
    26. 08049000-0804a000 r--p 00000000 08:0b 1052377 /home/libin/program/C/mem_bug/test
    27. 0804a000-0804b000 rw-p 00001000 08:0b 1052377 /home/libin/program/C/mem_bug/test
    28. 0943e000-0945f000 rw-p 00000000 00:00 0 [heap]
    29. b7700000-b7721000 rw-p 00000000 00:00 0
    30. b7721000-b7800000 ---p 00000000 00:00 0
    31. b78a5000-b78a6000 rw-p 00000000 00:00 0
    32. b78bc000-b78be000 rw-p 00000000 00:00 0
    33. bf917000-bf92c000 rw-p 00000000 00:00 0 [stack]
    比较有用的信息是backtrace打印出来的堆栈调用关系,有了这个,我们就可以方便的利用objdump出来的汇编代码,定位问题,其中,报错很明白的告诉我们是double free,重复释放内存的问题。效果很好
    *** glibc detected *** ./test: double free or corruption (top): 0x0943e008 ***

    阅读(2306) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~