
1、通过查看linux找到是哪个函数访问了异常地址,进行改正。
2、在linux数组或者结构体成员的前后分别加上magicnumber,复现故障,使用linux工具查看对应的magicnumber是否被修改,判断是向前踩内存还是向后踩内存,内存越界是软件系统主要错误之一,是指当内存输入超出了预分配的空间大小,就会覆盖该空间之后的一段存储区域,导致系统异常,其后果往往不可预料且非常严重。
Linux c/c++上常用内存泄露检测工具有valgrind, Rational purify。Valgrind免费。Valgrind可以在 32位或64位 PowerPC/Linux内核上工作。Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。下面分别介绍个工具的作用:
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)
Valgrind不检查静态分配数组的使用情况。
Valgrind占用了更多的内存--可达两倍于你程序的正常使用量。如果你用Valgrind来检测使用大量内存的程序就会遇到问题,它可能会用很长的时间来运行测试
2.1. 下载安装
http://www.valgrind.org
安装
./configuremakemake install
2.2. 编译程序
被检测程序加入–g -fno-inline 编译选项保留调试信息。
2.3. 内存泄露检测
$ valgrind --tool=memcheck --log-file=/root/valgrind_log_all --leak-check=full --error-limit=no --show-reachable=yes --trace-children=yes /usr/local/sdata/sbin/rpcbakupsvr
其中--leak-check=full 指的是完全检查内存泄漏,--show-reachable=yes是显示内存泄漏的地点,--trace-children=yes是跟入子进程。当程序正常退出的时候valgrind自然会输出内存泄漏的信息。
1.内存泄露:
#include <stdio.h>void function()
{int *p = (int*)malloc(10*sizeof(int)) p[10] = 0
}int main()
{function() return 0
}
相关日志:
==20220== Memcheck, a memory error detector
==20220== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20220== Using Valgrind-3.6.1-Debian and LibVEXrerun with -h for copyright info
==20220== Command: ./test
==20220== Parent PID: 20160
==20220==
==20220== Invalid write of size 4
==20220==at 0x80483FF: function (in /mnt/Documents/Training/valgrind/test)
==20220==by 0x8048411: main (in /mnt/Documents/Training/valgrind/test)
==20220== Address 0x41be050 is 0 bytes after a block of size 40 alloc'd
==20220==at 0x4028876: malloc (vg_replace_malloc.c:236)
==20220==by 0x80483F5: function (in /mnt/Documents/Training/valgrind/test)
==20220==by 0x8048411: main (in /mnt/Documents/Training/valgrind/test)
==20220==
==20220==
==20220== HEAP SUMMARY:
==20220== in use at exit: 40 bytes in 1 blocks
==20220== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==20220==
==20220== LEAK SUMMARY:
==20220==definitely lost: 40 bytes in 1 blocks
==20220==indirectly lost: 0 bytes in 0 blocks
==20220== possibly lost: 0 bytes in 0 blocks
==20220==still reachable: 0 bytes in 0 blocks
==20220== suppressed: 0 bytes in 0 blocks
==20220== Rerun with --leak-check=full to see details of leaked memory
==20220==
==20220== For counts of detected and suppressed errors, rerun with: -v
==20220== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)
2.使用未初始化的内存
#include <stdio.h>int main()
{int a if (a==1)
{printf("a==%d\n",a)
}return 0
}
日志分析:
==20345== Memcheck, a memory error detector
==20345== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20345== Using Valgrind-3.6.1-Debian and LibVEXrerun with -h for copyright info
==20345== Command: ./test
==20345==
==20345== Conditional jump or move depends on uninitialised value(s)
==20345==at 0x80483F2: main (in /mnt/Documents/Training/valgrind/test)
==20345==
==20345==
==20345== HEAP SUMMARY:
==20345== in use at exit: 0 bytes in 0 blocks
==20345== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==20345==
==20345== All heap blocks were freed -- no leaks are possible
==20345==
==20345== For counts of detected and suppressed errors, rerun with: -v
==20345== Use --track-origins=yes to see where uninitialised values come from
==20345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)
可以使用--track-origins=yes 得到更多的信息
3.内存读写越界
#include <stdio.h>int main()
{int *a = (int*)malloc(5*sizeof(int)) a[5] = 1 return 0
}
==20368== Memcheck, a memory error detector
==20368== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==20368== Using Valgrind-3.6.1-Debian and LibVEXrerun with -h for copyright info
==20368== Command: ./test
==20368==
==20368== Invalid write of size 4
==20368==at 0x8048404: main (in /mnt/Documents/Training/valgrind/test)
==20368== Address 0x41be03c is 0 bytes after a block of size 20 alloc'd
==20368==at 0x4028876: malloc (vg_replace_malloc.c:236)
==20368==by 0x80483F8: main (in /mnt/Documents/Training/valgrind/test)
==20368==
==20368==
==20368== HEAP SUMMARY:
==20368== in use at exit: 20 bytes in 1 blocks
==20368== total heap usage: 1 allocs, 0 frees, 20 bytes allocated
==20368==
==20368== LEAK SUMMARY:
==20368==definitely lost: 20 bytes in 1 blocks
==20368==indirectly lost: 0 bytes in 0 blocks
==20368== possibly lost: 0 bytes in 0 blocks
==20368==still reachable: 0 bytes in 0 blocks
==20368== suppressed: 0 bytes in 0 blocks
==20368== Rerun with --leak-check=full to see details of leaked memory
==20368==
==20368== For counts of detected and suppressed errors, rerun with: -v
==20368== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)
4.内存申请释放管理错误
#include <stdio.h>int main()
{int *a = new int[5] /*free(a)*/delete a return 0
}
1:一般都是非法内存 *** 作,例如数组越界,例如申请a[5],却访问到a[5]或者a[6],这也会有很多情况,可能是循环 *** 作时循环变量控制有问题,可能是字符串拷贝时长度发生溢出;2:指针指向了非法内存,例如申明一个指针,但是没有对指针进行初始化,直接就引用,或者引用里面的元素或者函数,或者没有分配内存就进行释放等,另外,申请内存还要检查是否申请成功,如果没有申请成功也会出现这种情况;3:单步调试或者加打印信息,细心一点总可以找到错误的,注意编译成调试版本;4:如果是linux,可以产生core文件,从core文件查看出错的地方。欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)