Linux下Valgrind的使用概述 来源:Linux社区 作者:dndxhej
本地使用情况,在Ubantu系统上编写的测试性能:
1,下载:sudo apt-get install valgrind;
2,验证是否安装成功:试着valgrind ls -l来检测是否正常工作;
具体看原文的介绍和使用:
Valgrind简介:
Valgrind是动态分析工具的框架。有很多Valgrind工具可以自动的检测许多内存管理和多进程/线程的bugs,在细节上剖析你的程序。你也可以利用Valgrind框架来实现自己的工具。
Valgrind通常包括6个工具:一个内存错误侦测工具,两个线程错误侦测工具,cache和分支预测的分析工具,堆的分析工具。
Valgrind的使用与CPU OS以及编译器和C库都有关系。目前支持下面的平台:
- x86/Linux
- AMD64/Linux
- PPC32/Linux
- PPC64/Linux
- ARM/Linux
- x86/MacOSX
- AMD64/MacOSX
Valgrind是GNU v2下的开源软件,你可以从http://valgrind.org下载最新的源代码。
Valgrind的安装:
1.从http://valgrind.org下载最新的valgrind-3.7.0.tar.bz2d,用tar -xfvalgrind-3.7.0.tar.bz2解压安装包。
2.执行./configure,检查安装要求的配置。
3.执行make。
4.执行make install,最好是用root权限。
5.试着valgrind ls -l来检测是否正常工作。
Valgrind的概述:
Valgrind时建立动态分析工具的框架。它有一系列用于调试分析的工具。Valgrind的架构是组件化的,所以可以方便的添加新的工具而不影响当前的结构。
下面的工具是安装时的标准配置:
Memcheck:用于检测内存错误。它帮助c和c++的程序更正确。
Cachegrind:用于分析cache和分支预测。它帮助程序执行得更快。
Callgrind:用于函数调用的分析。
Helgrind:用于分析多线程。
DRD:也用于分析多线程。与Helgrind类似,但是用不同的分析技术,所以可以检测不同的问题。
Massif:用于分析堆。它帮助程序精简内存的使用。
SGcheck:检测栈和全局数组溢出的实验性工具,它和Memcheck互补使用。
Valgrind的使用:
1.准备好程序:
编译程序时用-g,这样编译后的文件包含调试信息,那Memcheck的分析信息中就包含正确的行号。最好使用-O0的优化等级,使用-O2及以上的优化等级使用时可能会有问题。
2.在Memcheck下运行程序:
如果你的程序执行如下:
myprog arg1 arg2
那么使用如下:
valgrind --leak-check=yes myprog arg1 arg2
Memcheck是默认的工具。--leak-check打开内存泄漏检测的细节。
在上面的命令中运行程序会使得程序运行很慢,而且占用大量的内存。Memcheck会显示内存错误和检测到的内存泄漏。
3.如何查看Memcheck的输出:
这里有一个实例c代码(a.c),有一个内存错误和一个内存泄漏。
#include <stdlib.h>
void f(void)
{
int*x = (int *)malloc(10 * sizeof(int));
x[10]= 0;
//problem 1: heap block overrun
} //problem 2: memory leak -- x not freed
int main(void)
{
f();
return0;
}
运行如下:
www.linuxidc.com @linuxidc:~/NFS/valg/test$ valgrind--leak-check=yes ./a
==24780== Memcheck, a memory error detector
==24780== Copyright (C) 2002-2011, and GNUGPL'd, by Julian Seward et al.
==24780== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info
==24780== Command: ./a
==24780==
==24780== Invalid write of size 4
==24780== at 0x80484DF: f() (a.c:5)
==24780== by 0x80484F1: main (a.c:11)
==24780== Address 0x42d3050 is 0 bytes after a block of size 40 alloc'd
==24780== at 0x4026444: malloc (vg_replace_malloc.c:263)
==24780== by 0x80484D5: f() (a.c:4)
==24780== by 0x80484F1: main (a.c:11)
==24780==
==24780==
==24780== HEAP SUMMARY:
==24780== in use at exit: 40 bytes in 1 blocks
==24780== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==24780==
==24780== 40 bytes in 1 blocks aredefinitely lost in loss record 1 of 1
==24780== at 0x4026444: malloc (vg_replace_malloc.c:263)
==24780== by 0x80484D5: f() (a.c:4)
==24780== by 0x80484F1: main (a.c:11)
==24780==
==24780== LEAK SUMMARY:
==24780== definitely lost: 40 bytes in 1 blocks
==24780== indirectly lost: 0 bytes in 0 blocks
==24780== possibly lost: 0 bytes in 0 blocks
==24780== still reachable: 0 bytes in 0 blocks
==24780== suppressed: 0 bytes in 0 blocks
==24780==
==24780== For counts of detected andsuppressed errors, rerun with: -v
==24780== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 17 from 6)
如何来阅读这个输出结果:
==24780== Memcheck, a memory error detector
==24780== Copyright (C) 2002-2011, and GNUGPL'd, by Julian Seward et al.
==24780== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info
==24780== Command: ./a
这一部分是显示使用的工具以及版本信息。其中24780是Process ID。
==24780== Invalid write of size 4
==24780== at 0x80484DF: f() (a.c:5)
==24780== by 0x80484F1: main (a.c:11)
==24780== Address 0x42d3050 is 0 bytes after a block of size 40 alloc'd
==24780== at 0x4026444: malloc (vg_replace_malloc.c:263)
==24780== by 0x80484D5: f() (a.c:4)
==24780== by 0x80484F1: main (a.c:11)
这部分指出了错误:Invalid write。后面的几行显示了函数堆栈。
==24780== HEAP SUMMARY:
==24780== in use at exit: 40 bytes in 1 blocks
==24780== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==24780==
==24780== 40 bytes in 1 blocks aredefinitely lost in loss record 1 of 1
==24780== at 0x4026444: malloc (vg_replace_malloc.c:263)
==24780== by 0x80484D5: f() (a.c:4)
==24780== by 0x80484F1: main (a.c:11)
==24780==
==24780== LEAK SUMMARY:
==24780== definitely lost: 40 bytes in 1 blocks
==24780== indirectly lost: 0 bytes in 0 blocks
==24780== possibly lost: 0 bytes in 0 blocks
==24780== still reachable: 0 bytes in 0 blocks
==24780== suppressed: 0 bytes in 0 blocks
这部分是对堆和泄漏的总结,可以看出内存泄漏的错误。
==24780== For counts of detected andsuppressed errors, rerun with: -v
==24780== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 17 from 6)
这部分是堆所有检测到的错误的总结。代码中的两个错误都检测到了。
Helgrind:线程错误检测工具
若使用这个工具,在Valgrind的命令中添加--tool=helgrind。
Helgrind用于c,c++下使用POSIXpthreads的程序的线程同步错误。
Helgrind可以检测下面三类错误:
1.POSIX pthreads API的错误使用
2.由加锁和解锁顺序引起的潜在的死锁
3.数据竞态--在没有锁或者同步机制下访问内存
以数据竞态为例来说明Helgrind的用法:
在不使用合适的锁或者其他同步机制来保证单线程访问时,两个或者多个线程访问同一块内存就可能引发数据竞态。
一个简单的数据竞态的例子:
#include <pthread.h>
int var = 0;
void* child_fn ( void* arg ) {
var++;/* Unprotected relative to parent */ /* this is line 6 */
returnNULL;
}
int main ( void ) {
pthread_tchild;
pthread_create(&child,NULL, child_fn, NULL);
var++;/* Unprotected relative to child */ /* this is line 13 */
pthread_join(child,NULL);
return0;
}
运行如下:
www.linuxidc.com @linuxidc:~/NFS/valg/test$ valgrind--tool=helgrind ./b
==25449== Helgrind, a thread error detector
==25449== Copyright (C) 2007-2011, and GNUGPL'd, by OpenWorks LLP et al.
==25449== Using Valgrind-3.7.0 and LibVEX;rerun with -h for copyright info
==25449== Command: ./b
==25449==
==25449==---Thread-Announcement------------------------------------------
==25449==
==25449== Thread #1 is the program's rootthread
==25449==
==25449== ---Thread-Announcement------------------------------------------
==25449==
==25449== Thread #2 was created
==25449== at 0x4123A38: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)
==25449== by 0x40430EA: pthread_create@@GLIBC_2.1 (in /lib/tls/i686/cmov/libpthread-2.11.1.so)
==25449== by 0x402A9AD: pthread_create_WRK (hg_intercepts.c:255)
==25449== by 0x402AA85: pthread_create@* (hg_intercepts.c:286)
==25449== by 0x80484E1: main (b.c:11)
==25449==
==25449==----------------------------------------------------------------
==25449==
==25449== Possible data race during read ofsize 4 at 0x804A020 by thread #1
==25449== Locks held: none
==25449== at 0x80484E2: main (b.c:12)
==25449==
==25449== This conflicts with a previouswrite of size 4 by thread #2
==25449== Locks held: none
==25449== at 0x80484A7: child_fn (b.c:6)
==25449== by 0x402AB04: mythread_wrapper (hg_intercepts.c:219)
==25449== by 0x404296D: start_thread (in /lib/tls/i686/cmov/libpthread-2.11.1.so)
==25449== by 0x4123A4D: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)
==25449==
==25449==----------------------------------------------------------------
==25449==
==25449== Possible data race during writeof size 4 at 0x804A020 by thread #1
==25449== Locks held: none
==25449== at 0x80484E2: main (b.c:12)
==25449==
==25449== This conflicts with a previouswrite of size 4 by thread #2
==25449== Locks held: none
==25449== at 0x80484A7: child_fn (b.c:6)
==25449== by 0x402AB04: mythread_wrapper (hg_intercepts.c:219)
==25449== by 0x404296D: start_thread (in /lib/tls/i686/cmov/libpthread-2.11.1.so)
==25449== by 0x4123A4D: clone (in /lib/tls/i686/cmov/libc-2.11.1.so)
==25449==
==25449==
==25449== For counts of detected andsuppressed errors, rerun with: -v
==25449== Use --history-level=approx or=none to gain increased speed, at
==25449== the cost of reduced accuracy ofconflicting-access information
==25449== ERROR SUMMARY: 2 errors from 2contexts (suppressed: 0 from 0)
错误信息从“Possible data race during write of size 4 at 0x804A020 by thread #1
”开始,这条信息你可以看到竞态访问的地址和大小,还有调用的堆栈信息。
第二条调用堆栈从“This conflicts with a previous write of size 4 by thread #2
”开始,这表明这里与第一个调用堆栈有竞态。
一旦你找到两个调用堆栈,如何找到竞态的根源:
首先通过每个调用堆栈检查代码,它们都会显示对同一个位置或者变量的访问。
现在考虑如何改正来使得多线程访问安全:
1.使用锁或者其他的同步机制,保证同一时间只有独立的访问。
2.使用条件变量等方法,确定多次访问的次序。
本文介绍了valgrind的体系结构,并重点介绍了其应用最广泛的工具:memcheck和helgrind。阐述了memcheck和helgrind的基本使用方法。在项目中尽早的发现内存问题和多进程同步问题,能够极大地提高开发效率,valgrind就是能够帮助你实现这一目标的出色工具。
Linux下Valgrind的使用概述 来源:Linux社区 作者:dndxhej的更多相关文章
- linux下valgrind的使用概述
Valgrind简介: Valgrind是动态分析工具的框架.有很多Valgrind工具可以自动的检测许多内存管理和多进程/线程的bugs,在细节上剖析你的程序.你也可以利用Valgrind框架来实现 ...
- Linux下c语言环境概述
Linux下C语言环境概述 主要涉及编辑器.编译链接器.调试器.项目管理工具 编辑器 Linux中常用的编辑器有vi和emacs 查看vim配置文件并编辑 编译链接器 在Linux中,最常用的编译器是 ...
- linux下sort命令使用详解---linux将文本文件内容加以排序命令
转载自:http://www.cnblogs.com/hitwtx/archive/2011/12/03/2274592.html linux下sort命令使用详解---linux将文本文件内容加以排 ...
- Linux下不借助工具实现远程linux服务器上传下载文件
# Linux下不借助工具实现远程linux服务器上传下载文件 ## 简介 - Linux下自带ssh工具,可以实现远程Linux服务器的功能- Linux下自带scp工具,可以实现文件传输功能 ## ...
- linux下鼠标穿透和取消穿透--linux小白,大神无视
最近在用qt写一个跨平台的软件,因为设置了无边框,并且我自己给程序窗口加了阴影,阴影范围又比较大 所以必须给阴影区域加上鼠标穿透才能有更好的体验. 上网查了一下,在windows下使用SetWindo ...
- .netcore在linux下使用P/invoke方式调用linux动态库
http://www.mamicode.com/info-detail-2358309.html .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...
- linux下的时间管理概述
2017/6/21 时间这一概念在生活中至关重要,而在操作系统中也同样重要,其在系统中的功能绝不仅仅是给用户提供时间这么简单,内核的许多机制都依赖于时间子系统.但凡是要在某个精确的时间执行某个事件,必 ...
- Linux 下Valgrind 使用
Valgrind包括如下一些工具: Memcheck.这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内 ...
- linux下patch命令使用详解---linux打补丁命令
http://blog.csdn.net/pashanhu6402/article/details/51849354 语 法:patch [-bceEflnNRstTuvZ][-B <备份字首字 ...
随机推荐
- 深挖android low memory killer
对于PC来说,内存是至关重要.如果某个程序发生了内存泄漏,那么一般情况下系统就会将其进程Kill掉.Linux中使用一种名称为OOM(Out Of Memory,内存不足)的机制来完成这个任务,该机制 ...
- java log4j日志配置
1.首先看pom.xml文件,需要以下配置 <dependency> <groupId>log4j</groupId> <artifactId>log4 ...
- 十个 Laravel 5 程序优化技巧
性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践,还有调优技巧,大家有别的建议也欢迎留言讨论. 这里是简单的列表: 配 ...
- word2013怎样批量重设图片和大小?(转)
https://www.zhihu.com/question/52908434/answer/132934213 点击视图,宏,查看宏,任意输入一个宏名,创建,清空框内内容,复制以下代码粘贴,保存. ...
- 使用 Edit + MASM 5.0 编译器 + Linker 连接器
其实这种方式是很简单的,只是很麻烦,因为简单而且麻烦, 所以我采用尽可能的将截图传上来,然后稍加注解的方式进行介绍, 软件准备: 需要 MASM 5.0 或者以上的汇编编译器 首先,是要编辑汇编源代码 ...
- 关闭Pycharm拼写检查
转载: https://blog.csdn.net/u013088062/article/details/50001189 Pycharm作为一款优秀的PythonIDE,唯一让我觉得不安的就是它的拼 ...
- android中RecyclerView控件的使用
1.RecyclerView控件不在标准的库里面,需要先引入,引入比较简单,点击控件右边的下载按钮即可 2.先添加一个新闻实体类,用来为新闻列表提供数据,news.java: package com. ...
- Unity3d -> Xcode 多个渠道版本发布文件合并
第一步: Users/xxx/.jenkins/jobs/projectname/workspace/build/iOS_iphone 把这里面所有文件拷贝到生成的xcode 工程下的Data目录 如 ...
- LintCode: Number of Airplanes in the Sky
C++ (1)把interval数组中的所有start和所有end放在同一个数组中,然后进行排序,遇到start就起飞一架飞机,遇到一架end就降落一架飞机,所以start有个+1属性,end有个-1 ...
- 将/home空间从新挂载到/var/lib/docker
[lxl@node1 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 49G 34G 15G ...