文档章节

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

卜星星
 卜星星
发布于 2015/02/12 10:09
字数 1975
阅读 550
收藏 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
968
3
利用Valgrind和gperftools解决内存问题

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

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

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

04zhujunjie
2015/11/02
0
1
Head First C学习日志 第六章 最高机密 二叉树和valgrind工具

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

AlexTuan
2016/02/23
53
0
记录一场没有胜利的局部战斗

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

Laruence
2017/09/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
16
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
16
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
23
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
14
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部