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

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

Win安装MySQL8全过程

《Win安装MySQL8全过程》:本文主要介绍Win安装MySQL8全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Win安装mysql81、下载MySQL2、解压文件3、新建文件夹data,用于保存数据库数据文件4、在mysql根目录下新建文件my.ini

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删