valgrind 是个啥?

最近在看PG代码时,看到许多VALGRIND相关的宏,例如 VALGRIND_MAKE_MEM_DEFINED、 VALGRIND_MAKE_MEM_NOACCESS,特别是移植PG的某模块到OG时,由于OG中没有定义这些宏,遇到这些宏,一开始我也不知道该怎么办了。

后来了解了下,valgrind是一种可以探测你的C/C++程序是否有内存泄漏,或踩内存的程序,当然它还有其它功能,但是应用最多的就是memcheck功能了,对于valgrind的使用有两种情况:

1、C/C++程序用 -g 编译,然后用valgrind执行:

valgrind --leak-check=yes --log-file=1_g myprog arg1 arg2

如果有内存泄漏之类的问题,在执行过程或执行结束后会有相关打印。

2、还有一种情况是在客户程序(myprog)的代码中加入memcheck相关宏(#include valgrind.h或valgrind目录下的头文件),memcheck的仿真cpu在执行客户程序期间,会执行这些宏所代表的动作,或者这些宏会向memcheck仿真cpu传递一些信息,指导它检测内存错误。这样会让memcheck检测到之前检测不到的内存问题。

为了能够对自定义的内存分配系统进行跟踪,就需要在自定义的内存分配系统代码里加入种种valgrind宏,可以参考:

Use Valgrind Memcheck with a custom memory manager | Red Hat Developer

例如:

struct message*
next_message (struct message *m)
{
  int next_seq_nr = m->seq_nr + 1;

  /* clean up the old message... */
  memset (m, 0, sizeof (struct message));
  m->seq_nr = next_seq_nr;

  /* Except for the sequence number, everything else is undefined till
     frob () is used on the message.  */
  VALGRIND_MAKE_MEM_UNDEFINED (&m->msg, sizeof (struct rawmsg));
 
  return m;
}

VALGRIND_MAKE_MEM_UNDEFINED 告诉 memcheck仿真cpu,从&m->msg开始sizeof (struct rawmsg)大小的内存,标记为未定义(初始化)的内存,如果没有这个宏,memcheck仿真cpu会认为这块内存是已经被初始化的,因为前面调用了memset(memcheck仿真cpu会监视memset),如果后面的代码没有给msg赋值就直接读取,valgrind就会报错,注意,valgrind只会在日志或终端输出错误信息,并不会让客户程序退出(其它宏也是这样的),这个宏,一般在需要重用一块内存时使用。

类似测试程序还有:

#include <string>
#include <iostream>
#include <assert.h>
#include <cmath>
#include <cstring>
#include <valgrind/memcheck.h>
#include <unistd.h>
 

int main() {

    while(1) {
        void* p1 = malloc(229);
        int mod = ((long)p1) % 16;
        cout << p1 << " " << mod << endl;
        VALGRIND_MAKE_MEM_NOACCESS(p1, sizeof(int));
        *(int*)p1 = 33;
        //VALGRIND_MAKE_MEM_DEFINED(p1, 16);
        //VALGRIND_MAKE_MEM_UNDEFINED(p1, sizeof(int));
        int i = *(int*)p1;
        cout << i << endl;
        sleep(1);
    }

    return 0;
}
 

这个程序分配程序但是不释放,会导致valgrind报错,用VALGRIND_MAKE_MEM_NOACCESS标记p1开始的4字节int的内存时不可访问的(不可读写),后面有对这块内存的读写,都会报错。

还可尝试 VALGRIND_MAKE_MEM_UNDEFINED 设置一块内存是未定义(无论之前是否初始化),如何后面访问这块内存,valgrind就会报访问未定义内存的错误。


了解memcheck实现原理,有利于更好的使用valgrind,了解它的优缺点:

memcheck实现了一个仿真的cpu,C/C++二进制程序是被memcheck的仿真cpu解释执行的,仿真cpu可以在所有内存读写指令发出时 ,检测读写的合法性和地址的合法性。

虚拟cpu为进程地址空间的每个字节分配了8bit的bitmap,记录了这个字节的属性,例如是否被初始化过,是否被读写过,是否是有效值。

为每个cpu寄存器分配到了若干bit(具体几个我也不知道)的bitmap,记录了寄存器的属性。

还为每个字节分配了1bit的bitmap,记录这个字节的地址是否能被读写。

当然,不可能真的为进程地址空间的每个字节,分配记录其属性的bitmap,因为这些bitmap本身也占用地址空间的字节,memcheck只记录被客户程序触及到的进程地址空间字节的属性,未触及到的字节的属性,应该有办法压缩表示。

可见,以valgrind运行C/C++程序是会减慢速度,而且增加内存消耗的。


有了上面的认知,再来看PG代码中的VALGRIND_XXX宏,如果要把PG代码移植到OG,遇到这些宏,可以直接删掉。

参考:

valgrind基本功能介绍、基础使用方法说明_valgrind教程-CSDN博客

https://valgrind.org/docs/manual/mc-manual.html/mc-manual.html#mc-manual.machine

https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq

Use Valgrind Memcheck with a custom memory manager | Red Hat Developer

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

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

相关文章

C语言面试题之合并排序的数组

合并排序的数组 实例要求 1、给定两个排序后的数组 A 和 B&#xff0c;其中 A 的末端有足够的缓冲空间容纳 B&#xff1b; 2、编写一个方法&#xff0c;将 B 合并入 A 并排序&#xff1b; 3、初始化 A 和 B 的元素数量分别为 m 和 n&#xff1b; 示例: 输入: A [1,2,3,0…

小剧场短剧剧集收费短剧小程序APP

1. 内容展现 付费、免费、任务解锁&#xff1a;用户可以通过付费直接观看短剧&#xff0c;也可以通过完成平台任务&#xff08;如签到、分享等&#xff09;获得免费观看的机会。这种灵活的解锁方式既满足了用户的多种需求&#xff0c;也促进了平台的活跃度。主流展现形式&…

蓝桥杯简单模板

目录 最大公约数 两个数的最大公约数 多个数的最大公约数 最小公倍数 两个数的最小公倍数 多个数的最小公倍数 素数 ​编辑 位数分离 正写 ​编辑 反写 闰年 最大公约数 两个数的最大公约数 之前看见的是辗转相除法&#xff0c;例如现在让算一个49&#xff0c;21…

libVLC 提取视频帧使用OpenGL渲染

在上一节中&#xff0c;我们讲解了如何使用QWidget渲染每一帧视频数据。 由于我们不停的生成的是QImage对象&#xff0c;因此对 CPU 负荷较高。其实在绘制这块我们可以使用 OpenGL去绘制&#xff0c;利用 GPU 减轻 CPU 计算负荷&#xff0c;本节讲解使用OpenGL来绘制每一帧视频…

Leetcode面试经典150_Q169多数元素

题目&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊n/2⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 解题思路&#xff1a; 1. 注意“大于 ⌊n/2⌋”&#xff0c;…

【每日一题】2529. 正整数和负整数的最大计数-2024.4.9

题目&#xff1a; 2529. 正整数和负整数的最大计数 给你一个按 非递减顺序 排列的数组 nums &#xff0c;返回正整数数目和负整数数目中的最大值。 换句话讲&#xff0c;如果 nums 中正整数的数目是 pos &#xff0c;而负整数的数目是 neg &#xff0c;返回 pos 和 neg二者中…

A Survey for LLM

一、背景介绍 我们关注大模型中的两个主流&#xff1a;大语言模型和预训练的基础模型。01 大语言模型&#xff08;LLMs&#xff09; 语言建模是许多自然语言处理任务的基础&#xff0c;而大语言模型&#xff08;LLMs&#xff09;的初衷是为了提高语言建模的性能。与传统的神经语…

STM32之HAL开发——串行FLASH文件系统FatFs

文件系统 文件系统是为了存储和管理数据&#xff0c;而在存储介质建立的一种组织结构&#xff0c;这些结构包括操作系统引导区、目录和文件。 常见的 windows 下的文件系统格式包括 FAT32、 NTFS、exFAT。 在使用文件系统前&#xff0c;要先对存储介质进行格式化。格式化先擦除…

React 状态管理:高效处理数组数据的5种方法

1.原因 为什么在 React 中,状态(state)如果是数组类型,需要单独处理&#xff1f;主要有以下几个原因: 不可变性(Immutability): React 中的状态是不可变的,意味着我们不能直接修改状态,而是要创建一个新的状态对象。对于数组来说,直接修改数组元素是不符合 React 的设计原则的…

[LeetCode][LCR133]位 1 的个数——快速从右边消去1

题目 LCR 133. 位 1 的个数 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为 汉明重量).&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言…

多个代理proxy配置——日志查看代理后的地址

一个项目接口有两个域名&#xff0c;需要配置两个代理复制一个axios封装文件&#xff0c;修改baseUrl为新的标识 ququ新接口文件引入新的request1即可 proxy: {// 新接口采用 /ququ前缀/ququ: {target: http://192.168.2.82:8888, //鑫哥 changeOrigin: true,logLevel: debug, …

【Python】RocketMQ 基础使用

目录 1. 介绍 2. 实践 2.1. 启动消费者 2.2. 启动生产者 1. 介绍 RocketMQ是一个开源的分布式消息传递系统&#xff0c;最初由阿里巴巴集团开发并于2012年开源。它旨在解决高可靠性、高吞吐量、低延迟和可伸缩性等大规模分布式系统下的消息通信需求。 RocketMQ的设计目标…

vue对比react18

1.模板语法-——>jsx JSX表达式用{}包裹&#xff0c;vue模板表达式用{{}}包裹&#xff0c;其余一致。 注意:if语句、switch语句、变量声明属于语句&#xff0c;不是表达式&#xff0c;不能出现在{}或{{}}中 <!--vue--> <template><div><p>I have…

Java开发面试题分享

目录 1、简述MyISAM和InnoDB的区别 2、简述Hash和B树索引的区别 3、简述MyBatis的实现逻辑 4、#{}和${}的区别 5、简述Mybatis的优缺点 6、当实体类中的属性名和表中的字段名不一样时怎么办&#xff1f; 7、resultType与resultMap的区别 8、如何执行批量插入 9、Mybat…

Unity自己实现的中英文的切换(简单好抄)

关键技术&#xff08;读取文件的方法&#xff0c;Split()分割字符串&#xff09; 1.搭建一个这样的场景&#xff0c;场景中有3个文本&#xff08;用新版的&#xff09;&#xff0c;一个空对象&#xff0c;一个按钮 2.编写翻译文本&#xff08;编写一个txt文本&#xff0c;在文…

jq命令简易教程——Linux中处理JSON数据的利器

在shell脚本中&#xff0c;当我们需要对JSON数据&#xff08;例如ceph、kubernetes等一些命令的输出&#xff0c;或是调用API获得的响应&#xff09;进行处理和提取时&#xff0c;如果使用传统的文本三剑客sed、awk和grep&#xff0c;命令将会非常臃肿不可读。虽然这三个命令在…

腾讯云视频点播配置说明 | Modstart

开通云点播 开通云点播 云点播VOD_音视频点播_直播回看_音视频上传、存储转码AI处理方案-腾讯云 获取腾讯云 SecretId 和 SecretSecret 注册并且登录 腾讯云

14. 【Android教程】文本输入框 EditText

在上一节我们讲到了 TextView&#xff0c;它用来显示一段文本。这一节可以算作成是 TextView 的延续&#xff0c;因为从功能上 EditText 在 TextView 的基础之上多了一个输入的功能&#xff1b;从代码上 EditText 是继承自 TextView 的子类&#xff0c;所以我们可以大胆的理解为…

下载python电子书

下面展示一些 内联代码片。 import requests from lxml import etree from urllib import parse from pprint import pprint from tqdm import tqdm class PythonBook: def init(self): self.url“https://m.jb51.net/books/list476_1.html” self.url_page“https://m.jb51.n…

数字乡村发展新模式:科技创新引领农业现代化与乡村振兴协同发展

随着信息技术的飞速发展&#xff0c;数字乡村已成为新时代农业现代化与乡村振兴协同发展的新模式。科技创新作为推动这一模式的核心动力&#xff0c;正引领着乡村产业结构的优化升级&#xff0c;促进农村经济的全面振兴&#xff0c;让农民在现代化的进程中共享发展成果。 一、科…