valgrind安装+使用【附带callgrind + dot】

2023-12-19 16:58

本文主要是介绍valgrind安装+使用【附带callgrind + dot】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.valgind 安装

1.1源码安装

获取源码:(也可点击链接下载)

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

解压

tar -jxvf valgrind-3.16.0.tar.bz2 

安装

cd valgrind-3.16.0
./configure (./configure --prefix=/home/user1/valgrind 这种方式可以指定安装目录,但是可能需要配置环境才能使用)
make
make install

1.2指令安装(推荐)

sudo apt-get install valgrind

验证是否安装成功

valgrind --help

Ps:valgrind布置valgrind本身(线程安全,内存检查)还有callgrind(函数调用关系分析等)还有其他工具。只要安装valgrind也可以使用其他工具。

1.3基本介绍

包含如下工具:

  1. memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。
  2. callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。
  3. cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。
  4. helgrind:用于检查多线程程序的竞态条件。
  5. massif:堆栈分析器,指示程序中使用了多少堆内存等信息。

2.memcheck工具

例子:

valgrind -v --log-file=valgrind0928.log --tool=memcheck --leak-check=full --show-mismatched-frees=yes ./v2xAlgo

用法:
valgrind [options]prog-and-args [options]:常用选项,适用于所有Valgrind工具。
!!!使用valgrind的时候记得把编译条件的-pg关掉!!!!!!!。
常用选项释义:

  1. -tool=最常用的选项。运行valgrind中名为toolname的工具。默认memcheck。
  2. h –help显示帮助信息。
  3. -version显示valgrind内核的版本,每个工具都有各自的版本。
  4. q –quiet安静地运行,只打印错误信息。
  5. v –verbose更详细的信息,增加错误数统计。
  6. -trace-children=no|yes跟踪子线程? [no]
  7. -track-fds=no|yes跟踪打开的文件描述?[no]
  8. -time-stamp=no|yes增加时间戳到LOG信息? [no]
  9. -log-fd=输出LOG到描述符文件 [2=stderr]
  10. -log-file=将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
  11. -log-file-exactly=输出LOG信息到 file
  12. -log-file-qualifier=取得环境变量的值来做为输出信息的文件名。 [none]
  13. -log-socket=ipaddr:port输出LOG到socket ,ipaddr:port

LOG信息输出

  1. -xml=yes将信息以xml格式输出,只有memcheck可用

  2. -num-callers= show callersin stack traces [12]

  3. -error-limit=no|yes如果太多错误,则停止显示新错误? [yes]

  4. -error-exitcode=如果发现错误则返回错误代码 [0=disable]

  5. -db-attach=no|yes当出现错误,valgrind会自动启动调试器gdb。[no]

  6. -db-command=启动调试器的命令行选项[gdb -nw %f %p]

适用于Memcheck工具的相关选项:

  1. -leak-check=no|summary|full要求对leak给出详细信息? [summary]

  2. -leak-resolution=low|med|high how much bt merging in leakcheck [low]

-show-reachable=no|yesshow reachable blocks in leak check? [no]

3.callgrind工具

例子:
valgrind --tool=callgrind --separate-threads=yes ./test
其中./test 就是我们要分析的程序。
-separate-threads=yes。这样就会为每个线程额外单独生成一个性能分析文件。
执行完毕后,就会在当前目录下生成一个进程观测文件和几个线程观测文件。
进程观测文件名为“callgrind.out.进程号”。线程观测文件名为“callgrind.out.进程号-01”,“callgrind.out.进程号-02”……。
例如:
callgrind.out.31113 callgrind.out.31113-01 callgrind.out.31113-02 callgrind.out.31113-03 …………

callgrind + dot绘图 用法:
单独查看子线程:

valgrind --tool=callgrind --separate-threads=yes ./test 

先用上述方法生成out文件。然后使用gprof2dot生成dot文件:

gprof2dot -f callgrind -s callgrind.out.7339-05 > callgrind05.dot

然后把dot文件生成图片:

dot -Tpng callgrind05.dot -o callgrind05.png 或者dot -Tsvg callgrind05.dot -o callgrind05.svg

其中-T为选择生图片的类型,有的时候png不好使会出现绘图失败的情况,建议换成svg

不单独查看子线程:

valgrind --tool=callgrind ./test 

先用上述方法生成out文件。然后使用gprof2dot生成dot文件:

gprof2dot -f callgrind -s callgrind.out.7339 > callgrind.dot

然后把dot文件生成图片:

dot -Tpng callgrind.dot -o callgrind.png 或者dot -Tsvg callgrind.dot -o callgrind.svg

4.callgrind辅助:kcachegrind 安装和使用

4.1定性分析

安装:

sudo apt-get install  kcachegrind

使用:

kcachegrind callgrind.out.7339-05

其中,callgrind.out.7339-05为通过callgrind生成的分析文件
定性分析

左侧为所有函数 及其相关信息
右侧选择call graph选项卡可以看左侧点选的函数的相关调用关系
目的:可以观测到更加精准的函数调用关系,通过gprof2dot 生成的图片是整个生命周期所调用到的函数。所以函数关系可能比较复杂。kcachegrind的callgraph可以帮忙过滤掉不必要的信息。

4.2 定量分析

定量分析
首先要介绍一下,kcache的相关按键。红框内的relative表示的是切换【该行函数的cpu周期数占比】和【该行函数的具体cpu周期数量】在定性分析时只需关注百分比即可。但是定量分析的时候具体的cpu周期数量就显得尤为重要。
那么如何阅读kcache的表格呢?
首先先要看懂表头的意思。

  • function和location分别是函数名和函数所在文件就不多赘述了。
  • 蓝框中的incl.是inclusive的简写。表示的是该函数及其内容所有函数的内容所占用的周期数。
  • 黄框中的self是exclusive的意味。即该函数中除去其他函数的内容所占用的周期数。
  • 绿框中的called是该函数在程序运行中调用的次数。

举例

  1. main()函数是主函数只运行一次,所以called=1。主函数肯定是包含程序的全部内容所以主函数incl占比无线接近百分百。但是主函数中一般包含别的函数,所以self占比往往非常低。
  2. 以粉色框为例,该函数运行1005次,总共占用43741422次。那么一次运行大概占用43523.8个cpu周期。

举例
在知道cpu周期数后,如何知道真正运行的时间呢?毕竟时间更加直观。
此处需要补充一些系统原理基本知识。
1个cpu周期=6个状态周期=12个节拍=12个震荡脉冲周期=12/震荡脉冲频率
只要能查到系统的震荡脉冲频率即可,一般机器的震荡脉冲频率有另一个叫法【cpu主频】
linux下可以通过如下指令查到

cat /proc/cpuinfo

我的cpuMhz为3192.079Mhz,那么一个cpu周期【cpu cycle/machine cycle】为3.759纳秒,如此便可以算出粉色框的函数单次运行时长为163.6微秒。与之前通过clock_gettime()函数计算得到的时间相近。
公式
t i m e = I n c l . c p u c y c l e c a l l e d ∗ 12 f r e q c p u . time= \frac{Incl._{cpu cycle}}{called}*\frac{12}{freq_{cpu}}. time=calledIncl.cpucyclefreqcpu12.

4.3kcachegrind补充

在摸索kcachegrind的过程中发现大部分都集中在看函数调用的树图,关于时间的计算和其他内容在百度或CSDN并没有过多描述,为此看了一上午,后来发现大部分内容在官网都是有描述。花费10到20分钟慢慢看一下官网,基本要找的信息全都找到了。
kcachegrind官网
工具是开源的,sourcecode和github上都可以跟踪。

5.其他工具

5.1Cachegrind

Cache分析器,它模拟CPU中的一级缓存和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
但是官网在程序优化中明确有建议程序不要过度优化,一般callgrind足够在代码效率上提供优化空间,所以cachegrind的使用概率较小,除非有明确的使用的场景。

使用方法:

valgrind –tool=cachegrind ./程序名

5.2Helgrind

它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发觉的错误。Helgrind实现了名为Eraser的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验状态。
一般在做内存泄露的时候通常是使用memcheck,memcheck就已经能够覆盖多线程工作的情况,helgrind提供的是线程竞争的检测能力,这个检测不一定代表内存会泄露,但是也会出现程序运行结果不满足预期的问题。由于helgrind还在完善中,所以不是非常推荐使用,遇到多线程结果不满足预期,但也没有内存泄露的情况下,可以考虑进行分析。报告仅供参考,还是需要技术人员进一步自行分析。
或者可以找找看有没有开发比较完善的同类型分析工具
使用方法:

valgrind --tool=helgrind ./程序名

5.3Massif【亟待补充】

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。

Massif对内存的分配和释放做profile。程序开发者通过它可以深入了解程序的内存使用行为,从而对内存使用进行优化。这个功能对C++尤其有用,因为C++有很多隐藏的内存分配和释放。
由于目前项目采用c++开发,所以在内存的分配和释放上如果希望更进一步,可以进行使用,同时也提供了一个更加便利的堆栈管理,相比于传统指令查看。
后续最好可以深入研究一下,或者可以找找看有没有开发比较完善的同类型分析工具

5.4其他

此外,lackey 和 nulgrind 也会提供。Lackey 是小型工具,很少用到;Nulgrind 只是为开发者展示如何创建一个工具。这里就不做介绍了。

这篇关于valgrind安装+使用【附带callgrind + dot】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/512978

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他