【Valgrind工具】


一. 概述

Valgrind 是一个linux下用于内存调试、内存泄漏检测和性能分析的仿真调试工具的集合。

由内核(core)以及基于内核的其他调试工具组成。

内核类似于一个框架(framework), 它模拟了一个 CPU 环境, 并提供服务给其他工具。

其他工具则类似于插件(plug-in), 利用内核提供的服务完成各种特定的内存调试任务。

Valgrind体系结构图

二. 安装步骤

1. 下载路径 http://sourceware.org/pub/valgrind/valgrind-3.22.0.tar.bz2
2. tar -xvf valgrind-3.22.0.tar.bz2 && cd valgrind-3.22.0
3. ./configure && make && make install

(注: 麒麟V10系统报错 需要单独安装glibc-debuginfo 的rpm包)

三. 常用选项

(1) --help: [显示帮助信息]

(2) --version: [显示 valgrind 版本]

(3) --tool=: [运行 valgrind 中名为 toolname 的工具,默认memcheck,还可以为cachegrid、drd、lackey、callgrind、helgrind、massif等]

(4) --quiet: [安静地运行, 只打印错误信息]

(5) --verbose: [更详细的信息,增加错误数统计]

(6) --trace-childer = no | yes: [跟踪子线程]

(7) --track-fds = no | yes: [跟踪打开的文件描述]

(8) --time-stamp = no | yes: [增加时间戳到 Log 信息]

(9) --log-fd=: [输出Log信息到文件描述符]

(10) --log-file=: [输出Log信息到指定的文件]

(11) --xml=yes: [将错误信息以xml格式输出,只有memcheck可用]

(12) --xml-file=: [XML输出到指定文件]

(13) --error-limit = no | yes: [如果错误太多,则停止显示新错误]

(14) --error-exitcode=: [如果发现错误,则返回错误代码]

(15) --leak-check = no | summary | full: [对发现的内存泄露给出的信息级别,只有memcheck可用]

(16) --show-reachable = no | yes: [用于控制是否检测控制范围之外的泄漏,比如全局指针、static指针等]

(17) –num-callers=(num): [默认值12, 最大值50, 表示显示多少层的堆栈,设置越高会使Valgrind运行越慢而且使用更多的内存]

(18) --trace-children = no | yes: [是否跟入子进程]

四. 常用工具

注意: 需要检测的程序需要时可调式版本,编译时需要加上 -g 选项 并去掉优化选项等)

1. [Memcheck]

	1.1 概述:
			用来检测程序中出现的内存问题, 所有对内存的读写都会被检测到, 
			一切对malloc()/free()/new/delete的调用都会被捕获
	
	1.2 原理:
			valgrind创建了一个映射内存空间,与程序的实际内存空间相对应。
			在这个映射内存中,Memcheck会跟踪每个字节的状态,包括是否已初始化、是否已定义、是否已分配等。
			
	1.3 相关问题:
				1) 对未初始化内存的使用
				2) 读/写释放后的内存块
				3) 读/写超出malloc分配的内存块
				4) 读/写不适当的栈中内存块
				5) 内存泄漏, 指向一块内存的指针永远丢失
				6) 不正确的malloc/free或new/delete匹配
				7)  memcpy()相关函数中的dst和src指针重叠

	1.4 使用方法: 
			valgrind  --tool=memcheck  --leak-check=full  [your_program]

2. [Massif]

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

	2.2 使用方法:
				valgrind  --tool=massif   [your_program]
				ms_print massif.out.pid

3. [Callgrind]

	3.1 概述:
				主要用于检查程序中函数调用过程中的问题。
				Callgrind 收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行 cache 模拟。
				在运行结束时,它会把分析数据写入一个文件。callgrind_annotate 可以把这个文件的内容转化成可读的形式。

	3.2 使用方法:
				valgrind --tool=callgrind  [your_program]
				callgrind_annotate  callgrind.out.pid

4. [Cachegrind]

	4.1 概述: 
				主要用于检查程序中缓存使用出现问题。
				Cache 分析器,通过模拟 CPU 中的一级缓存 I1,Dl 和二级缓存,精确地指出程序中 cache 的丢失和命中。
				如果需要,它还能够为我们提供 cache 丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。
				通过运行结果可以分析CPU的cache命中率、丢失率,用于进行代码优化。
		
	4.2 使用方法:
				valgrind --tool=cachegrind [your_program]

5.[Helgrind] 多线程竞争

	5.1 概述:
				主要用来检查多线程程序中出现的竞争问题。

	5.2 使用方法:
				valgrind --tool=helgrind [your_program]

五. 举个栗子

1. Memcheck

示例代码:

#include <stdio.h>
#include <stdlib.h>

//valgrind demo1
int main()
{
        //内存泄漏
        char *p1 = (char *)malloc(sizeof(char) * 128);

        //越界访问
        int  *p2 = (int *)malloc(sizeof(int) * 5);
        p2[5] =1;
        free(p2);

        //未初始化的内存
        char *p3;
        char ch = *p3;

        //使用已经释放的内存
        char *p4 = (char *)malloc(sizeof(char) * 8);
        free(p4);
        p4[0] = 'a';

        return 0;
}

编译: gcc mem.c -o mem -g
工具:valgrind --tool=memcheck --leak-check=full ./mem

``结果:

==9104== Memcheck, a memory error detector     //9104 表示进程号
==9104== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==9104== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info  //工具的版本号
==9104== Command: ./mem	 //进程的启动方式
==9104==
==9104== Invalid write of size 4   //非法写入四个字符,对应代码12行
==9104==    at 0x400589: main (mem.c:12)
==9104==  Address 0x520b114 is 0 bytes after a block of size 20 alloc'd
==9104==    at 0x4C2B11C: malloc (vg_replace_malloc.c:442)
==9104==    by 0x40057C: main (mem.c:11)
==9104==
==9104== Use of uninitialised value of size 8  //使用未初始化的内存,大小为8个字节,对应代码17行
==9104==    at 0x40059F: main (mem.c:17)
==9104==
==9104== Invalid write of size 1	//非法写入一个字节,对应代码22行
==9104==    at 0x4005C3: main (mem.c:22)
==9104==  Address 0x520b160 is 0 bytes inside a block of size 8 free'd
==9104==    at 0x4C2E112: free (vg_replace_malloc.c:985)
==9104==    by 0x4005BE: main (mem.c:21)
==9104==  Block was alloc'd at
==9104==    at 0x4C2B11C: malloc (vg_replace_malloc.c:442)
==9104==    by 0x4005AE: main (mem.c:20)
==9104==
==9104==
==9104== HEAP SUMMARY:
==9104==     in use at exit: 128 bytes in 1 blocks
==9104==   total heap usage: 3 allocs, 2 frees, 156 bytes allocated  //堆空间的使用情况,三次申请,两次释放
==9104==
==9104== 128 bytes in 1 blocks are definitely lost in loss record 1 of 1
==9104==    at 0x4C2B11C: malloc (vg_replace_malloc.c:442)
==9104==    by 0x40056E: main (mem.c:8)
==9104==
==9104== LEAK SUMMARY:    //内存泄漏的情况汇总
==9104==    definitely lost: 128 bytes in 1 blocks //确认丢失的内存,意思是这些内存没有被释放,且程序无法再次访问他们
==9104==    indirectly lost: 0 bytes in 0 blocks   //间接丢失的内存, 意思是直接丢失的内存块包含了指向这些内存的指针
==9104==      possibly lost: 0 bytes in 0 blocks   //可能丢失的内存,意思是这些内存可能还在使用,但可能已经丢失
==9104==    still reachable: 0 bytes in 0 blocks   //在结束时没有被释放,程序还可以再访问到的内存,但持续增长可能会出问题
==9104==         suppressed: 0 bytes in 0 blocks   //抑制的错误,意思是 valgrind 明确告知的忽略的错误
==9104==
==9104== Use --track-origins=yes to see where uninitialised values come from
==9104== For lists of detected and suppressed errors, rerun with: -s
==9104== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0) //总结:在不同的四个地方存在四个错误

2. gdbserver

相关网址:https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

The Bug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值