一、valgrind介绍

 1、valgrind概述

Valgrind是一套Linux下,开放源代码的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。Valgrind的体系结构如下图所示:

2、valgrind包括的工具

(1)memcheck(主要用的就是这个、默认的也是这个)
最常用的工具,用来检测程序中出现的内存问题。所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。所以,它能检测以下问题:
1.对未初始化内存的使用;
2.读/写释放后的内存块;
3.读/写超出malloc分配的内存块;
4.读/写不适当的栈中内存块;
5.内存泄漏,指向一块内存的指针永远丢失;
6.不正确的malloc/free或new/delete匹配;
7,memcpy()相关函数中的dst和src指针重叠。
这些问题往往是C/C++程序员最头疼的问题,Memcheck在这里帮上了大忙。
(2)callgrind
和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。
(3)cachegrind
Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
(4)helgrind
它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为“Eraser”的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验阶段。
(5)massif
堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。
此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具。我们就不做介绍了。

3、valgrind检测内存问题的原理

如下图所示,valgrind能检测内存主要依赖于其两个全局表——Value表和Address表

(1)Valid-Value 表:

对于进程的整个地址空间中的每一个字节(byte),都有与之对应的 8 个bits;对于 CPU 的每个寄存器,也有一个与之对应的bit 向量。这些 bits 负责记录该字节或者寄存器值是否具有有效的、已初始化的值。

(2)Valid-Address 表:

对于进程整个地址空间中的每一个字节(byte),还有与之对应的 1 个bit,负责记录该地址是否能够被读写。

(3)检测原理:

1)当要读写内存中某个字节时,首先检查这个字节对应的 A bit。如果该A bit显示该位置是无效位置(说明不能够读写),此时memcheck则报告读写错误。

2)内核(core)类似于一个虚拟的 CPU 环境,这样当内存中的某个字节被加载到真实的 CPU 中时,该字节对应的 V bit 也被加载到虚拟的 CPU 环境中。一旦寄存器中的值被用来产生内存地址或者该值能够影响程序输出,则 memcheck 会检查对应的V bits,如果该值尚未初始化(说明该寄存器中的值无效),则会报告使用未初始化内存错误。

4、Linux程序在内存中的布局(补充)

下图展示了一个典型的Linux C程序内存空间布局:

一个典型的Linux C程序内存空间由如下几部分组成:

(1)代码段(.text)。这里存放的是CPU要执行的指令。代码段是可共享的,相同的代码在内存中只会有一个拷贝,同时这个段是只读的,防止程序由于错误而修改自身的指令。
(2)初始化数据段(.data)。这里存放的是程序中需要明确赋初始值的变量,例如位于所有函数之外的全局变量:int val=100。需要强调的是,以上两段都是位于程序的可执行文件中,内核在调用exec函数启动该程序时从源程序文件中读入。
(3)未初始化数据段(.bss)。位于这一段中的数据,内核在执行该程序前,将其初始化为0或者null。例如出现在任何函数之外的全局变量:int sum;
(4)堆(Heap)。这个段用于在程序中进行动态内存申请,例如经常用到的malloc,new系列函数就是从这个段中申请内存。
(5)栈(Stack)。函数中的局部变量以及在函数调用过程中产生的临时变量都保存在此段中。

二、valgrind安装

(0)切换至安装目录例如:cd /usr/mysoftware/valgrind

(1)wget http://www.valgrind.org/downloads/valgrind-3.14.0.tar.bz2  下载安装包

注:最好安装最新版本的,否则容易出模型奇妙的问题(据说)。

(2)tar xvf valgrind-3.14.0.tar           #解压安装包。

(3)cd valgrind-3.14.0        #进入文件夹。

(4)make           #从makefile中读取指令。

(5)make install       #执行安装。

(6)配置环境变量,便于调用。

1)cd /etc/profile.d 目录下,创建文件valgrind.sh

2)在文件里面填入如下内容:

#!/bin/bash
VALGRIND_ROOT=/home/Lyndon/valgrind-3.14.0
VALGRIND_INCLUDE=/usr/local/include/valgrind
VALGRIND_LIB=/usr/local/lib/valgrind
export VALGRIND_ROOT VALGRIND_INCLUDE VALGRIND_LIB

3)chmod +x valgrind.sh      #再修改一下valgrind的权限即可。

三、valgrind的使用

形式:valgrind --tool=toolname ./test

其中的toolname就是那五个工具中的一个。

例如:

(1)valgrind --tool=memcheck ./test5

(2)valgrind  ./test5    #memcheck的时候tool的选择是可以默认省略的。

(3)valgrind --tool=helgrind ./test5

四、valgrind使用举例

1、访问非法内存:

(1)程序如下:

#include <iostream>
#include <stdlib.h>
using namespace std;
void func(){int *x=(int*)malloc(10*sizeof(int));x[10]=0;
}
int main(){func();cout<<"done"<<endl;return 0;
}

(2)编译程序 g++ -g -o test test.cpp

(3)使用valgrind检测:valgrind  ./test

(4)结果如下:

(5)分析:两个问题。1)第六行对堆内存的访问越界。   2)malloc动态申请的对内存没有释放。

2、使用未初始化内存:

(1)程序如下:

#include<iostream>
using namespace std;
int main(){int a[5];int i,s=0;a[0]=a[1]=a[3]=a[4]=0;for(i=0;i<5;++i)s+=a[i];if(s==33)cout<<"sum is 33"<<endl;elsecout<<"sum is not 33"<<endl;return 0;
}

(2)结果如下:

3、内存读写越界:

(1)程序如下:

#include<iostream>
#include <stdlib.h>
using namespace std;
int main(){int len=4;int *pt=(int*)malloc(len*sizeof(int));int *p=pt;for(int i=0;i<len;++i)p++;*p=5;cout<<"The value of p is "<<*p<<endl;return 0;
}

(2)结果如下:

4、内容覆盖:

(1)程序如下:

#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
int main(){char x[50];int i;for(i=0;i<50;++i)x[i]=i+1;strncpy(x+20,x,20);strncpy(x+20,x,21);strncpy(x+20,x,20);strncpy(x+20,x,21);x[39]='\0';strcpy(x,x+20);x[39]=39;x[40]='\0';strcpy(x,x+20);return 0;
}

(2)结果如下:

5、动态内存管理:

(1)程序如下:

#include<iostream>
#include <stdlib.h>
using namespace std;
int main(){int i;char *p=(char*)malloc(10);char *pt=p;for(i=0;i<10;++i){p[i]='z';}delete p;pt[1]='x';free(pt);return 0;
}

(2)结果如下:

内存检查工具valgrind介绍、安装与使用相关推荐

  1. linux valgrind memCheck ---内存检查工具的可视化方法valkyrie

    linux valgrind memCheck -内存检查工具的可视化方法valkyrie linux valgrind Memcheck–内存检查工具 1.安装valgrind valgrind 安 ...

  2. valgrind 简介(内存检查工具)

    1. valgrind 简介 1. valgrind 简介 1.1. 概图 1.2. 特点 1.3. 使用示例 1.4. 参数说明 1.4.1. 常用参数 1.4.2. 展示 1.4.3. 子进程.动 ...

  3. 【Linux】内存检测工具Valgrind

    内存检测工具Valgrind Valgrind是运行在Linux上的一套基于仿真技术的程序调试和分析工具,作者是获得过Google-O'Reilly开源大奖的Julian Seward,它包含一个内核 ...

  4. Windows系统内存分析工具的介绍

    Windows系统内存分析工具的介绍(进程管理器,资源管理器,性能监视器, VMMap, RamMap,PoolMon) 微软官方提供多种工具来分析Windows 的内存使用情况,除了系统自带的任务管 ...

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

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

  6. 动态内存检测工具Valgrind

    1. Valgrind查找内存泄露利器 Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析.你可以在它的环境中运行你的程序来 ...

  7. php 代码 自动检查工具下载,PHP_CodeSniffer安装和使用教程(自动代码检查规范工具)...

    在我们开发中都会讲究代码规范,若是个人开发者,代码规范与否,只要自己看得懂便可以了,但是在团队协作中,代码规定尤为重要,下面,我们介绍一款PHP_CodeSniffer,自动检查代码规范的工具. PH ...

  8. MAT内存分析工具-独立版安装教程及实战教学

    MAT是什么? MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速.功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗.使 ...

  9. ASan(Linux),gcc4.8以上版本自带的内存检查工具

    转自:http://shafeng.github.io/2017/05/10/asan/ 最近线上的程序总是莫名其妙崩溃,因为我们的项目使用了分布负载的机制,对于玩家的影响其实很小,但是我肯定是忍不了 ...

  10. iphone内存检查工具leak

    iphone下面检查内存的工具,大家都知道是leak,而且这个工具也很强大,可以这么说,只要是它报出来的泄露,基本上都是自己程序代码的问题, 当然,有的时候它没那么智能,报的位置不是那么准确,它基本上 ...

最新文章

  1. Angular2响应式表单
  2. 灾难恢复级别_防患于未然:灾难恢复全攻略,助你有效恢复业务数据
  3. php插件 pycharm_原来Pycharm中有这么多好用的插件|Pycharm精选插件
  4. 攻防世界 web(二)
  5. 04-老马jQuery教程-DOM节点操作及位置和大小
  6. c++ 静态变量赋值_Python变量及常量解释说明
  7. 【渝粤题库】国家开放大学2021春2476旅游学概论题目
  8. Java 跨平台运行机理:Dos 命令在桌面新建文件夹,并在其中编译、运行一段 Java 程序
  9. hdu 1231 最大连续子序列 ,1003 Max Sum;
  10. view函数_python测试开发django63.基于函数的视图(@api_view())
  11. 向你推荐一个免费电话
  12. 信创办公--基于WPS的Word最佳实践系列(图片背景的删除)
  13. 速读原著-UnixLinux基础(六)
  14. 聊聊几个阿里 P8、P9 程序员的故事
  15. 使用 CSS Color-Mix() 简化你的调色板
  16. 微信更新值得注意的几点
  17. Apache Doris1.0版本集群搭建、负载均衡与参数调优
  18. 俏丽教师杂志俏丽教师杂志社俏丽教师编辑部2022年第9期目录
  19. java冒泡排序(java冒泡排序经典代码)
  20. IOS 之FishHook原理及例子

热门文章

  1. 如何解决js引入混乱_做个笔记,图片如何实现懒加载(LazyLoad按需加载)
  2. PTA 程序设计天梯赛(141~160题)
  3. L1-064 估值一亿的AI核心代码 (20 分)—团体程序设计天梯赛
  4. Android RatingBar 实现评星功能
  5. JMeter录制的两种方法
  6. 自己的包增加为第三方包,使用Eclipse环境报Unresolved import错误(pycharm可用正常引用)...
  7. JQuery表单验证插件EasyValidator
  8. 论Web控件开发 - 完美上传下载控件“新”(一)
  9. OSPF特殊区域的作用
  10. 常用网络协议的端口号