#内存泄露# #内存检测#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\Problem memory overrun double free use after free wild free access uninited read invalid memory memory leak use after return stack overflow c++ quick on/off call stack
Memory checking tools in Glibc   Yes   Yes     Yes   Yes(if use memcpy, strcpy, etc)      
TCMalloc(Gperftools)             Yes          
Valgrind Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes    
Address Sanitizer(ASan) Yes Yes Yes Yes (Memory Sanitizer) Yes Yes Yes Yes      
Memwatch   Yes   Yes     Yes          
Dr.Memory Yes Yes Yes Yes Yes Yes Yes Yes        
Electric Fence Yes Yes Yes Yes     Yes          
dmalloc Yes Yes Yes Yes     Yes       Yes  
mtrace             Yes       Yes  
leaktracer             Yes     Yes Yes Yes

你可能感兴趣的:(内存泄露)