当前位置: 首页 > article >正文

linux-valgrind检测分析C/C++程序(三)

这章主要讲述valgrind的使用
官方 地址:https://valgrind.org/
在这里插入图片描述
检测内存泄漏
Windows平台下的内存检测方法
VLD(Visual Leak Detector)工具
CRT库
windows 性能分析 AQTIME

1:介绍
valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。valgrind由内核(core)以及基于内核的调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其它工具;而其它工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的调试分析任务。
Memcheck:内存错误检测器。 能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等;
Cachegrind :缓存和分支预测分析器。 分析热点函数,函数调用流程等,它可以帮助您使程序运行得更快。模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。
Callgrind :调用图生成缓存分析器。 它与 Cachegrind 有一些重叠,但也收集了 Cachegrind 没有的一些信息。
Helgrind :线程错误检测器。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。 它可以帮助您使您的多线程程序更加正确。
DRD :线程错误检测器。 它与 Helgrind 类似,但使用不同的分析技术,因此可能会发现不同的问题。
Massif :堆分析器。能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。 它可以帮助您减少程序使用的内存。
DHAT :是一种不同类型的堆分析器。 它可以帮助您了解块寿命、块利用率和布局效率低下的问题。
BBV :实验性的 SimPoint 基本块向量生成器。 对于从事计算机体系结构研究和开发的人来说很有用。

2:安装
1>valgrind 安装
sudo apt-get install valgrind
2>KCacheGrind 安装(KCacheGrind是一个Linux下的性能分析工具,可以用来分析程序的运行时间和内存使用情况)
sudo apt-get update
sudo apt-get install kcachegrind

在这里插入图片描述
在这里插入图片描述
使用说明
Memcheck: 用于检测内存错误,如内存泄漏、非法内存访问等。
Callgrind: 用于收集程序运行时的函数调用信息,帮助进行性能分析。
Cachegrind: 它主要用来检查程序中缓存使用出现的问题。
Helgrind: 它主要用来检查多线程程序中出现的竞争问题。
Massif: 用于分析程序的内存使用情况,帮助优化内存分配。

valgrind不会自动的检查程序的每一行代码,只会检查运行到的代码分支。
编译代码时,建议增加-g -o0选项,不要使用-o1、-o2选项。这样错误信息才能定位到代码行

命令的语法格式
valgrind -q --tool=<tool_name> --log-file=<file_name> <other_options> ./<program_name>
-q: -quiet 安静地运行,只打印错误信息,如版本号。
–tool=<tool_name>: 要使用的工具名称,如:memcheck、callgrind,该选项未设置时,默认为memcheck。tool_name可以是
memcheck
callgrind
cachegrind
helgrind
massif
–log-file=<file_name>: 日志输出文件。
<other_options>: 针对tool_name的其他选项。

3:测试
测试代码

#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
void no_leak_mem()
{
    int *p[3] ={NULL,NULL,NULL};
    p[0] = (int *)malloc(sizeof(int));
    p[1] = (int *)malloc(sizeof(int) * 2);
    p[2] = (int *)malloc(sizeof(int) * 3);

    free(p[0]);
    free(p[1]);
    free(p[2]);
}

void has_leak_mem()
{
    int *p[3] ={NULL,NULL,NULL};
    p[0] = (int *)malloc(sizeof(int));
    p[1] = (int *)malloc(sizeof(int) * 2);
    p[2] = (int *)malloc(sizeof(int) * 3);

    free(p[0]);
    free(p[1]);
   // free(p[2]);
}

//非法地址访问
void invalid_address_access()
{
    int *p = NULL;
    printf("val = %d\n", *p);
}


void corss_border_read_write()
{
    int a = 0x10;
    int *p = &a + 0x10;

    //越界读  程序不崩溃,可能导致逻辑错误
    printf("cross border address read %x\n", *p);

    //越界写  程序错误
    *p = 0x87654321;
    //printf("cross border address write %x\n", *p);
}

int main(){
	cout<<"test no_leak_mem"<<endl;
	no_leak_mem();
	cout<<"test has_leak_mem"<<endl;
	has_leak_mem();
	cout<<"test invalid_address_access"<<endl;
	//invalid_address_access();
	cout<<"test corss_border_read_write"<<endl;
	corss_border_read_write();
	cout<<"test finish"<<endl;
}

//g++ -g -o testleak  ./testleak.cpp
//valgrind --leak-check=full ./testleak

运行结果
在这里插入图片描述
内存越界测试

#include<stdio.h>
#include<stdlib.h>
int main(){
	int i;
	int len = 8;
	int *pt = (int*)malloc(len*sizeof(int));
	int *p = pt;
	for(i=0;i<len;i++)
	{
		p++;
	}
	*p = 9;

	return 0;
}

在这里插入图片描述
性能分析

#include <unistd.h>
#include <stdlib.h>
#include <thread>  
#include <iostream>
 
void thread_routine(unsigned long long n) {
    while (true) {
        const int array_size = 32;
        char buf[array_size] = {0};
        sprintf(buf, "%lu\n", n++);
        printf(buf);
    }   
}
 
int main() {
    std::thread t(thread_routine, 0); 
    t.detach();
    sleep(10);    
    return 0;  
}
//g++ -O0 -g -std=c++11 -lpthread testcallgrind.cpp -o test3
//valgrind --tool=callgrind --separate-threads=yes ./test3
//kcachegrind  ./callgrind.out.20486

用kcachegrind ./callgrind.out.20486 查看
在这里插入图片描述
在这里插入图片描述
valgrind 其他的工具 后面有空再补上

4:如果觉得有用,麻烦点个赞,加个收藏


http://www.kler.cn/a/377515.html

相关文章:

  • Spring框架和Spring Boot框架都使用注解来简化配置和提高开发效率,但它们之间存在一些区别
  • DCRNN解读(论文+代码)
  • HarmonyOS Next星河版笔记--界面开发(3)
  • Spring Boot 内置工具类
  • 我们来学mysql -- 同时使用 AND 和 OR 查询错误(填坑篇)
  • Docsify文档编辑器:Windows系统下个人博客的快速搭建与发布公网可访问
  • 4. STM32之TIM实验--输出比较(PWM输出,电机,四轴飞行器,智能车,机器人)--(实验2:PWM驱动舵机)
  • Java方法的使用
  • MP4650模块改为固定电压记录
  • 【C++】深入理解 C++ 输入输出同步机制:为什么 cin/cout 没有 scanf/printf 快?
  • Java: 遍历 Map
  • Ubuntu编译linux内核指南(适用阿里云、腾讯云等远程服务器;包括添加Android支持)
  • golang有序map
  • vue3 + ts + element-plus 二次封装 el-table
  • ✨ Midjourney中文版:创意启航,绘梦无界 ✨
  • Harmony NEXT - AlphabetIndexer实现联系人字母索引
  • 密码学简介
  • Python入门:如何掌控多线程数量
  • 【OD-支持在线评测】智能驾驶(200分)
  • 无人机之自动控制原理篇
  • oracle-函数-NULLIF (expr1, expr2)的妙用
  • Vuestic 数据表格 使用demo
  • HTML前端页面设计静态网站
  • [NOIP2008 普及组] 排座椅
  • 【Redis:原理、架构与应用】
  • 中阳量化交易模型的探索与发展:科技引领金融未来