linux背后隐藏着各种丰富的工具,学会这些工具,让这些工具更好地服务于我们的项目开发,不仅可以提高工作的效率,而且可以增强个人技术力。

参考:http://blog.chinaunix.net/uid-16135252-id-2752984.html

内存检测工具有以下的几种:

mtrace、memwatch、splint、valgrind

对比:

mtrace: 无需安装,使用时包含头文件mcheck.h,程序中调用mtrace和muntrace方法即可

memwatch: 在需要检测的.c文件里面包含memwatch.h文件,编译的时候加上几个参数即可

splint:需要下载源码并安装程序,通过标志和注释来获取想要的错误信息

valgrind:提供不同的工具来实现不同功能的检测,需要编译源码

各工具的使用

一、mtrace工具

mtrace是三款工具之中是最简单易用的,mtrace是一个C函數,在<mcheck.h>里声明及定义,函数原型为:

    void mtrace(void);

其实mtrace是类似malloc_hook的malloc handler,只不过mtrace的handler function已由系统为你写好,但既然如此,系统又怎么知道你想将malloc/free的记录写在哪里呢?为此,调用mtrace()前要先设置MALLOC_TRACE环境变量:

    #include <stdlib.h>     ....    
   setenv("MALLOC_TRACE", "output_file_name", 1);     ...
  还可以通过export MALLOC_TRACE = output_file_name进行环境变量的设置

「output_file_name」就是储存检测结果的文件的名称。

但是检测结果的格式是一般人无法理解的,而只要有安装mtrace的话,就会有一名为mtrace的Perl script,在shell输入以下指令:

    mtrace [binary] output_file_name

就会将output_file_name的內容转化成能被理解的语句,例如「No memory leaks」,「0x12345678 Free 10 was never alloc」诸如此类。

例如以下有一函数:(暂且放下single entry single exit的原则)

   #include <stdio.h>    
   #include <stdlib.h>    
   #include <errno.h>    
   #include <mcheck.h>    
   int main()
   {        
        char *hello;            
        setenv("MALLOC_TRACE", "output", 1);        
        mtrace();        
       if ((hello = (char *) malloc(sizeof(char))) == NULL)
      {            
           perror("Cannot allocate memory.");          
          return -1;       
      }
        return 0;    
    }

执行后,再用mtrace 将结果输出:

    …………………………………………
  ………………………………………………
    Memory not freed:     -----------------        Address     Size     Caller     0x08049a90      0x1  at 0x80483fe

最后一行标明有一个大小为1 byte的内存尚未释放,应该就是指hello

若我们把该段内存释放:

    #include <stdio.h>    
    #include <stdlib.h>    
   #include <errno.h>    
   #include <mcheck.h>    
  int main()
  {        
        char *hello;            
        setenv("MALLOC_TRACE", "output", 1);        
        mtrace();        
        if ((hello = (char *) malloc(sizeof(char))) == NULL)
       {            
            perror("Cannot allocate memory.");            
            return -1;        
       }
 
            free(hello);        
            return 0;    
  }

结果如下:

         ……………………
         ……………………
         No memory leaks.

mtrace的原理是记录每一对malloc-free的执行,若每一个malloc都有相应的free,则代表没有内存泄露,对于任何非malloc/free情況下所发生的内存泄露问题,mtrace并不能找出来。

二、memwatch工具

在三种检测工具当中,设置最简单的算是memwatch,和dmalloc一样,它能检测未释放的内存、同一段内存被释放多次、位址存取错误及不当使用未分配之内存区域,溢出和下溢等错误。请在http://www.linkdata.se/sourcecode.html下载最新版本的Memwatch。

步骤:

  1. 确保被测工程中有memwatch.c和memwatch.h文件,
  1. 源码中每个.c文件中都include头文件memwatch.h,
  1. 编译代码,gcc后添加-DMEMWATCH 和 -DMW_STDIO(或者-DMEMWATCH_STDIO),还有memwatch.c文件,例如:

gcc -DMEMWATCH -DMW_STDIO test.c memwatch.c -o test

  1. 运行生成的可执行文件,程序运行结束后,生成的log文件名为memwatch.log,而且在程序执行期间,所有错误提示都会显示在stdout上

如果未生成上述文件,则会写入memwatNN.log文件,NN为01~99,如果还未成功,则放弃写log文件。

注:memwatch会使系统速度减慢

    三、splint的使用

         1.splint是静态代码检测工具,可以检查包括:

1)Null Dereferences:针对空指针

2)Undefined Values:未初始化数据

3)Types:转化类型不一致

4)Memory Management:内存管理检测,如内存泄露

5)sharing:共享存储空间安全性检测

6)Function Interfaces:函数接口检测(参数传递等)

7)Control Flow:函数执行分支检测

8)Buffer Sizes:缓冲区边界检查

9)Completeness:完整性检查,包括未使用变量、函数等

10)Macros(宏隐患检测等)

2.源码包安装:

#tar zxvf splint-3.1.2.src.tgz

#cd splint-3.1.2

#mkdir /usr/local/splint

#./configure --prefix=/usr/local/splint

#make

#make install

#vi ~/.bashrc    (或者 sudo gedit ~/.bashrc) ~目录是/root

向其中添加以下内容:

export LARCH_PATH=/usr/local/splint/share/splint/lib

export LCLIMPORTDIR=/usr/local/splint/share/splint/import

#source ~/.bashrc

#export PATH=/usr/local/splint/bin/splint:$PATH

到此,splint源码安装完成。

3.splint提供了三种方式进行检查的控制,分别是flags标志、 .splintrc配置文件和格式化注释。

flags: splint支持几百个标志用来控制检查和消息报告,使用时标志前加‘+’或‘-’,‘+’标志开启这个标志,‘-’表示关闭此标志。下面例子展示了flags标志的用法:

splint -showcol a.c //在检测a.c时,告警消息中列数不被打印

splint -varuse a.c //在检测a.c时,告警消息中未使用变量告警不被打印

.splintrc配置文件: .splintrc文件中对一些flags做了默认的设定,命令行中指定的flags会覆盖.splintrc文件中的标志。

格式化注释:格式化注释提供一个类型、变量或函数的额外的信息,可以控制标志设置,增加检查效果。所有格式化注释都以/*@开始,@*/结束,比如在函数参数前加/*@null@*/,表示该参数可能是NULL,做检测时,splint会加强对该参数的值的检测。

四. valgrind使用:

步骤:

1:tar -xf valgrind-3.9.0.tar.bz2

2:./configure

3:make

4:make install(如果失败,改用root权限)

5:valgrind ls -l(检查是否正常工作,如果出错,按照提示安装相应文件)

下面的工具是valgrind安装时的标准配置:

Memcheck:用于检测内存错误。它帮助c和c++的程序更正确。

Cachegrind:用于分析cache和分支预测。它帮助程序执行得更快。

Callgrind:用于函数调用的分析。

Helgrind:用于分析多线程。

DRD:也用于分析多线程。与Helgrind类似,但是用不同的分析技术,所以可以检测不同的问题。

Massif:用于分析堆。它帮助程序精简内存的使用。

SGcheck:检测栈和全局数组溢出的实验性工具,它和Memcheck互补使用。

--leak-check=yes打开内存泄露检测细节

--tool=helgrind使用Helgrind工具检测线程错误

假设hello是可执行程序:可能的使用方法如下

valgrind --leak-check=yes ./hello

或者valgrind ./hello

终端上显示检测信息。

 

linux下内存检测工具的使用和对比的更多相关文章

  1. Linux下内存泄漏工具【转】

    转自:http://www.cnblogs.com/guochaoxxl/p/6970090.html 概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况 ...

  2. Linux下内存泄漏工具

    概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...

  3. windows下内存检测工具

    1.Intel的Parallel Inspector工具,和vs集成超好, 而且还带了线程检测工具. 2.Purifyhttps://www.cnblogs.com/hehehaha/archive/ ...

  4. Linux内核内存检测工具KASAN

    KASAN 是 Kernel Address Sanitizer 的缩写,它是一个动态检测内存错误的工具,主要功能是检查内存越界访问和使用已释放的内存等问题.KASAN 集成在 Linux 内核中,随 ...

  5. Linux下内存问题检测神器:Valgrind

    在写大型C/C++工程时难免会发生内存泄漏现象,系统编程中一个重要的方面就是有效地处理与内存相关的问题.你的工作越接近系统,你就需要面对越多的内存问题.有时这些问题非常琐碎,而更多时候它会演变成一个调 ...

  6. linux下内存泄露检测工具Valgrind介绍

    目前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况. 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题. 推荐大家可以使用 ...

  7. 【调试】Linux下超强内存检测工具Valgrind

    [调试]Linux下超强内存检测工具Valgrind 内容简介 Valgrind是什么? Valgrind的使用 Valgrind详细教程 1. Valgrind是什么? Valgrind是一套Lin ...

  8. linux下C++开发工具

    就C++开发工具而言,与Windows下微软(VC, VS2005等)一统天下相比,Linux/Unix下C++开发,可谓五花八门,各式各样.Emacs, vi, eclipse, anjuta,kd ...

  9. Linux中系统检测工具top命令

    Linux中系统检测工具top命令 本文转自:https://www.cnblogs.com/zhoug2020/p/6336453.html 首先介绍top中一些字段的含义: VIRT:virtua ...

随机推荐

  1. 【Makefile】Makefile的自动化变量$@、$^ 、$<等

    所谓自动化变量,就是这种变量会把“模式”中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了.这种自动化变量只应出现在规则的命令中. $@ 表示规则中的目标文件集.在模式规则中,如果 ...

  2. mybatis配置文件祥解(mybatis.xml)

    以下是mybatis.xml文件,提倡放在src目录下,文件名任意 <?xml version="1.0" encoding="UTF-8"?> & ...

  3. 一个Action中,可以写多个类似的业务控制方法

    1)通过模块根路径 + 功能子路径 = 访问模块下子功能的路径 @Controller @RequestMapping(value="/user") public class Us ...

  4. TCP/IP 和 和 DoD 模型

    TCP/IP 模型也被称作 DoD 模型(Department of Defense Model).TCP/IP 字面上代表了两个协议:TCP(传输控制协议)和 IP(网络之间互联协议).TCP/IP ...

  5. Delphi编写的等长加密与解密

    最近在看一本关于网络游戏服务端开发的书,虽然该书是个空架子,里面没有多少实际的内容(此书评价不好),但其中关于等长加密与解密的代码还是有一定的借鉴作用的.他山之石,可以攻玉.因为书中是C++的代码,所 ...

  6. Linux显存占用无进程清理方法(附批量清理命令)

    在跑TensorFlow.pytorch之类的需要CUDA的程序时,强行Kill掉进程后发现显存仍然占用,这时候可以使用如下命令查看到top或者ps中看不到的进程,之后再kill掉: fuser -v ...

  7. SQL -------- JDBC 修改某条记录得内容

    package demo; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; ...

  8. Prettier格式化配置

    HTML/CSS/JS/LESS 文件的 prettier 格式化规则 { // 使能每一种语言默认格式化规则 "[html]": { "editor.defaultFo ...

  9. Linux 安装 openoffice

    1 说明 本文档采用rpm包方式安装,操作系统为centos 2 下载openoffice rpm包 创建nginx源码包存放目录 mkdir /usr/local/src/openoffice cd ...

  10. *【Python】【demo实验27】【练习实例】【定义递归函数】

    原题: 原题解答: #!/usr/bin/python # encoding=utf-8 # -*- coding: UTF-8 -*- # 利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出 ...