版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、在 linux 平台中调试c/c+ 内存泄漏方法收藏级别:初级韩 兆兵(), 软件工程师 , ibm 刘 盈 (), 软件工程师 , ibm 强 晟 (), 软件工程师 , ibm 2008 年 5 月 15 日由于c 和 c+ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误。同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果。本文将从静态分析和动态检测两个角度介绍在linux 环境进行内存泄漏检测的方法,并重点介绍静态分析工具beam 、动态监测工具valgrind 和rational purify 的使用方法。相信通过本文的介绍,能给大家对
2、处理其它产品或项目内存泄漏相关的问题时提供借鉴。由于c 和 c+ 程序中完全由程序员自主申请和释放内存,稍不注意,就会在系统中导入内存错误。同时,内存错误往往非常严重,一般会带来诸如系统崩溃,内存耗尽这样严重的后果。 从历史上看, 来自计算机应急响应小组和供应商的许多最严重的安全公告都是由简单的内存错误造成的。自从70 年代末期以来,c/c+ 程序员就一直讨论此类错误,但其影响在2007 年仍然很大。 与许多其他类型的常见错误不同,内存错误通常具有隐蔽性,即它们很难再现,症状通常不能在相应的源代码中找到。例如,无论何时何地发生内存泄漏,都可能表现为应用程序完全无法接受,同时内存泄漏不是显而易见
3、1 。存在内存错误的c 和c+ 程序会导致各种问题。如果它们泄漏内存,则运行速度会逐渐变慢,并最终停止运行;如果覆盖内存,则会变得非常脆弱,很容易受到恶意用户的攻击。因此,出于这些原因,需要特别关注c 和 c+ 编程的内存问题,特别是内存泄漏。本文先从如何发现内存泄漏,然后是用不同的方法和工具定位内存泄漏,最后对这些工具进行了比较, 另外还简单介绍了资源泄漏的处理(以句柄泄漏为例)。本文使用的测试平台是:linux (redhat as4)。但是这些方法和工具许多都不只是局限于c/c+ 语言以及linux 操作系统。内存泄漏一般指的是堆内存的泄漏。堆内存是指程序从堆中分配的、大小任意的 (内存
4、块的大小可以在程序运行期决定)、使用完后必须显示的释放的内存。应用程序一般使用malloc、realloc、 new 等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free 或delete 释放该内存块。否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。1. 如何发现内存泄漏有些简单的内存泄漏问题可以从在代码的检查阶段确定。还有些泄漏比较严重的,即在很短的时间内导致程序或系统崩溃,或者系统报告没有足够内存,也比较容易发现。最困难的就是泄漏比较缓慢,需要观测几天、 几周甚至几个月才能看到明显异常现象。那么如何在比较短的时间内检测出有没有潜在的内存泄漏问题呢?实际上不同的系统都
5、带有内存监视工具,我们可以从监视工具收集一段时间内的堆栈内存信息,观测增长趋势, 来确定是否有内存泄漏。在linux 平台可以用ps 命令,来监视内存的使用,比如下面的命令(观测指定进程的 vsz 值):ps -aux 回页首2. 静态分析包括手动检测和静态工具分析,这是代价最小的调试方法。2.1 手动检测当使用c/c+ 进行开发时, 采用良好的一致的编程规范是防止内存问题第一道也是最重要的措施。检测是编码标准的补充。二者各有裨益, 但结合使用效果特别好。专业的c 或 c+ 专业人员甚至可以浏览不熟悉的源代码,并以极低的成本检测内存问题。通过少量的实践和适当的文本搜索, 您能够快速验证平衡的*
6、alloc() 和 free() 或者new 和 delete 的源主体。人工查看此类内容通常会出现像清单1 中一样的问题,可以定位出在函数leaktest 中的堆变量logmsg 没有释放。清单 1. 简单的内存泄漏#include #include #include int leaktest(char * para) if(null=para) /local_log(leaktest func: empty parametern); return -1; char * logmsg = new char128; if(null = logmsg) /local_log(memeory al
7、location failedn); return -2; sprintf(logmsg,leaktest routine exit: %s.n, para); /local_log(logmsg); return 0;int main(int argc,char *argv ) char szinit = testcase1; leaktest(szinit); return 0; 2.2 静态代码分析工具代码静态扫描和分析的工具比较多,比如splint, pc-lint, beam 等。因为beam 支持的平台比较多,这以beam 为例,做个简单介绍,其它有类似的处理过程。beam 可以检
8、测四类问题: 没有初始化的变量;废弃的空指针;内存泄漏;冗余计算。而且支持的平台比较多。beam 支持以下平台:linux x86 (glibc 2.2.4) linux s390/s390 x (glibc 2.3.3 or higher) linux (powerpc, uss) (glibc 2.3.2 or higher) aix (4.3.2+) window2000 以上清单 2. 用作beam 分析的代码#include #include #include int *p;voidfoo(int a) int b, c; b = 0; if(!p) c = 1; if(c a) c
9、 += p1;int leaktest(char * para) char * logmsg = new char128; if(para=null)|(logmsg = null) return -1; sprintf(logmsg,leaktest routine exit: %s.n, para); return 0;int main(int argc,char *argv ) char szinit = testcase1; leaktest(szinit); return 0; 下面以x86 linux 为例 ,代码如清单2,具体的环境如下: os: red hat enterpri
10、se linux as release 4 (nahant update 2) gcc: gcc version 3.4.4 beam: 3.4.2; https:/ 可以把beam 看作一个c/c+ 编译器,按下面的命令进行编译(前面两个命令是设置编译器环境变量 ):./beam-3.4.2/bin/beam_configure -c gcc./beam-3.4.2/bin/beam_configure -cpp g+./beam-3.4.2/bin/beam_compile -beam:compiler=compiler_cpp_config.tcl -cpp code2.cpp 从下面的
11、编译报告中,我们可以看到这段程序中有三个错误:”内存泄漏”; “变量未初始化” ;“ 空指针操作”code2.cpp, line 10: warning: variable b was set but never used int b, c; beam_version=3.4.2beam_root=/home/hanzb/memdetectbeam_directory_write_innocents=beam_directory_write_errors=- error23(heap_memory) /*memory leak*/ error23_leaktest_7b00071dc5cbb4
12、58code2.cpp, line 24: memory leakone possible path leading to the error: code2.cpp, line 22: allocating using operator new (this memory will not be freed) code2.cpp, line 22: assigning into logmsg code2.cpp, line 24: deallocating logmsg because exiting its scope (losing last pointer to the memory)-
13、error1 /*uninitialized*/ error1_foo_60c7889b2b608code2.cpp, line 16: uninitialized cone possible path leading to the error: code2.cpp, line 10: allocating c code2.cpp, line 13: the if-condition is false code2.cpp, line 16: getting the value of c values a t the end of the path: p != 0 - error2 /*oper
14、ating on null*/ error2_foo_af57809a2b615code2.cpp, line 17: invalid operation involving null pointerone possible path leading to the error: code2.cpp, line 13: the if-condition is true (used as evidence that error is possible) code2.cpp, line 16: the if-condition is true code2.cpp, line 17: invalid
15、operation involving null pointer p values a t the end of the pa th: c = 1 p = 0 a = 0 2.3 内嵌程序可以重载内存分配和释放函数new 和 delete,然后编写程序定期统计内存的分配和释放,从中找出可能的内存泄漏。或者调用系统函数定期监视程序堆的大小,关键要确定堆的增长是泄漏而不是合理的内存使用。这类方法比较复杂,在这就不给出详细例子了。回页首3. 动态运行检测实时检测工具主要有valgrind, rational purify 等。3.1 valgrind valgrind 是帮助程序员寻找程序里的bug
16、 和改进程序性能的工具。程序通过valgrind 运行时,valgrind 收集各种有用的信息,通过这些信息可以找到程序中潜在的bug 和性能瓶颈。valgrind 现在提供多个工具,其中最重要的是memcheck , cachegrind, massif 和 callgrind。valgrind 是在linux 系统下开发应用程序时用于调试内存问题的工具。它尤其擅长发现内存管理的问题,它可以检查程序运行时的内存泄漏问题。其中的memecheck 工具可以用来寻找c、c+ 程序中内存管理的错误。可以检查出下列几种内存操作上的错误:读写已经释放的内存读写内存块越界(从前或者从后)使用还未初始化的
17、变量将无意义的参数传递给系统调用内存泄漏3.2 rational purify rational purify 主要针对软件开发过程中难于发现的内存错误、运行时错误。在软件开发过程中自动地发现错误,准确地定位错误,提供完备的错误信息,从而减少了调试时间。同时也是市场上唯一支持多种平台的类似工具,并且可以和很多主流开发工具集成。purify 可以检查应用的每一个模块,甚至可以查出复杂的多线程或进程应用中的错误。另外不仅可以检查 c/c+,还可以对java 或 .net 中的内存泄漏问题给出报告。在 linux 系统中,使用purify 需要重新编译程序。通常的做法是修改makefile 中的编译
18、器变量。下面是用来编译本文中程序的makefile :cc=purify gcc 首先运行purify 安装目录下的purifyplus_setup.sh 来设置环境变量,然后运行make 重新编译程序。./purifyplus_setup.sh 下面给出编译一个代码文件的示例,源代码文件命名为test3.cpp. 用 purify 和 g+ 的编译命令如下,-g是编译时加上调试信息。purify g+ -g test3.cpp o test 运行编译生成的可执行文件test,就可以得到图1,可以定位出内存泄漏的具体位置。./test 清单 3. purify 分析的代码#include ch
19、ar * logmsg;int leaktest(char * para) if(null=para) /local_log(leaktest func: empty parametern); return -1; logmsg = new char128; for (int i = 0 ; i 128; i+) logmsgi = i%64; if(null = logmsg) /local_log(memeory allocation failedn); return -2; sprintf(logmsg,leaktest routine exit: %s.n, para); /local_log(logmsg); return 0;int main(int argc,char *argv ) char szinit = testcase1; int i; leaktes
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二四年度智能家居系统研发与销售合作协议2篇
- 人教版九年级化学第七单元燃料及其利用2燃料的合理利用与开发课时2使用燃料对环境的影响新能源的开发和利用教学课件
- 2024年度股权转让合同标的及股权交付程序2篇
- 钢管与扣件2024年度供需合同2篇
- 版公司借个人借款协议标准版可打印
- 手术后终末处理
- 《女性与社会角色》课件
- 《奥运城市与音乐》课件
- 《女生完美身材》课件
- 发票合同范本
- 刘彭芝教育思想的哲学内涵记当代教育家刘彭芝(下)
- 火电厂专用英汉对照
- 现代的全面预算管理.ppt
- 道路交通安全法律法规(PPT 90页)
- (完整word版)气缸结构设计
- 土木工程常用术语英文
- MSDS(T-09)快干水2x3
- 《常用正颌外科手术》ppt课件
- 王虎应老师股市预测分析精彩卦例
- (完整版)数独题目100题
- 【原创】仁爱英语 七年级上册情景交际+看图写话(有答案)
评论
0/150
提交评论