首页 > 其他分享 >valgrind使用方法

valgrind使用方法

时间:2023-04-29 15:44:13浏览次数:62  
标签:-- Memcheck valgrind int 内存 使用 include 方法

valgrind使用

1. Preface

 valgrind是一套Linux下开源的程序仿真调试和分析工具的集合;集合中的每个工具负责执行某种类型的仿真,调试,或者分析任务;它的主要结构包括一个内核(软件模拟CPU环境)以及一系列的小工具。

valgrind包含的工具主要如下:

  • Memcheck

    主要针对C和C++程序的内存管理和分配错误;Memcheck会检测运行程序对内存所有的读写操作,包括(new/delete 和 malloc/free),Memcheck会对一下错误进行检测:
    (1) 访问非法的内存(未分配,已释放,堆边界以外的区域,栈不可访问的区域)
    (2) 以不安全的方式使用未初始化的值
    (3) 内存泄漏
    (4) 对内存释放异常(多次释放)
    (5) 向memcpy()函数传递的src和dst内存有重叠
    对于上述相关的错误,Memcheck会给出在源代码中的出错位置以及对应的调用栈信息

  • Cachegrind

    Cache分析器,它能够模拟CPU中的一级缓存L1,D1和二级缓存,且能够精确指出程序中cache的命中和丢失,此外还可以给出cache丢失次数;Cachegrind还可以给出每行代码,每个函数,每个模块,和整个程序的内存引用次数以及指令数;有利于优化程序;

  • Callgrind

    Callgrind相当于Cachegrind的一个扩展,它除了能够给出Cachegrind提供的所有信息之外,还可以给出程序的调用图;此外它还可作为一个独立的工具进行使用,可用于可视化的展示Callgrind收集到的数据;也可用于可视化的展示Cachegrind的输出信息;

  • Massif

    堆分析器,Massif通过程序的堆内存快照技术,实现堆内存的分析;Massif会生成一张表示程序运行过程中堆内存使用情况的图,包括在运行过程中哪个模块占用的堆内存最多等信息;生成的图以文本文件或者html文件呈现,

  • Helgrind

    Helgrind是线程调试器,用于检测多线程程序中出现的数据竞争问题,Helgrind会去查找被多个线程访问的内存区域,且检测这些内存区域在使用时是否进行了线程同步,如果没有,则这些内存区域会是潜在的隐患,可能会造成一些非常棘手的问题。

  • DRD

    功能与Helgrind类似,但是占用内存更少;

  • SGcheck

    用于检测栈和全局数组溢出

2. valgrind安装

源码下载地址:Valgrind官方网站

wget http://www.valgrind.org/downloads/valgrind-3.14.0.tar.bz2

2.1 解压安装包

tar -xvf valgrind-3.20.0.tar.bz2

2.2 运行autogen.sh
cd valgrind-3.20.0

./autogen.sh

如果提示缺少相应的autotools系列工具,则执行:

sudo apt get install autoconf

autotools系列工具包括如下子工具:

  • aclocal
  • autoscan
  • autoconf
  • autoheader
  • automake
2.3 运行configure脚本

./configure

2.4 编译安装
make 

sudo make install
3. valgrind使用

使用格式:

valgrind [options] prog-and-args

options选项:

  • -tool=<toolname> 选择valgrind工具集中的工具,默认为memcheck
  • -v/--version 显示版本信息
  • -h/--help 显示帮助信息
  • -q/--quiet 安静模式,只打印错误信息
  • -v/--verbose 打印详细信息
  • --trace-children=no|yes 是否跟踪子进程,默认值no
  • --trace-fds=no|yes 是否跟踪打开的文件描述符,默认值no
  • --time-stamp=no|yes 是否在打印的信息前面加上时间戳,默认值no

关于输出的选线:

  • --log-fd=<num> 输出Log信息到指定的文件描述符(0,1,2 /stdin,stdout,stderr)
  • --log-file=<file> 将Log信息输出到指定文件
  • --log-socket=ipAddr:Port 将Log输出到指定的socket
4. Memcheck的使用
  • --leak-check=no|summary|full 在退出时是否查找内存泄漏

    no表示不检查 summary表示输出概括性的信息 full表示输出详细信息

  • --leak-resolution=<low|med|high>

    表示是否将内存检查的结果进行合并展示,只会影响展示,不影响内存检查的结果(因为大概是这个意思)

  • --show-leak-kinds=<set>

    指定显示内存泄漏的种类 可选值:definite,indirect,possible,reachable,all

其他的参数可查阅说明书:https://valgrind.org/docs/manual/mc-manual.html#mc-manual.overview

Memcheck可检测的错误包括:

1.非法的读写错误

在程序读写Memcheck认为不合法的地址时,会输出类似的错误,例如访问已经释放的内存,以及非法的栈地址;

测试代码:

#include <stdlib.h>

int main(int argc, char* argv[])
{
    int* p = (int*)malloc(sizeof(int));

    *p = 1;

    *(p+1) = 2;      // 非法地址,未经过分配

    free(p);

    return 0;
}

Memcheck Log输出信息:

img

输出信息中需要注意如果ERROE SUMMARY: 后的错误数量不为0,则仔细查看输出的日志信息;

2.使用未初始化的值

测试代码:

#include <stdio.h>

int main(int argc, char* argv[])
{
    int x;
    
    printf("The value is %d\n", x);

    return 0;
}

Memcheck Log输出信息:

如果不想Memcheck检测此类错误,可以添加参数设置:

--undef-value-errors=no

3.未初始化或者在系统调用中无法寻址的变量

Memcheck会检测所有系统调用涉及到的参数,包括如下:

  • 如果系统调用需要从程序提供的缓冲区中读取数据,那么memcheck会检测缓冲区的地址是否有效以及缓冲区中的数据是否进行了初始化
  • 如果系统调用需要从程序提供的缓冲区中写入数据,则memcheck会检测缓冲区地址的有效性

测试代码:

#include <stdlib.h>
#include <unistd.h>

void test()
{
   char* arr  = (char*)malloc(10);

   int*  arr2 = (int*)malloc(sizeof(int));

   write( 1 /* stdout */, arr, 10 );

   exit(arr2[0]);   // arr2[0]无法进行寻址
}

int main(void)
{
   test();
}

Memcheck输出信息:

img

4. 非法的内存释放

Memcheck会对程序中使用new/malloc分配的内存进行持续追踪,因此它能够检测出传递给free/delete的内存地址是否是合法的;例如对同一块动态分配的内存执行两次释放;则第二次释放,free/delete的参数(地址)就是不合法的

测试程序:

#include <stdlib.h>
#include <unistd.h>

int main(void)
{
   char* arr  = (char*)malloc(10);

   free(arr);

   free(arr);      // 重复释放内存

   return 0;
}

img

5. 堆内存释放和分配函数不匹配

在c++中,内存的分配与释放函数必须匹配:

  • 使用malloc, calloc, realloc, valloc, memalign分配的内存,必须使用free进行释放
  • 使用new分配的内存必须使用delete进行释放
  • 使用new []分配的内存必须使用delete []进行释放
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>

int main(void)
{
    char* arr  = (char*)malloc(10);

    delete arr;

    return 0;
}

img

备注:在Linux平台上混用new和free并不会导致出错,但是在其他的平台上却不一定,可能会导致程序crash;

The reason behind the requirement is as follows. In some C++ implementations, delete[] must be used for objects allocated by new[] because the compiler stores the size of the array and the pointer-to-member to the destructor of the array's content just before the pointer actually returned. delete doesn't account for this and will get confused, possibly corrupting the heap. <from: https://valgrind.org/docs/manual/mc-manual.html#mc-manual.bad-syscall-args>

6. 源地址和目标地址的出现内存覆盖(overlapping)

c/c++语言可直接对内存进行操作,提供了许多的内存拷贝函数,memcpy, strcpy, strncpy, strcat, strncat,POSIX标准规定,如果对象之间的内存拷贝出现相互覆盖,则将导致最后的结果是不确定的;

标签:--,Memcheck,valgrind,int,内存,使用,include,方法
From: https://www.cnblogs.com/ncepubye/p/17315239.html

相关文章

  • 使用findIndex查找并做一些操作
    1.查找指定数据并删除letfindIndex=arrItemsApprover.findIndex(item=>item.zusrid===oObject.zusrid);if(findIndex!==-1){ arrItemsApprover.splice(findIndex,1);}2.查找指定数据并添加属性arrData.forEach(item=>{if(selectApproveUserData.findIndex(i=>item......
  • js封装深拷贝方法
    deepCopy:function(data){ if(data===null||data===undefined){ returnnull; } letresult=Array.isArray(data)?[]:{}; if(data&&typeofdata==='object'){ for(letkeyindata){ if(data[key]&&typeof......
  • 博客园中如何使用HTML所见即可得编辑器TinyMCE
    大纲基本内容:文本、段落规范结构:标题、大纲大量数据:表格、列表内外跳转:链接、锚点视觉媒体:图像、视频、音乐用户交流:表单、交互文本字体、大小、前景色、背景色、加粗、倾斜、下划线、中划线、清楚格式段落段落行间距、段落字间距、段落居中对其、段落居左对齐、......
  • 奇安信使用手册
    0.0登录账号为学号初始密码为123@Qweasd首次进入会自动更改密码1.0主界面2.0添加课程自主学习目光锁定左侧导航栏点击自主学习首次进入是没有任何课程(我是因为自己添加一次课程才有课)目光锁定右上角添加每个课右上角都有的标志,点击即可加入课程选择课程后,点击左......
  • pip 默认源使用虽然有时候慢,但是可以避免很多包的问题
    这里放上pip的默认源地址https://pypi.org/simple有时候我们在国内虽然使用清华或者豆瓣等源,但是有很多包的新版本都没有缓存下来,如果我们按照git项目创建环境可能就会因为源的问题导致无法复现,所以最好还是默认源......
  • Jupyter Notebook 配置与使用指南
    1、“.py”和“.ipynb”文件通常,我们看到的用Python语言编写的源代码文件,其文件后缀是",py"或".ipynb"。其中".py"文件是标准的Python源代码文件,通常情况下,我们会使用".py"的python源代码文件。.ipynb(即ipythonnotebook缩写)是jupyter可识别的后缀,其用来数据分析和画图非常方便的......
  • .net 6 使用 NEST 查询,时间字段传值踩坑
    0x01业务描述说明:同事搭建的业务系统,最开始使用 log4net 记录到本地日志.然后多个项目为了日志统一,全部记录在 Elasticsearch ,使用  log4net.ElasticSearchAppender.DotNetCore.然后搭建了Kibanal  对 Elasticsearch 进行查询. 但是项目组开发人员众多,不......
  • 【Jetpack】ViewModel + LiveData + DataBinding 综合使用 ( 核心要点说明 | 组合方式
    文章目录一、ViewModel+LiveData+DataBinding核心要点1、ViewModel使用要点2、LiveData使用要点3、DataBinding使用要点二、ViewModel+LiveData+DataBinding代码示例1、ViewModel+LiveData代码2、build.gradle构建脚本-启用DataBinding3、DataBinding布局文......
  • 自动化测试工具自动化工具Pyautogui和Pywinauto详细介绍和使用
    自动化测试工具介绍和使用PC端应用程序自动化测试——pywinauto、pywin32、pyautogui详解Python中pyautogui库的最全使用方法自动化测试工具自动化工具Pyautogui和Pywinauto详细介绍和使用   1、自动化测试工具介绍和使用一.Pywinauto库的介绍二、pyautogui库的......
  • stm32cubeIde中使用shift+鼠标单击批量删除多行代码
    先从一个位置点击鼠标左键,然后拖动滚动条在需要开始或者结束的地方按着shift在点击鼠标左键,这样就可以批量删除了,对于几千行的代码来说,特别有用!什么?一个文件不会这么多行?呵呵。你再想想。......