Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析。你可以在它的环境中运行你的程序来监视内存的使用情况,比如C 语言中的malloc和free或者 C++中的new和 delete。使用Valgrind的工具包,你可以自动的检测许多内存管理和线程的bug,避免花费太多的时间在bug寻找上,使得你的程序更加稳固。

  Valgrind的主要功能
  Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。下面分别介绍个工具的作用:

Memcheck 工具主要检查下面的程序错误:

  1.使用未初始化的内存 (Use of uninitialised memory)
  2.使用已经释放了的内存 (Reading/writing memory after it has been free’d)
  3.使用超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)
  4.对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)
  5.申请的空间是否有释放 (Memory leaks – where pointers to malloc’d blocks are lost forever)
  6.malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
  7.src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)
Callgrind
  Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache 模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。

Cachegrind
它模拟 CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中 cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。

Helgrind
  它主要用来检查多线程程序中出现的竞争问题。Helgrind 寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为” Eraser” 的竞争检测算法,并做了进一步改进,减少了报告错误的次数。

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

Ubuntu 安装valgrind:

#> sudo apt-get install valgrind

valgrind 使用:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> int main()
{ char *ptr = (char *)malloc(); ptr[] = ; // memcpy(ptr+, ptr, ); char ch = ptr[]; free(ptr);
free(ptr); char *ptr1;
*ptr1 = 'a'; char *ptr2 = (char *)malloc(); return ;
}

#> valgrind --tool=memcheck --leak-check=yes ./valgTest

  注意在编译程序的时候加上-g选项,打印错误信息的时候会给出行号。上面的执行结果给出了六个错误。

  下面看一个多线程竞争的情况:

#include <pthread.h>
#include <stdio.h> int a = ; void* child_fn (void* arg)
{
a++;
return NULL;
} int main ()
{
pthread_t child;
pthread_create(&child,NULL, child_fn, NULL);
a++;
pthread_join(child,NULL);
return ;
}

zhuyp@ubuntu:~/valgrind$ valgrind --tool=helgrind ./helTest
==5639== Helgrind, a thread error detector
==5639== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.
==5639== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==5639== Command: ./helTest
==5639==
==5639== ---Thread-Announcement------------------------------------------
==5639==
==5639== Thread #1 is the program's root thread
==5639==
==5639== ---Thread-Announcement------------------------------------------
==5639==
==5639== Thread #2 was created
==5639== at 0x51562CE: clone (clone.S:74)
==5639== by 0x4E44199: do_clone.constprop.3 (createthread.c:75)
==5639== by 0x4E458BA: pthread_create@@GLIBC_2.2.5 (createthread.c:245)
==5639== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5639== by 0x40068D: main (helTest.c:15)
==5639==
==5639== ----------------------------------------------------------------
==5639==
==5639== Possible data race during read of size 4 at 0x60104C by thread #1
==5639== Locks held: none
==5639== at 0x40068E: main (helTest.c:16)
==5639==
==5639== This conflicts with a previous write of size 4 by thread #2
==5639== Locks held: none
==5639== at 0x40065E: child_fn (helTest.c:8)
==5639== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5639== by 0x4E45181: start_thread (pthread_create.c:312)
==5639== by 0x515630C: clone (clone.S:111)
==5639==
==5639== ----------------------------------------------------------------
==5639==
==5639== Possible data race during write of size 4 at 0x60104C by thread #1
==5639== Locks held: none
==5639== at 0x400697: main (helTest.c:16)
==5639==
==5639== This conflicts with a previous write of size 4 by thread #2
==5639== Locks held: none
==5639== at 0x40065E: child_fn (helTest.c:8)
==5639== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5639== by 0x4E45181: start_thread (pthread_create.c:312)
==5639== by 0x515630C: clone (clone.S:111)
==5639==
==5639==
==5639== For counts of detected and suppressed errors, rerun with: -v
==5639== Use --history-level=approx or =none to gain increased speed, at
==5639== the cost of reduced accuracy of conflicting-access information
==5639== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

前面写过一个使用coredump调试死锁的方法,这里使用valgrind 的 helgrind 工具也可以检查出死锁问题。

#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std; mutex m1,m2; void func_2()
{
m2.lock();
cout<< "about to dead_lock"<<endl;
m1.lock(); } void func_1()
{
m1.lock(); chrono::milliseconds dura( );// delay to trigger dead_lock
this_thread::sleep_for( dura ); m2.lock(); } int main()
{ thread t1(func_1); thread t2(func_2); t1.join();
t2.join();
return ; }

zhuyp@ubuntu:~/valgrind$ g++ -Wall dead_lock_demo.cpp -o dead_lock_demo -g -std=c++11 -lpthread
zhuyp@ubuntu:~/valgrind$ valgrind --tool=helgrind ./dead_lock_demo
==5646== Helgrind, a thread error detector
==5646== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.
==5646== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==5646== Command: ./dead_lock_demo
==5646==
about to dead_lock  // 执行到这里,Ctrl + C 结束进程,则打印出如下信息
^C==5646== ---Thread-Announcement------------------------------------------ 
==5646==
==5646== Thread #2 was created
==5646== at 0x56702CE: clone (clone.S:74)
==5646== by 0x4E44199: do_clone.constprop.3 (createthread.c:75)
==5646== by 0x4E458BA: pthread_create@@GLIBC_2.2.5 (createthread.c:245)
==5646== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646== by 0x510CE3E: std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==5646== by 0x401789: std::thread::thread<void (&)()>(void (&)()) (thread:135)
==5646== by 0x40112D: main (dead_lock_demo.cpp:33)
==5646==
==5646== ----------------------------------------------------------------
==5646==
==5646== Thread #2: Exiting thread still holds 1 lock
==5646== at 0x4E4BF2C: __lll_lock_wait (lowlevellock.S:135)
==5646== by 0x4E47656: _L_lock_909 (pthread_mutex_lock.c:151)
==5646== by 0x4E4747E: pthread_mutex_lock (pthread_mutex_lock.c:79)
==5646== by 0x4C32072: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646== by 0x40101B: __gthread_mutex_lock(pthread_mutex_t*) (gthr-default.h:748)
==5646== by 0x401421: std::mutex::lock() (mutex:134)
==5646== by 0x401111: func_1() (dead_lock_demo.cpp:25)
==5646== by 0x40278C: void std::_Bind_simple<void (*())()>::_M_invoke<>(std::_Index_tuple<>) (functional:1732)
==5646== by 0x4026E6: std::_Bind_simple<void (*())()>::operator()() (functional:1720)
==5646== by 0x40267F: std::thread::_Impl<std::_Bind_simple<void (*())()> >::_M_run() (thread:115)
==5646== by 0x510CBEF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==5646== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646==
==5646== ---Thread-Announcement------------------------------------------
==5646==
==5646== Thread #3 was created
==5646== at 0x56702CE: clone (clone.S:74)
==5646== by 0x4E44199: do_clone.constprop.3 (createthread.c:75)
==5646== by 0x4E458BA: pthread_create@@GLIBC_2.2.5 (createthread.c:245)
==5646== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646== by 0x510CE3E: std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==5646== by 0x401789: std::thread::thread<void (&)()>(void (&)()) (thread:135)
==5646== by 0x40113E: main (dead_lock_demo.cpp:35)
==5646==
==5646== ----------------------------------------------------------------
==5646==
==5646== Thread #3: Exiting thread still holds 1 lock
==5646== at 0x4E4BF2C: __lll_lock_wait (lowlevellock.S:135)
==5646== by 0x4E47656: _L_lock_909 (pthread_mutex_lock.c:151)
==5646== by 0x4E4747E: pthread_mutex_lock (pthread_mutex_lock.c:79)
==5646== by 0x4C32072: pthread_mutex_lock (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646== by 0x40101B: __gthread_mutex_lock(pthread_mutex_t*) (gthr-default.h:748)
==5646== by 0x401421: std::mutex::lock() (mutex:134)
==5646== by 0x4010DF: func_2() (dead_lock_demo.cpp:14)
==5646== by 0x40278C: void std::_Bind_simple<void (*())()>::_M_invoke<>(std::_Index_tuple<>) (functional:1732)
==5646== by 0x4026E6: std::_Bind_simple<void (*())()>::operator()() (functional:1720)
==5646== by 0x40267F: std::thread::_Impl<std::_Bind_simple<void (*())()> >::_M_run() (thread:115)
==5646== by 0x510CBEF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19)
==5646== by 0x4C30E26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==5646==
==5646==
==5646== For counts of detected and suppressed errors, rerun with: -v
==5646== Use --history-level=approx or =none to gain increased speed, at
==5646== the cost of reduced accuracy of conflicting-access information
==5646== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)

吐槽一下,刚刚在Linux操作并编辑该博文,各种不适应啊,还是换到Windows下来编辑要方便些。。。

ubuntu 上使用valgrind的更多相关文章

  1. Ubuntu上交叉编译valgrind for Android 4.0.4的过程与注意事项

    编译环境:Ubuntu x86_64(Linux root 2.6.32-45-generic #101-Ubuntu SMP Mon Dec 3 15:39:38 UTC 2012 x86_64 G ...

  2. 【转】在Ubuntu上下载、编译和安装Android最新源代码

    原文网址:http://blog.csdn.net/luoshengyang/article/details/6559955 看完了前面说的几本书之后,对Linux Kernel和Android有一定 ...

  3. 在Ubuntu上下载、编译和安装Android最新源码

    看完了前面说的几本书之后,对Linux Kernel和Android有一定的认识了,是不是心里蠢蠢欲动,想小试牛刀自己编译一把Android源码了呢?一直习惯使用Windows系统,而Android源 ...

  4. 在Ubuntu上下载、编译和安装Android最新源代码

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6559955 看完了前面说的几本书之后,对Lin ...

  5. .NET跨平台:在Ubuntu上用自己编译的dnx运行ASP.NET 5示例程序

    在 Linux Ubuntu 上成功编译 dnx 之后,会在 artifacts/build/ 文件夹中生成 dnx-coreclr-linux-x64/ 与 dnx-mono/ 这2个文件夹,前者是 ...

  6. Ubuntu 上搭建 Samba 服务器

    由于经常要接收同事发送的一些文件,U盘拷来拷去的很麻烦. 在本机Ubuntu上搭了各Samba服务器,过程中遇到点小问题,记录一下 sudo apt-get install samba 创建一个共享目 ...

  7. 微软KinectV2深度传感器在Ubuntu上的配置和使用

    最新博客地址已转到: http://blog.csdn.net/zzlyw?viewmode=contents   ------------------------------------------ ...

  8. .NET跨平台:在Linux Ubuntu上编译coreclr/corefx/dnx(20150617)

    编译时间:北京2015年6月17日上午 操作系统:Ubuntu 14.04.2 LTS Mono版本:Mono JIT compiler version 4.3.0 (master/3445ac5 T ...

  9. [异常解决] ubuntu上安装JLink驱动遇到的坑及给后来者的建议

    一.前言 最近将整个电脑格式化,改成了linux操作系统 希望这样能让自己在一个新的世界探索技术.提升自己吧- win上的工具用多了,就不想变化了- 继上一篇<ubuntu上安装虚拟机遇到的问题 ...

随机推荐

  1. 【linux】linux查看资源任务管理器,使用top命令 + 查看java进程下的线程数量【两种方式】

    ================================ 详解:https://blog.csdn.net/achenyuan/article/details/77867661 ======= ...

  2. Unity5.x shader打包AssetBundle总结

    最近比较忙,好久没有更新博客了,新项目切换到unity5.x后使用了新的打包机制,在打包shader的时候遇到了一些问题,这里来记录一下吧. 在上一个项目中,我们使用unity4.7,对于shader ...

  3. [Web 前端] 你不知道的 React Router 4

    cp from https://segmentfault.com/a/1190000010718620 几个月前,React Router 4 发布,我能清晰地感觉到来自 Twitter 大家对新版本 ...

  4. 从阿里Java开发手册学习线程池的正确创建方法

    前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更 ...

  5. nodejs中thiskeyword的问题

    再分析详细内容之前,必需要好好阅读下面下面两篇blog 学习Javascript闭包(closure) Javascript的this使用方法 这两篇文章是阮一峰老师对Javascript的闭包和th ...

  6. WEB中会话跟踪

    一.     什么叫会话跟踪 记录用户一段时间内的逻辑上相关联的不同访问请求个过程叫“会话跟踪”.通过用户在每次对服务请求时的唯一标识,可以跟踪会话. 二.     会话跟踪产生的原因 我们都知道In ...

  7. lftp命令

    lftp 是一个功能强大的下载工具,它支持访问文件的协议: ftp, ftps, http, https, hftp, fish.(其中ftps和https需要在编译的时候包含openssl库).ll ...

  8. secureCRT在Windows上面的安装过程

    参考这篇文章: https://www.cnblogs.com/yjd_hycf_space/p/7729796.html

  9. MFC增强----任务对话框CTaskDialog类

    /** 注意:从Windows Vista系统才开始支持CTaskDialog类,所以在使用时最好调用 CTaskDialog::IsSupported() 方法做判断 同时:CTaskDialog类 ...

  10. SQL操作查漏补缺

    SQL教程地址:http://www.w3school.com.cn/sql/index.asp TOP 子句 TOP 子句用于规定要返回的记录的数目. 对于拥有数千条记录的大型表来说,TOP 子句是 ...