Valgrind——内存调试和性能分析工具

news2025/4/8 9:01:53

文章目录

  • 一、Valgrind 介绍
  • 二、Valgrind 功能和使用
    • 1. 主要功能
    • 2. 基本用法
      • 2.1 常用选项
      • 2.2 内存泄漏检测
      • 2.3 详细报告
      • 2.4 性能分析
      • 2.5 多线程错误检测
  • 三、在 Ubuntu 上安装 Valgrind
  • 四、示例
    • 1. 检测内存泄漏
    • 2. 使用未初始化的内存
    • 3. 内存读写越界
    • 4. 综合错误
  • 五、工具集
    • 1. Memcheck
    • 2. Callgrind
    • 3. Cachegrind
    • 4. Helgrind
    • 5. Massif

一、Valgrind 介绍

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

Valgrind 是一个强大的内存调试和性能分析工具,广泛用于 Linux 系统上的程序开发和测试。它可以帮助开发者检测内存泄漏、数组越界、未初始化变量等问题,并提供详细的报告。Valgrind 支持多种编程语言,尤其是 C 和 C++。

Valgrind可以帮助开发者检测和修复程序中的内存问题和性能瓶颈。通过合理使用 Valgrind 的各种工具和选项,可以显著提高程序的质量和性能。

二、Valgrind 功能和使用

1. 主要功能

valgrind 主要功能包括:

  1. 内存泄漏检测:检测程序中未释放的内存分配。
  2. 数组越界检测:检测数组访问越界的情况。
  3. 未初始化变量检测:检测使用未初始化的变量。
  4. 多线程错误检测:检测线程同步问题,如数据竞争。
  5. 性能分析:提供详细的性能分析报告,帮助优化程序。

2. 基本用法

Valgrind 的基本用法是:

valgrind [valgrind-options] ./your-program [program-options]

其中,[valgrind-options]表示Valgrind的选项。

2.1 常用选项

  1. –tool=tool_name:指定要使用的Valgrind工具,如Memcheck、Callgrind等。
  2. –leak-check=full:在程序退出时检查内存泄漏,并显示所有的内存泄漏信息。
  3. –track-origins=yes:跟踪未初始化变量的来源。
  4. –log-file=<文件>:将Valgrind输出的信息保存至文件中。

2.2 内存泄漏检测

valgrind --leak-check=yes ./your-program

2.3 详细报告

valgrind --leak-check=full --show-leak-kinds=all ./your-program

2.4 性能分析

valgrind --tool=callgrind ./your-program

2.5 多线程错误检测

valgrind --tool=helgrind ./your-program

三、在 Ubuntu 上安装 Valgrind

打开虚拟机,执行以下命令安装 valgrind:

sudo apt-get install valgrind

在这里插入图片描述

四、示例

1. 检测内存泄漏

内存泄漏源码示例:
memleak.c

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
       char *ptr;
       ptr = (char *)malloc(10);
       return 0;
}

编译程序,然后用valgrind检测,可以知道在程序退出时还有多少内存没释放。

gcc -g -o memleak memleak.c
valgrind --tool=memcheck ./memleak

在这里插入图片描述

可以看到,如果我们仅仅用默认方式执行,valgrind只报告内存泄漏,但没有显示具体代码中泄漏的地方。

因此我们需要使用 “–leak-check=full”选项启动 valgrind,我们再执行一次:

valgrind --leak-check=full ./memleak

在这里插入图片描述
和上次的执行结果基本相同,只是指明了代码中出现泄漏的具体位置。

2. 使用未初始化的内存

代码示例:

#include <stdio.h>                                                              
int main()
{
    int x;
    if(x == 0)
    {
        printf("X is zero");
    }
    return 0;
}

编译程序,然后用valgrind检测:

gcc -g -o test test.c
valgrind --tool=memcheck  ./test 

在这里插入图片描述

3. 内存读写越界

代码示例:

#include <stdlib.h>
#include <stdio.h>
int main(int argc,char *argv[])
{
    int len=5;
    int i;
    int *pt=(int*)malloc(len*sizeof(int));
    int *p=pt;
    for(i = 0; i < len; i++)
    {
	    p++;
    }
    
    *p=5;
    printf("%d",*p);
    
    return 0;
}

在 for 循环中,p 是一个指向动态分配数组的指针。每次循环,p 都会递增。循环结束后,p 指向了动态分配数组的最后一个元素的下一个位置。此时,p 已经越界,指向了不属于分配内存的区域。
所以试图通过 p 解引用并赋值,但由于 p 已经越界,这会导致未定义行为(Undefined Behavior, UB)。程序可能会崩溃,或者导致其他不可预测的行为。

编译程序,然后用valgrind检测:

gcc -g -o test test.c
valgrind --tool=memcheck  ./test 

在这里插入图片描述

4. 综合错误

代码示例:包括堆中的内存越界、踩内存、栈中的内存越界、非法指针。

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    char *ptr = malloc(10);
    ptr[12] = 'a'; // 内存越界
    memcpy(ptr + 1, ptr, 5); // 踩内存
    char a[10];
    a[12] = 'i'; // 数组越界
    free(ptr); // 重复释放
    free(ptr);
    char *p1;
    *p1 = '1'; // 非法指针
   
    return 0;
}

编译程序,然后用valgrind检测:

gcc -g -o test test.c
valgrind --tool=memcheck  ./test 

在这里插入图片描述
在这里插入图片描述

五、工具集

Valgrind工具集中包含了多个实用的工具,每个工具都有其特定的功能。

1. Memcheck

内存错误检测器,能够发现开发中绝大多数内存错误使用情况,比如使用未初始化的内存、使用已经释放了的内存、内存访问越界等。它还可以分析热点函数和函数调用流程,帮助优化程序性能。

2. Callgrind

用于分析程序的函数调用关系,收集程序运行时的一些数据,建立函数调用关系图。它还可以有选择地进行cache模拟,并在运行结束时将分析数据写入一个文件。

3. Cachegrind

分析程序的缓存使用情况和缓存命中率,通过模拟处理器缓存的访问情况来统计程序的缓存行使用情况、缓存命中率和缓存失效次数等信息。

4. Helgrind

线程错误检测器,用于检查多线程程序中出现的竞争问题。它寻找内存中被多个线程访问而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,容易导致难以发现的错误。

5. Massif

堆栈分析器,主要用来检查程序中堆栈使用中出现的问题。它能测量程序在堆栈中使用了多少内存,帮助开发者了解块寿命、块利用率和布局效率低下的问题。

此外,Valgrind还提供了其他工具,如DHAT(用于检测堆内存分配和使用情况)等,以满足不同开发者的需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2330360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习MySQL第七天

夕阳无限好 只是近黄昏 一、子查询 1.1 定义 将一个查询语句嵌套到另一个查询语句内部的查询 我们通过具体示例来进行演示&#xff0c;这一篇博客更侧重于通过具体的小问题来引导大家独立思考&#xff0c;然后熟悉子查询相关的知识点 1.2 问题1 谁的工资比Tom高 方…

Spring启示录、概述、入门程序以及Spring对IoC的实现

一、Spring启示录 阅读以下代码&#xff1a; dao package org.example1.dao;/*** 持久层* className UserDao* since 1.0**/ public interface UserDao {/*** 根据id删除用户信息*/void deleteById(); } package org.example1.dao.impl;import org.example1.dao.UserDao;/**…

电机的了解到调试全方面讲解

一、什么是电机 电机是一种将电能转换为机械能的装置,通常由定子、转子和电磁场组成。 当电流通过电机的绕组时,产生的磁场会与电机中的磁场相互作用,从而使电机产生旋转运动。电机广泛应用于各种机械设备和工业生产中,是现代社会不可或缺的重要设备之一。 常见的电机种…

笔试专题(七)

文章目录 乒乓球筐&#xff08;哈希&#xff09;题解代码 组队竞赛题解代码 删除相邻数字的最大分数&#xff08;线性dp&#xff09;题解代码 乒乓球筐&#xff08;哈希&#xff09; 题目链接 题解 1. 两个哈希表 先统计第一个字符串中的字符个数&#xff0c;再统计第二个字…

【嵌入式学习3】UDP发送端、接收端

目录 1、发送端 2、接收端 3、UDP广播 1、发送端 from socket import *udp_socket socket(AF_INET,SOCK_DGRAM) udp_socket.bind(("127.0.0.1",3333))data_str "UDP发送端数据" data_bytes data_str.encode("utf-8") udp_socket.sendto(d…

Linux 系统 SVN 源码安装与配置全流程指南

Linux系统SVN源码安装与配置全流程指南 一、环境准备 系统要求 CentOS 7及以上版本需安装GCC编译工具链 依赖项 APR/APR-UTIL&#xff08;Apache可移植运行库&#xff09;SQLite&#xff08;嵌入式数据库&#xff09;zlib&#xff08;数据压缩库&#xff09; 二、下载及安装…

Redis 的五种数据类型面试回答

这里简单介绍一下面试回答、我之前有详细的去学习、但是一直都觉得太多内容了、太深入了 然后面试的时候不知道从哪里讲起、于是我写了这篇CSDN帮助大家面试回答、具体的深入解析下次再说 面试官你好 我来介绍一下Redis的五种基本数据类型 有String List Set ZSet Map 五种基…

关于类模板STL中vector容器的运用和智能指针的实现

代码题&#xff1a;使用vector实现一个简单的本地注册登录系统 注册&#xff1a;将账号密码存入vector里面&#xff0c;注意防重复判断 登录&#xff1a;判断登录的账号密码是否正确 #include <iostream> #include <cstring> #include <cstdlib> #in…

Opencv计算机视觉编程攻略-第十一节 三维重建

此处重点讨论在特定条件下&#xff0c;重建场景的三维结构和相机的三维姿态的一些应用实现。下面是完整投影公式最通用的表示方式。 在上述公式中&#xff0c;可以了解到&#xff0c;真实物体转为平面之后&#xff0c;s系数丢失了&#xff0c;因而无法会的三维坐标&#xff0c;…

git修改已经push的commit的message

1.修改信息 2.修改message 3.强推

2026考研数学张宇武忠祥复习视频课,高数基础班+讲义PDF

2026考研数学武忠祥老师课&#xff08;网盘&#xff09;&#xff1a;点击下方链接 2026考研数学武忠祥网课&#xff08;最新网盘&#xff09; 一、基础阶段&#xff08;3-5个月&#xff09; 目标&#xff1a;搭建知识框架掌握基础题型 教材使用&#xff1a; 高数&#xff1a;…

C++使用Qt Charts可视化大规模点集

引言 数据可视化是数据分析和决策过程中的重要环节。随着数据量的不断增长&#xff0c;如何高效地可视化大规模数据集成为了一个挑战。Qt Charts 提供了一个强大的工具集&#xff0c;用于创建直观的数据可视化图表。本文将探讨如何使用 C 和 Qt Charts 可视化大规模点集&#…

质检LIMS系统在生态修复企业的实践 生态修复行业的质量管控难题

一、生态修复行业的质量管控新命题 在生态文明建设的大背景下&#xff0c;生态修复企业面临着复杂的环境治理挑战。土壤改良、水体净化、植被恢复等工程&#xff0c;均需以精准的实验数据支撑决策。传统实验室管理模式存在数据孤岛、流程非标、合规风险高等痛点&#xff0c;而…

Spring Cloud之服务入口Gateway之Route Predicate Factories

目录 Route Predicate Factories Predicate 实现Predicate接口 测试运行 Predicate的其它实现方法 匿名内部类 lambda表达式 Predicate的其它方法 源码详解 代码示例 Route Predicate Factories The After Route Predicate Factory The Before Route Predicate Fac…

《AI大模型应知应会100篇》第6篇:预训练与微调:大模型的两阶段学习方式

第6篇&#xff1a;预训练与微调&#xff1a;大模型的两阶段学习方式 摘要 近年来&#xff0c;深度学习领域的一个重要范式转变是“预训练-微调”&#xff08;Pretrain-Finetune&#xff09;的学习方式。这种两阶段方法不仅显著提升了模型性能&#xff0c;还降低了特定任务对大…

java后端对时间进行格式处理

时间格式处理 通过java后端&#xff0c;使用jackson库的注解JsonFormat(pattern "yyyy-MM-dd HH:mm:ss")进行格式化 package com.weiyu.pojo;import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; import lombok.Data; import …

汽车BMS技术分享及其HIL测试方案

一、BMS技术简介 在全球碳中和目标的战略驱动下&#xff0c;新能源汽车产业正以指数级速度重塑交通出行格局。动力电池作为电动汽车的"心脏"&#xff0c;其性能与安全性不仅直接决定了车辆的续航里程、使用寿命等关键指标&#xff0c;更深刻影响着消费者对电动汽车的…

【TI MSPM0】CMSIS-DSP库学习

一、什么是CMSIS-DSP库 基于Cortex微控制器软件接口标准的数字信号处理的函数库 二、页面概览 这个用户手册用来描述CMSIS-DSP软件的函数库&#xff0c;有通用的计算处理函数给Cortex-M和Cortex-A的处理器使用 三、工程学习 1.导入工程 2.样例介绍 在Q15的格式下&#xff0c…

Vue3:初识Vue,Vite服务器别名及其代理配置

一、创建一个Vue3项目 创建Vue3项目默认使用Vite作为现代的构建工具&#xff0c;以下指令本质也是通过下载create-vue来构建项目。 基于NodeJs版本大于等于18.3&#xff0c;使用命令行进行操作。 1、命令执行 npm create vuelatest输入项目名称 2、选择附加功能 选择要包含的功…

Go语言类型捕获及内存大小判断

代码如下&#xff1a; 类型捕获可使用&#xff1a;reflect.TypeOf()&#xff0c;fmt.Printf在的%T。 内存大小判断&#xff1a;len()&#xff0c;unsafe.Sizeof。 package mainimport ("fmt""unsafe""reflect" )func main(){var i , j 1, 2f…