#内存泄露# #内存检测#Linux中的常用内存问题检测工具

C/C++等底层语言在提供强大功能及性能的同时,其灵活的内存访问也带来了各种纠结的问题。如果crash的地方正是内存使用错误的地方,说明你人品好。如果crash的地方内存明显不是consistent的,或者内存管理信息都已被破坏,并且还是随机出现的,那就比较麻烦了。当然,祼看code打log是一个办法,但其效率不是太高,尤其是在运行成本高或重现概率低的情况下。另外,静态检查也是一类方法,有很多工具(lint, cppcheck, klockwork, splint, o, etc.)。但缺点是误报很多,不适合针对性问题。另外好点的一般还要钱。最后,就是动态检查工具。下面介绍几个Linux平台下主要的运行时内存检查工具。绝大多数都是开源免费且支持x86和ARM平台的。

首先,比较常见的内存问题有下面几种: 

  1. • memory overrun:写内存越界 
  2. • double free:同一块内存释放两次 
  3. • use after free:内存释放后使用 
  4. • wild free:释放内存的参数为非法值 
  5. • access uninitialized memory:访问未初始化内存 
  6. • read invalid memory:读取非法内存,本质上也属于内存越界 
  7. • memory leak:内存泄露 
  8. • use after return:caller访问一个指针,该指针指向caller的栈内内存 
  9. • stack overflow:栈溢出

针对上面的问题,主要有以下几种方法: 

  • 1. 为了检测内存非法使用,需要hook内存分配和操作函数。hook的方法可以是用C-preprocessor,也可以是在链接库中直接定义(因为Glibc中的malloc/free等函数都是weak symbol),或是用LD_PRELOAD。另外,通过hook strcpy(),memmove()等函数可以检测它们是否引起buffer overflow。 
  • 2. 为了检查内存的非法访问,需要对程序的内存进行bookkeeping,然后截获每次访存操作并检测是否合法。bookkeeping的方法大同小异,主要思想是用shadow memory来验证某块内存的合法性。至于instrumentation的方法各种各样。有run-time的,比如通过把程序运行在虚拟机中或是通过binary translator来运行;或是compile-time的,在编译时就在访存指令时就加入检查操作。另外也可以通过在分配内存前后加设为不可访问的guard page,这样可以利用硬件(MMU)来触发SIGSEGV,从而提高速度。 
  • 3. 为了检测栈的问题,一般在stack上设置canary,即在函数调用时在栈上写magic number或是随机值,然后在函数返回时检查是否被改写。另外可以通过mprotect()在stack的顶端设置guard page,这样栈溢出会导致SIGSEGV而不至于破坏数据。

以上方法有些强于功能,有些胜在性能,有些则十分方便易用,总之各有千秋。以下是几种常用工具在Linux x86_64平台的实验结果,注意其它平台可能结果有差异。另外也可能由于版本过老,编译环境差异,姿势不对,总之各种原因造成遗漏,如有请谅解~

Tool\Problemmemory overrundouble freeuse after freewild freeaccess uninitedread invalid memorymemory leakuse after returnstack overflowc++quick on/offcall stack
Memory checking tools in Glibc Yes Yes  Yes Yes(if use memcpy, strcpy, etc)   
TCMalloc(Gperftools)      Yes     
ValgrindYesYesYesYesYesYesYesYesYesYes  
Address Sanitizer(ASan)YesYesYesYes(Memory Sanitizer)YesYesYesYes   
Memwatch Yes Yes  Yes     
Dr.MemoryYesYesYesYesYesYesYesYes    
Electric FenceYesYesYesYes  Yes     
dmallocYesYesYesYes  Yes   Yes 
mtrace      Yes   Yes 
leaktracer      Yes  YesYesYes
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值