文档章节

第一 valgrind初步学习并深入使用

卜星星
 卜星星
发布于 2015/02/12 10:09
字数 1975
阅读 556
收藏 1

开始写第一篇的时候就是想记录一下自己当时怎么用的,后来想想还是应该深入的了解一下,方便以后使用。

所以我在官网下了使用手册来看看,并且自己写程序一点一点的分析,故意出错,看会给什么相应的信息。

官网手册下载地址:http://valgrind.org/docs/download_docs.html


对了补充一下:每个信息前面都有一个数字,并且每次的都是一样的,这个是进程ID号

在补充一点:就是在使用valgrind的时候信息是输出到标准错误上的,也就是stderr,文件描述符一般就是2了,所以我们在屏幕上运行的时候,一般打印到屏幕上是很乱的,所以输出到文件中比较容易查阅,这里重定向要使用 2> 文件名,比如:

valgrind --leak-check=full ./a.out 2> record.txt

当然了,如果你蛋疼可以这么写:

valgrind --leak-check=full -v --log-fd=1 ./a.out > record.txt

--log-fd=1就是valgrind自己的内部选项,把日志重定向到相应描述符上,先定向到1就是标准输出,然后后面直接使用 >也是可以的,但是。。。。。。。。。。

当然了,还有一种办法就是直接使用文件名的:

valgrind --leak-check=full --log-file=record.txt ./a.out

这样也是输出到那个文件中了,貌似这个多进程的时候更有用,但我还不知道有什么用,看到了再补充。

终于看到是为什么了,这个多进程指定文件后,可以把不同进程的输出到相应的文件中,这样用:

valgrind --leak-check=full --log-file=record.%p ./a.out

这样就是按进程ID来输出到相应的文件中,%p就是进程ID匹配用,但是好像只能是两个进程,多个进程好像只输出

前两个了,还需要进一步使用看看,好了初步学习的记录就到这,要不然太长了。


  1. 写最简单的程序

test.cpp

#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
    return 0;
}

编译成a.out后,对了,在编译的时候,加上-g,这样在valgrind的信息中会有代码行号等信息,使用valgrind来查看:

valgrind --leak-check=full ./a.out 2> record.txt

==6977== Memcheck, a memory error detector
==6977== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==6977== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==6977== Command: ./a.out
==6977== 
==6977== 
==6977== HEAP SUMMARY:
==6977==     in use at exit: 0 bytes in 0 blocks
==6977==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==6977== 
==6977== All heap blocks were freed -- no leaks are possible
==6977== 
==6977== For counts of detected and suppressed errors, rerun with: -v
==6977== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


上面就是所有输出内容。差不多就这么多。

2. 然后用一个带有没有free或者delete泄漏的。

#include <iostream>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    return 0;
}


使用valgrind查看结果如下:

==7048== Memcheck, a memory error detector
==7048== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7048== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7048== Command: ./a.out
==7048== 
==7048== 
==7048== HEAP SUMMARY:
==7048==     in use at exit: 12 bytes in 1 blocks
==7048==   total heap usage: 1 allocs, 0 frees, 12 bytes allocated
==7048== 
==7048== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7048==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7048==    by 0x4006DC: main (test.cpp:13)
==7048== 
==7048== LEAK SUMMARY:
==7048==    definitely lost: 12 bytes in 1 blocks
==7048==    indirectly lost: 0 bytes in 0 blocks
==7048==      possibly lost: 0 bytes in 0 blocks
==7048==    still reachable: 0 bytes in 0 blocks
==7048==         suppressed: 0 bytes in 0 blocks
==7048== 
==7048== For counts of detected and suppressed errors, rerun with: -v
==7048== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)


这就有问题了,并且告诉的非常明确:

==7048== 12 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7048==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7048==    by 0x4006DC: main (test.cpp:13)

第一行是说:definitely lost (肯定丢了),这是12bytes

第二行是说:调用了new的时候

第三行是说:在调用main()函数的时候

12字节刚好是我们上面定义那个结构体的大小三个int型,12个字节

这样就找到了问题,是new了但是没有delete,然后加上delete后,再运行看结果

==7164== Memcheck, a memory error detector
==7164== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7164== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7164== Command: ./a.out
==7164== 
==7164== 
==7164== HEAP SUMMARY:
==7164==     in use at exit: 0 bytes in 0 blocks
==7164==   total heap usage: 1 allocs, 1 frees, 12 bytes allocated
==7164== 
==7164== All heap blocks were freed -- no leaks are possible
==7164== 
==7164== For counts of detected and suppressed errors, rerun with: -v
==7164== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)


又成这样了,说明解决了。这次练习到这里,之后深入学习

3. 下面用了malloc,但是没有free

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    return 0;
}


输出结果是这样的:

==7433== Memcheck, a memory error detector
==7433== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7433== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7433== Command: ./a.out
==7433== 
==7433== 
==7433== HEAP SUMMARY:
==7433==     in use at exit: 24 bytes in 2 blocks
==7433==   total heap usage: 2 allocs, 0 frees, 24 bytes allocated
==7433== 
==7433== 12 bytes in 1 blocks are definitely lost in loss record 1 of 2
==7433==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==7433==    by 0x40071C: main (test.cpp:14)
==7433== 
==7433== 12 bytes in 1 blocks are definitely lost in loss record 2 of 2
==7433==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==7433==    by 0x40072A: main (test.cpp:16)
==7433== 
==7433== LEAK SUMMARY:
==7433==    definitely lost: 24 bytes in 2 blocks
==7433==    indirectly lost: 0 bytes in 0 blocks
==7433==      possibly lost: 0 bytes in 0 blocks
==7433==    still reachable: 0 bytes in 0 blocks
==7433==         suppressed: 0 bytes in 0 blocks
==7433== 
==7433== For counts of detected and suppressed errors, rerun with: -v
==7433== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6)

这里就有两个definitely了,这是那个new和malloc都没有释放的原因,最后一句也告诉我们,有两处错误

LEAK SUMMARY:告诉我们,有两个blocks泄漏,共24字节

ERROR SUMMARY:告诉我们,有两处内存肯定泄漏的错误

4. 然后我们进去内存越界访问,先用malloc分配的数组尝试,分配了10个int大小,但是却访问之后的一个int:

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    int *parray = (int *)malloc(10 * sizeof(int));
    parray[10] = 1;
    delete x;
    free(p);
    free(parray);
    return 0;
}

这样会有相应的提示信息告诉我们错误:

==7649== Memcheck, a memory error detector
==7649== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7649== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7649== Command: ./a.out
==7649== 
==7649== Invalid write of size 4
==7649==    at 0x4007D5: main (test.cpp:19)
==7649==  Address 0x4c29108 is 0 bytes after a block of size 40 alloc'd
==7649==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==7649==    by 0x4007C8: main (test.cpp:18)
==7649== 
==7649== 
==7649== HEAP SUMMARY:
==7649==     in use at exit: 0 bytes in 0 blocks
==7649==   total heap usage: 3 allocs, 3 frees, 64 bytes allocated
==7649== 
==7649== All heap blocks were freed -- no leaks are possible
==7649== 
==7649== For counts of detected and suppressed errors, rerun with: -v
==7649== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 6)

错误信息是这样的:Invalid write of size 4

并且告诉我们在main.c的第19行,就是这里我们越界了。

5. 下面我们不用malloc分配,直接在栈上分配,看看越界会不会有提示:

#include <iostream>
#include <cstdlib>
using namespace std;
struct xx {
    int a;
    int b;
    int c;
};
int main(int argc, char *argv[])
{
    xx *x = new xx;
    xx *p = (xx *)malloc(sizeof(xx));
    int *parray = (int *)malloc(10 * sizeof(int));
    parray[9] = 1;
    delete x;
    free(p);
    free(parray);
    int array[10];
    array[10] = 1;
    return 0;
}


下面是提示信息:

==7765== Memcheck, a memory error detector
==7765== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==7765== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==7765== Command: ./a.out
==7765== 
==7765== 
==7765== HEAP SUMMARY:
==7765==     in use at exit: 0 bytes in 0 blocks
==7765==   total heap usage: 3 allocs, 3 frees, 64 bytes allocated
==7765== 
==7765== All heap blocks were freed -- no leaks are possible
==7765== 
==7765== For counts of detected and suppressed errors, rerun with: -v
==7765== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)

看,这里是没有错误的,所以这种是不提示的,只是分析heap也就是堆上的内存问题的。











© 著作权归作者所有

共有 人打赏支持
卜星星
粉丝 27
博文 111
码字总数 68736
作品 0
海淀
程序员
私信 提问
Valgrind 3.12.0 发布,应用运行时诊断工具

Valgrind 3.12.0 发布,这是一个功能版本,有大量的改进和修复。 Valgrind 是一个运行时诊断工具,它可以监视 一个指定程序的活动并通知你在你的代码中可能存在的各种各样的内存管理问题。它...

王练
2016/10/26
1K
3
利用Valgrind和gperftools解决内存问题

近期,在对于系统进行性能测试,暴露一些问题。在定位过程中尝试使用一些工具,有效的帮助识别问题,并且解决了问题。由于问题比较典型,分享给大家,以便大家遇到类似问题时,借鉴参考。 工...

通爸
2017/12/28
0
0
RAC/MVVM个人学习资源汇总

RAC和MVVM可以说是最近比较热门的话题,本着对新技术的好奇心,我也是东看看西看看了一个月,也算是初步入门了一下,于是便准备在这里向新新手推荐一些个人学习时所看过的博客以及demo。 个人...

04zhujunjie
2015/11/02
0
1
记录一场没有胜利的局部战斗

14 May 15 记录一场没有胜利的局部战斗 本文地址: http://www.laruence.com/2015/05/14/3021.html 转载文章 这个问题, 早在1年前就遇到了, 当时因为没有在意一直没有跟进. 最近团队来了个新人...

Laruence
2017/09/12
0
0
Head First C学习日志 第六章 最高机密 二叉树和valgrind工具

程序会从根节点开始提问,其左右子树为疑犯名字或另外一个问题。先看数据结构: typedef struct node {char *question;struct node *no;struct node *yes;} node; 一个递归结构,内容很简单,...

AlexTuan
2016/02/23
53
0

没有更多内容

加载失败,请刷新页面

加载更多

BigDecimal 比较大小

通过BigDecimal的compareTo方法来进行比较。 返回的结果是int类型: -1表示小于,0是等于,1是大于

嘴角轻扬30
14分钟前
2
0
PHP实现excel导出

1:前端代码 <div id=‘export’>导出excel表单</div> // //导入excel文件 $("#export").on('click', function(){ $.ajax({ url:"importexcel.php", type:'POST', dataType:'json', data:{}......

葬-花
16分钟前
2
0
内存性能的正确解读

一台服务器,不管是物理机还是虚拟机,必不可少的就是内存,内存的性能又是如何来衡量呢。 1. 内存与缓存 现在比较新的CPU一般都有三级缓存,L1 Cache(32KB-256KB),L2 Cache(128KB-2MB)...

阿里云官方博客
18分钟前
2
0
《边缘云计算技术及标准化白皮书》

12月12日,第八届中国云计算标准和应用大会在北京隆重召开,工业和信息化部党组成员,总工程师张峰先生,中国工程院副院长陈左宁女士,中国工程院院士沈昌祥先生,中国电子技术标准化研究院院...

阿里云云栖社区
18分钟前
2
0
iOS 官方文档

https://developer.apple.com/library/prerelease/content/navigation/#section=Platforms&topic=iOS...

walking_yxf
32分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部