valgrind¶
valgrind一款内存检测工具,包括如下模块 1. Memcheck:是一个内存错误检测器。对未初始化内存的使用;读/写释放后的内存块;读/写超出malloc分配的内存块;读/写不适当的栈中内存块;内存泄漏,指向一块内存的指针永远丢失;不正确的malloc/free或new/delete匹配;memcpy()相关函数中的dst和src指针重叠 2. Cachegrind: 是一个缓存和分支预测分析器。它可以帮助您使程序运行得更快。它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。 3. Callgrind: 是一个调用图生成缓存分析器。它与 Cachegrind 有一些重叠,但也收集了一些 Cachegrind 没有的信息。 4. Helgrind:是一个线程错误检测器。它可以帮助您使您的多线程程序更正确。锁检测。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误 5. DRD:也是一个线程错误检测器。它与 Helgrind 类似,但使用不同的分析技术,因此可能会发现不同的问题。 6. Massif:是一个堆分析器。它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小,它可以帮助您使程序使用更少的内存。 7. DHAT:是一种不同类型的堆分析器。它可以帮助您了解块生命周期、块利用率和布局效率低下的问题。 8. BBV:是一个实验性的 SimPoint 基本块向量生成器。它对从事计算机体系结构研究和开发的人很有用。
1 安装¶
- 下载源码包(https://valgrind.org/downloads/current.html),解压缩(tar –jxvf valgrind.tar.bz2)
- 根据源码目录下的README文件,源码安装,可能需要安装
automake
、autoconf
包yum install -y autoconf automake
To install from the GIT repository:
0. Clone the code from GIT:
git clone git://sourceware.org/git/valgrind.git
There are further instructions at
http://www.valgrind.org/downloads/repository.html.
1. cd into the source directory.
2. Run ./autogen.sh to setup the environment (you need the standard
autoconf tools to do so).
3. Continue with the following instructions...
To install from a tar.bz2 distribution:
4. Run ./configure, with some options if you wish. The only interesting
one is the usual --prefix=/where/you/want/it/installed.
5. Run "make".
6. Run "make install", possibly as root if the destination permissions
require that.
7. See if it works. Try "valgrind ls -l". Either this works, or it
bombs out with some complaint. In that case, please let us know
(see http://valgrind.org/support/bug_reports.html).
2 valgrind 通用命令行选项¶
- 语法:
valgrind [valgrind-options] your-prog [your-prog-options]
valgrind 输出的第一列是进程号,第2列是检测信息,如输出结果
==12345== some-message-from-Valgrind
2.1 --tool¶
- 功能:指定使用的valigrind提供的哪一种工具,
memcheck
(默认),cachegrind
,callgrind
,helgrind
,drd
,massif
,dhat
,lackey
- 格式:
--tool=<toolname> [default: memcheck]
2.2 --trace-children¶
title: 其实是跟踪exec调用的程序,而不是子进程
Note that Valgrind does trace into the child of a `fork` (it would be difficult not to, since `fork` makes an identical copy of a process), so this option is arguably badly named. However, most children of `fork` calls immediately call `exec` anyway.
- 功能:跟踪子进程(exec system call),在多进程中开启
- 格式:
--trace-children=<yes|no> [default: no]
2.3 --time-stamp¶
- 功能:每条消息前面都会显示自启动以来经过的挂钟时间,没字段分别是 days, hours, minutes, seconds and milliseconds
- 格式:
--time-stamp=<yes|no> [default: no]
- 示例:下面257是毫秒,前面的00,分别是 days, hours, minutes, seconds
[root@centos7 Valgrind]# valgrind --time-stamp=yes ./a.out
...
==00:00:00:00.000 1597== Command: ./a.out
==00:00:00:00.000 1597==
==00:00:00:00.257 1597== Invalid write of size 4
==00:00:00:00.257 1597== at 0x40054E: f() (test.cc:6)
==00:00:00:00.257 1597== by 0x40055E: main (test.cc:11)
...
2.4 --track-fds¶
- 功能:
- 格式:
2.5 --log-fd¶
- 功能:指定valgrind将所有消息发送到指定的文件描述符
- 格式:
--log-fd=<number> [default: 2, stderr]
2.6 --log-file¶
- 功能:指定valgrind将所有消息写入到指定的文件中
- 格式:
--log-file=<filename>
,其中支持以下几个格式%p
:表示进程id,通常在多进程中很有用,多个进程的消息分别写入自己的文件中%n
:被替换为此进程唯一的文件序列号。这对于从同一文件名模板生成多个文件的进程很有用。
[root@centos7 Valgrind]# valgrind --log-file=file-%p ls
[root@centos7 Valgrind]# ll file*
-rw-r--r--. 1 root root 915 Aug 7 20:12 file-2291
2.7 --log-socket¶
- 功能:将输出写入指定的socket上,如果不指定端口,默认是1500。可以通过使用valgrind-listener 来监听客户端valgrind发送过来的信息
- 格式:
--log-socket=<ip-address:port-number>
2.8 --vgdb¶
具体操作见(https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver)
- 功能:允许外部 GNU GDB 调试器在 Valgrind 上运行时控制和调试程序
- 格式:
--vgdb=<no|yes|full> [default: yes]
2.9 --main-stacksize¶
- 功能:指定主线程堆栈的大小。默认使用当前ulimit设置的值
- 格式:
--main-stacksize=<number> [default: use current 'ulimit' value]
2.10 --max-threads¶
- 功能:指定valgrind支持的最大线程数。默认是500个线程
- 格式:
--max-threads=<number> [default: 500]
2.11 memcheck内存泄漏检测¶
通过指定--tool=memcheck
(默认)来启用memcheck
- 选项
- --leak-check=<no|summary|yes|full> [default: summary]
:当设置成summary时,仅统计内存泄漏数量,yes|full会显示详细信息
- --show-leak-kinds=<set> [default: definite,possible]
:指定需要显示的内存泄漏类型
- 可选类型有:definite indirect possible reachable none all
;all相当于definite indirect possible reachable
3 valgrind-listener¶
- 功能:监听来自valgrind通过socket发送过来的信息
- 语法:
valgrind-listener [options]
-e --exit-at-zero
:当连接的进程数回落到零时,退出。没有这个,它将永远运行,也就是说,直到你发送它 ctrl+c。--max-connect=整数
:默认情况下,监听器最多可以连接 50 个进程。有时,这个数字太小了。使用此选项可提供不同的限制。例如。 --最大连接=100。portnumber
:将其侦听的端口从默认值 (1500) 更改。指定的端口必须在 1024 到 65535 的范围内。同样的限制适用于由 --log-socket 指定到 Valgrind 本身的端口号。
- 示例步骤
- 先启动一个终端,启动监听
valgrind-listener
- 在启动一个终端,启动valgrind检查,比如
valgrind --log-socket=192.168.211.7 ls
- 查看终端1是否接收到来自终端2发送的信息
- 先启动一个终端,启动监听
### 终端2,启动valgrind检查ls
[root@centos7 Valgrind]# valgrind --log-socket=192.168.211.7 ls
### 终端1,启动监听,当终端2执行命令后,终端1收到消息
[root@centos7 ~]# valgrind-listener
valgrind-listener started at Sun Aug 7 22:40:55 2022
(1) -------------------- CONNECT --------------------
(1)
(1) ==2683== Memcheck, a memory error detector
(1) ==2683== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
(1) ==2683== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
(1) ==2683== Command: ls
(1) ==2683==
(1) ==2683==
(1) ==2683== HEAP SUMMARY:
(1) ==2683== in use at exit: 19,916 bytes in 10 blocks
(1) ==2683== total heap usage: 44 allocs, 34 frees, 56,463 bytes allocated
(1) ==2683==
(1) ==2683== LEAK SUMMARY:
(1) ==2683== definitely lost: 0 bytes in 0 blocks
(1) ==2683== indirectly lost: 0 bytes in 0 blocks
(1) ==2683== possibly lost: 0 bytes in 0 blocks
(1) ==2683== still reachable: 19,916 bytes in 10 blocks
(1) ==2683== suppressed: 0 bytes in 0 blocks
(1) ==2683== Rerun with --leak-check=full to see details of leaked memory
(1) ==2683==
(1) ==2683== For lists of detected and suppressed errors, rerun with: -s
(1) ==2683== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
(1)
(0) ------------------- DISCONNECT -------------------
(0)
4 valgrind 使用注意事项¶
- 您应该在此处运行真正的(机器代码)可执行文件。例如,如果您的应用程序是由 shell 或 Perl 脚本启动的,则需要对其进行修改以在真正的可执行文件上调用 Valgrind。直接在 Valgrind 下运行此类脚本将导致您收到与 /bin/sh、/usr/bin/perl 或您正在使用的任何解释器有关的错误报告。这可能不是您想要的并且可能会造成混淆。您可以通过提供选项 --trace-children=yes 来强制解决此问题,但仍有可能造成混淆