精华内容
下载资源
问答
  • Valgrind工具简介
    2021-07-22 11:56:18

    一 Valgrind工具集简绍
    Valgrind包含下列工具:
    1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。
    2、callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。
    3、cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。
    4、helgrind:用于检查多线程程序的竞态条件。
    5、massif:堆栈分析器,指示程序中使用了多少堆内存等信息。
    6、lackey:
    7、nulgrind:
    这几个工具的使用是通过命令:valgrand --tool=name 程序名来分别调用的,当不指定tool参数时默认是 --tool=memcheck

    二 Valgrind工具详解
    1.Memcheck
    最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc、free、new、delete的调用都会被捕获。所以,它能检测以下问题:
    1、对未初始化内存的使用;
    2、读/写释放后的内存块;
    3、读/写超出malloc分配的内存块;
    4、读/写不适当的栈中内存块;
    5、内存泄漏,指向一块内存的指针永远丢失;
    6、不正确的malloc/free或new/delete匹配;
    7、memcpy()相关函数中的dst和src指针重叠。

    使用步骤:
    valgrind --tool=memcheck ./a.out || valgrind --leak-check=full ./a.out
    查看错误信息
    valgrind --db-attach=yes --tool=memcheck ./a.out
    一出现错误,valgrind会自动启动调试器(一般是gdb)

    2.Callgrind
    和gprof类似的分析工具,但它对程序的运行观察更是入微,能给我们提供更多的信息。和gprof不同,它不需要在编译源代码时附加特殊选项,但加上调试选项是推荐的。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。
    生成可视化的图形需要下载gprof2dot:http://jrfonseca.googlecode.com/svn/trunk/gprof2dot/gprof2dot.py
    这是个python脚本,把它下载之后修改其权限chmod +7 gprof2dot.py ,并把这个脚本添加到$PATH路径中的任一文件夹下,我是将它放到了/usr/bin目录下,这样就可以直接在终端下执行gprof2dot.py了。
    Callgrind可以生成程序性能分析的图形,首先来说说程序性能分析的工具吧,通常可以使用gnu自带的gprof,它的使用方法是:在编译程序时添加-pg参数
    –inclusive=yes表示报表统计的函数的时间消耗包含其内部子函数的时间消耗,如果=no表示不包含内部其他函数的时间消耗。

    使用步骤
    1、valgrind --tool=callgrind ./a.out
    Callgrind会输出很多,而且最后在当前目录下生成一个文件: callgrind.out.pid
    如果你调试的程序是多线程,你也可以在命令行中加一个参数 -separate-threads=yes。这样就会为每个线程单独生成一个性能分析文件
    2、valgrind callgrind_annotate --inclusive=yes/no callgrind.out.pid
    查看性能分析信息

    3.Cachegrind
    Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。
    作一下广告:valgrind自身利用该工具在过去几个月内使性能提高了25%-30%。据早先报道,kde的开发team也对valgrind在提高kde性能方面的帮助表示感谢。
    它的使用方法也是:valgrind --tool=cachegrind 程序名

    使用步骤
    valgrind --tool=cachegrind ./a.out
    查看缓存信息,当前目录下生成一个文件: cachegrind.out.pid
    cg_annotate cachegrind.out.pid
    通过cg_annotate来读取,输出是一个更详细的列表

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

    5. Massif
    堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。
    Massif对内存的分配和释放做profile。程序开发者通过它可以深入了解程序的内存使用行为,从而对内存使用进行优化。这个功能对C++尤其有用,因为C++有很多隐藏的内存分配和释放。
    此外,lackey和nulgrind也会提供。Lackey是小型工具,很少用到;Nulgrind只是为开发者展示如何创建一个工具。

    Massif的使用和cachegrind类似,不过它也会生成一个名为massif.pid.ps的PostScript文件,里面只有一幅描述堆栈使用状况的彩图

    更多相关内容
  • Valgrind工具

    2018-08-10 13:49:58
    valgrind是一款及其好用的linux内存检测工具,可以用于检测内存越界、内存泄露等场景。 本份工具我已经改过configure文件,可以支持极大部分编译器,如果不能编译,可以直接qq与我联系: 979822945
  • 讲解Linux下使用valgrind工具对c/c++程序进行内存泄漏检测的方法。

    1.使用背景

      C/C++的程序员完成程序开发后,除了实现功能以外,还会是否存在内存泄漏的问题,特别是在复杂的应用程序中,肉眼review代码很难完全检查可能存在的出内存的泄漏问题,我们需要借助工具进行内存检测。

    2.Valgrind介绍

    2.1 基本概念

      Valgrind是一个Linux下灵活的调试和剖析可执行工具。它由在软件层提供综合的CPU内核,和一系列调试、剖析的工具组成。架构是模块化的,所以可以在不破坏现有的结构的基础上很容易的创建出新的工具来。

    2.2 主要工具

    Memcheck

    • 用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对malloc()/free()/new/delete的调用都会被捕获。

      本文主要介绍的就是使用该工具进行程序的内存泄漏问题的检测和定位。

    Callgrind

    • 收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。

    Cachegrind

    • Cache分析器,它模拟CPU中的一级缓存I1,Dl和二级缓存,能够精确地指出程序中cache的丢失和命中。

    Helgrind

    • 它主要用来检查多线程程序中出现的竞争问题。
      Helgrind寻找内存中被多个线程访问,而又没有加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。

    Massif

    • 堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。

    2.3 特点与不足

    特点

    • 内存检测位置非常准确,可以确定代码出现问题的位置,这样为迅速解决内存问题非常重要。检测报告易读。

    不足

    • 由于Valgrind是程序下运行下,才能检测内存错误。另外没有运行到的路径也无法检测到错误。

    3.Valgrind安装

      CentOS7中直接使用命令进行安装

    yum install -y valgrind
    

    4.使用Valgrind进行内存检测

    4.1 示例代码

      编写不释放内存的示例代码

    #include <stdio.h>
    
    int main()
    {
        int *p_num = new int(10);
        int num = 100;
        p_num = &num;
        printf("num = %d\n", *p_num);
    }
    

      进行编译,注意,在编译过程中加入-g能够定位内存泄漏的代码位置,帮助我们进行问题排查。

    g++ -g -o test.so main.c
    

    4.2 执行工具命令

    ## 控制台查看
    valgrind --tool=memcheck --leak-check=full ./test.so
    
    ## 生成检测结果到文件
    valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-leak-kinds=all ./test.so
    

    4.3 执行结果查看

    ==73506== Memcheck, a memory error detector
    ==73506== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==73506== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
    ==73506== Command: ./test.so
    ==73506== 
    num = 100
    ==73506== 
    ==73506== HEAP SUMMARY:
    ==73506==     in use at exit: 4 bytes in 1 blocks
    ==73506==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated
    ==73506== 
    ==73506== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==73506==    at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344)
    ==73506==    by 0x40067E: main (main.c:5)
    ==73506== 
    ==73506== LEAK SUMMARY:
    ==73506==    definitely lost: 4 bytes in 1 blocks
    ==73506==    indirectly lost: 0 bytes in 0 blocks
    ==73506==      possibly lost: 0 bytes in 0 blocks
    ==73506==    still reachable: 0 bytes in 0 blocks
    ==73506==         suppressed: 0 bytes in 0 blocks
    ==73506== 
    ==73506== For lists of detected and suppressed errors, rerun with: -s
    ==73506== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
    

    4.4 执行结果分析

    主要关注的模块

    HEAP SUMMARY:输出堆上内存变化的统计信息

    LEAK SUMMARY:内存泄漏统计信息

    实际分析

      valgrind提示在程序退出前,还有4bytes空间未释放,分析日志中提示by 0x40067E: main (main.c:5)中的代码int *p_num = new int;没有释放,前面也提到了因为在编译中加了-g的参数,所以才能在运行介绍后,定位到没有释放内存模块申请内存的具体代码位置。

      从代码看,最开始申请了指向一个值为10的int数,然后将指针重新指向了其他地址,于是原来开辟的那块内存就无法进行释放操作了。

    按提示释放内存

      修改后的代码如下:

    #include <stdio.h>
    
    int main()
    {
        int *p_num = new int(100);
        printf("num = %d\n", *p_num);
        if (p_num != NULL)
        {
            delete p_num;
            p_num = NULL;
        }
    }
    

      继续测试,结果如下:

    $ g++ -g -o test.so main.c 
    $ valgrind --tool=memcheck --leak-check=full ./test.so
    ==77914== Memcheck, a memory error detector
    ==77914== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==77914== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
    ==77914== Command: ./test.so
    ==77914== 
    num = 100
    ==77914== 
    ==77914== HEAP SUMMARY:
    ==77914==     in use at exit: 0 bytes in 0 blocks
    ==77914==   total heap usage: 1 allocs, 1 frees, 4 bytes allocated
    ==77914== 
    ==77914== All heap blocks were freed -- no leaks are possible
    ==77914== 
    ==77914== For lists of detected and suppressed errors, rerun with: -s
    ==77914== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    

    5. 其他内存错误

    错误提示与原因对应关系如下:

    • uninitialisedvalue:使用了未初始化的变量
    • Invalid read/write:内存读写越界/读写已经释放的内存
    • Source anddestination overlap:内存覆盖
    展开全文
  • valgrind工具

    2021-03-31 20:01:24
    借用valgrind的百度百科的解释:Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。而且它遵守GNU通用公共许可证条款,是一款自由软件。链接: valgrind官网. 内存的使用产生问题,对于偏向于...

    valgrind简介

    借用valgrind的百度百科的解释:Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。而且它遵守GNU通用公共许可证条款,是一款自由软件。链接: valgrind官网.

    内存的使用产生问题,对于偏向于嵌入式的程序员来说,是很难避免的。虽然靠编码规范,规矩的开发流程,严格的单元测试,以及自身的底子的实力程度能很大程度避开这些问题,但是遇到了,就最好从根源上解决。

    valgrind包含很多工具,如下:

    工具作用
    Memcheck专门用于检测内存的问题,如:内存泄漏,内存覆盖,未初始化的内存的使用,越界访问等等
    Cachegrind主要用来检查程序中缓存使用时出现的问题
    Callgrind主要用来检查程序中函数调用过程中出现的问题
    Helgrind主要用来检查多线程程序中可能存在的竞争问题
    Massif主要用来检查程序中堆栈使用中存在的问题
    Extension通过core提供的功能,来编写特定的内存调试工具

    本文着重于Memcheck的使用。

    valgrind的交叉编译

    环境:

    目标机:ZLG的m1808核心板(基于Rockchip 的RK1808 AIoT处理器)
    宿主机:Ubuntu18.04

    源码:

    首先在自己的开发宿主机上下载份最新的valgrind源码。

    wget https://sourceware.org/pub/valgrind/valgrind-3.17.0.tar.bz2
    

    配置:

    1.先找到自己的交叉编译工具链的位置。然后进入解压后的valgrind-3.17.0中,执行以下命令:

    ./autogen.sh
    ./configure CC=xxx/aarch64-linux-gnu-gcc CXX=xxx/aarch64-linux-gnu-g++ LD=xxx/aarch64-linux-gnu-ld AR=xxx/aarch64-linux-gnu-ar --host=aarch64-linux --prefix=PATH
    
    #其中xxx为交叉编译工具链的路径 "aarch64-linux"为configure文件中可选的选项(选择适合自己目标机的)
    #PATH为编译后生成的文件存放位置
    

    着重说明一点,按照其README给的建议,–prefix的路径最好与目标机中的位置一样,不然容易出现问题,比如:
    “valgrind: failed to start tool ‘memcheck’ for platform ‘arm-linux’: No such file or directory”
    这步配置完后,剩下的步骤很简单:

    sudo make -j4
    sudo make install
    

    2.找到生成的文件,打包传入一样位置的路径中。如果不想传入一样的路径,那就在目标机的系统文件/etc/profile中添加:“export VALGRIND_LIB=/opt/valgrind-3.17.0/lib/valgrind
    当然,还可以在其中PATH路径的”/usr/bin:/usr/sbin:/bin:"后面把“xxx/valgrind-3.17.0/bin”加上,执行下source /etc/profile ,就可以当valgrind命令使用了。

    3.最后直接在目标机上任意位置输入命令:

    valgrind --version
    

    返回对应的版本号就成功了。否则,根据提示的信息找问题。如下图:
    图1

    valgrind的memcheck的使用

    –tool=< toolname > [default: memcheck] :toolname为选择的工具,默认为memecheck
    –log-file= < filename >:filename 为日志输出的文件名。
    ————————————————————————————————————————

    从官方文档看,对于memcheck使用,常用的有以下的选项指令:

    –leak-check=<no|summary|yes|full> [default: summary]
    启用后,在客户端程序完成时搜索内存泄漏。如果设置为summary,则说明发生了多少泄漏。如果设置为full或 yes,则每个泄漏都将详细显示和/或计为错误,如选项–show-leak-kinds和 所指定 --errors-for-leak-kinds。如果–xml=yes给出,则memcheck将自动使用value --leak-check=full。–show-leak-kinds=none如果您对泄漏结果不感兴趣,可以使用减少xml输出的大小。

    –leak-resolution=<low|med|high> [default: high]
    在执行泄漏检查时,确定为了将多个泄漏合并到一个泄漏报告中,Memcheck如何考虑将不同的回溯痕迹视为相同。设置为时low,仅前两个条目需要匹配。当med为时,必须匹配四个条目。当为时high,所有条目都必须匹配。

    核心泄漏调试,您可能希望 --leak-resolution=high与–num-callers=40或如此多一起使用 。
    请注意,该–leak-resolution设置不会影响Memcheck的发现泄漏的能力。它仅更改结果的显示方式。

    –show-leak-kinds= [default: definite,possible]
    full 通过以下方式之一指定要在泄漏搜索中显示的泄漏类型:
    用逗号分隔的一个或多个列表 definite indirect possible reachable。
    all指定全套(所有泄漏种类)。等同于 --show-leak-kinds=definite,indirect,possible,reachable。
    none 为空集。

    –errors-for-leak-kinds= [default: definite,possible]
    指定要在full泄漏搜索中计为错误的泄漏种类 。的 指定方式类似于 --show-leak-kinds

    –leak-check-heuristics= [default: all]
    指定在泄漏搜索期间要使用的一组泄漏检查启发式方法。启发式方法控制哪个内部指针指向一个块,使其被认为是可到达的。启发式集是通过以下方式之一指定的:

    用逗号分隔的一个或多个列表 stdstring length64 newarray multipleinheritance。
    all激活完整的启发式方法。等同于 --leak-check-heuristics=stdstring,length64,newarray,multipleinheritance。
    none 为空集。

    –show-reachable=<yes|no> , --show-possibly-lost=<yes|no>
    这些选项提供了一种选择的方式来指定要显示的泄漏类型:

    –show-reachable=no --show-possibly-lost=yes等同于 --show-leak-kinds=definite,possible。
    –show-reachable=no --show-possibly-lost=no等同于 --show-leak-kinds=definite。
    –show-reachable=yes等同于 --show-leak-kinds=all。
    【注意,–show-possibly-lost=no如果–show-reachable=yes指定,则无效。】

    –undef-value-errors=<yes|no> [default: yes]
    控制Memcheck报告是否使用未定义的值错误。no如果您不想看到未定义的值错误,请将此设置为 。它还具有一定程度加快Memcheck速度的副作用。AddrCheck(在Valgrind 3.1.0中删除)的功能类似于Memcheck(带有) --undef-value-errors=no。

    –track-origins=<yes|no> [default: no]:
    控制Memcheck是否跟踪未初始化值的来源。默认情况下,它不是,这意味着,尽管它可以告诉您未初始化的值正在以危险的方式使用,但是它无法告诉您未初始化的值是从哪里来的。这通常使得很难找到根本问题。

    设置yes为时,Memcheck会跟踪所有未初始化值的来源。然后,当报告未初始化的值错误时,Memcheck将尝试显示值的来源。源可以是以下四个位置之一:堆块,堆栈分配,客户端请求或其他各种源(例如的调用brk)。

    对于源自堆块的未初始化值,Memcheck将显示该块的分配位置。对于源自堆栈分配的未初始化值,Memcheck可以告诉您哪个函数分配了该值,但仅此而已-通常它会向您显示该函数的左括号的源位置。因此,您应该仔细检查函数的所有局部变量是否已正确初始化。

    请注意,组合 --track-origins=yes 和–undef-value-errors=no是荒谬的。Memcheck在启动时会检查并拒绝此组合。

    使用示例:

    void func(void)
    {
        float* t = (float*)malloc(sizeof(float)*4); 
        float* p = t;
        for(int i=0; i<4;i++){
            p++;
        }
        *p =4.4;  //未分配内存,无效的写入
        printf("%f\n",*p); //无效的读出
        //t指针未释放!
    }
    
    int main(void)
    {
        func();
        return 0; 
    }
    

    结果如下图:
    图2
    如愿的检查出三处地方:

    1. Invalid write of size 4”:无效的写入。
    2. Invalid read of size 4”:无效的读出。
    3. 16 byte in 1blocks are definitely lost…”:确定地泄漏了16字节。

    总的来说,valgrind对于项目上内存问题地检测还是不小的帮助,可以较快速地定位问题。

    展开全文
  • valgrind工具使用

    2019-07-26 15:31:27
    针对memcheck工具,需要注意以下几点: a. 强烈推荐被调试的目标程序在编译时加入-g参数,这样再运行valgrind memcheck时,可以拿到更为丰富的调试信息,比如行号,调用栈等。 b. 当使用-O0编译目标程序时,...

    1. 关于编译选项:

    针对memcheck工具,需要注意以下几点:

    a. 强烈推荐被调试的目标程序在编译时加入-g参数,这样再运行valgrind memcheck时,可以拿到更为丰富的调试信息,比如行号,调用栈等。

    b. 当使用-O0编译目标程序时,valgrind可以保证输出的所有警告、错误提示信息都是准确的,副作用是程序运行会非常慢。

    c. 当使用-O1编译目标程序时,valgrind可以保证程序运行速度相对较快,副作用是无法保证错误提示信息100%精确,比如,行号会不精确。(这点也很好理解,因为-O1下编译器会对指令进行重排)

    d. valgrind不推荐使用-O2和-O3编译目标程序,此时错误提示信息可能会存在误报,比如,valgrind会报大量uninitialised-value错误,实际这些错误并不真实存在。

    e. 在编译目标程序时添加-fno-inline,有利于valgrind生成更为精确的堆栈信息。(非必需)

        注意:如果不添加-fno-inline选项,也可以在运行valgrind时添加--read-inline-info=yes,这样valgrind会读取目标程序调试信息,使函数调用链能够正确显示。

    f. 在编译目标程序时推荐使用-Wall,打印所有编译器告警信息。因为在较高的编译优化级别下,valgrind可能无法检测出全部编译期告警信息。

    其他用于profile相关的工具,比如Cachegrind,通常不受编译优化选项的影响。在测试前,往往需要让程序在正常的编译优化选项下进行编译(比如-O2/-O3),之后再运行valgrind。

    2. 关于输出信息:

    为了说明valgrind的基本使用,以下是一个简单的示例(来自valgrind官网)。

     #include <stdlib.h>
     
     void f(void)
     {
         int* x = malloc(10 * sizeof(int));
         x[10] = 0;        // problem 1: heap block overrun
     }                    // problem 2: memory leak -- x not freed
     
     int main(void)
     {
         f();
         return 0;
     }
    当运行valgrind时,程序会输出以下信息:

    [adam040606@localhost test01]$ valgrind demo 
    ==17084== Memcheck, a memory error detector
    ==17084== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
    ==17084== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
    ==17084== Command: demo
    ==17084== 
    ==17084== Invalid write of size 4
    ==17084==    at 0x40054E: f (in /home/adam040606/Projects/valgrindTests/test01/demo)
    ==17084==    by 0x40055E: main (in /home/adam040606/Projects/valgrindTests/test01/demo)
    ==17084==  Address 0x51f7068 is 0 bytes after a block of size 40 alloc'd
    ==17084==    at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
    ==17084==    by 0x400541: f (in /home/adam040606/Projects/valgrindTests/test01/demo)
    ==17084==    by 0x40055E: main (in /home/adam040606/Projects/valgrindTests/test01/demo)
    ==17084== 
    ==17084== 
    ==17084== HEAP SUMMARY:
    ==17084==     in use at exit: 40 bytes in 1 blocks
    ==17084==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
    ==17084== 
    ==17084== LEAK SUMMARY:
    ==17084==    definitely lost: 40 bytes in 1 blocks
    ==17084==    indirectly lost: 0 bytes in 0 blocks
    ==17084==      possibly lost: 0 bytes in 0 blocks
    ==17084==    still reachable: 0 bytes in 0 blocks
    ==17084==         suppressed: 0 bytes in 0 blocks
    ==17084== Rerun with --leak-check=full to see details of leaked memory
    ==17084== 
    ==17084== For counts of detected and suppressed errors, rerun with: -v
    ==17084== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
    关于上面这个例子,有几点是值得关注的:

    a) valgrind实际上提供了一组默认工具集。如果不指定具体运行哪个工具集,则默认运行memcheck。

        在上面的示例中,valgrind demo 实际等价于 valgrind --tool=memcheck demo。

    b) 最左侧的数字 ——17084,实是PID。

    c) Invalid write of size 4 

        说明了具体的错误类型,说明发生了写越界。

        由于目标程序采用-O0进行编译,可以看到出现错误时完整的堆栈信息。

    d) definitely lost: 40 bytes in 1 blocks

        上述信息说明代码中存在明确的内存泄漏。

        如果在运行时添加了--leak-check=full,则会输出以下信息:

    ==17543== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==17543==    at 0x4C29BE3: malloc (vg_replace_malloc.c:299)
    ==17543==    by 0x400541: f (in /home/adam040606/Projects/valgrindTests/test01/demo)
    ==17543==    by 0x40055E: main (in /home/adam040606/Projects/valgrindTests/test01/demo)
    二、命令参数详解

    一、输出信息重定向:

    默认情况下,valgrind输出的信息会重定向到标准错误输出流(stderr,fd=2)。但有时我们往往需要将输出信息重定向到指定文件,有以下几种方式:

    1. --log-fd=N:

        通过这种方式直接将输出信息重定向到fd=N的文件中。

    2. --log-file=filename:

        将输出重定向到filename指向的文件。

    3. --log-socket=host_ip:port:

        举例:--log-socket=192.168.0.1:18888 或者 --log-socket=192.168.0.1

        通过这种方式可以将输出重定向到一台远程主机。如果端口号未填写,则默认1500。对于这种方式,valgrind不支持使用host_name,只能使用host_ip。

        valgrind还支持添加listener,可以同时处理50个valgrind进程的输出。

    二、屏蔽错误信息:

    我们的程序一般都会依赖一些系统库或者C运行时库。在使用valgrind进行memcheck时,会产生大量关于这些运行时库的错误信息,而这些信息通常是我们无法处理的。

    valgrind会在启动时,读取一个默认的suppresion file,屏蔽里面添加的错误。suppression file是在运行configure脚本时产生的。你可以根据自身项目需要,修改suppression file。

    详情可以查阅官方文档2.5节Suppressing Error。

    三、关键命令行选项:

    1. Tool-selection Option:

        --tool=<toolname> [default: memcheck]

        目前valgrind可以使用的工具包括:memcheck、cachegrind,callgrind,helgrind,drd,massif,lackey,none,exp-sgcheck,exp-bbv,exp-dhat等。

    2. Basic Options:

        以下只列出一些相关关键的命令行选项。

        a. -v, --verbose:

        输出更为详尽的提示信息,比如,所加载的共享对象的信息(the shared objects loaded)、输出屏蔽信息(the suppressions used)、注入(instrumentation)和执行(execution)引擎的工作过程,以及其他无用的告警。

        ===== 以下开关跟子进程相关 =====

        b. --trace-children=<yes|no> [default:no]:

        如果这个开关打开,valgrind将会跟踪当前进程创建的子进程。子进程必须通过exec()系统调用创建,目前valgrind无法对通过fork()创建出来的子进程进行跟踪。

        c. --trade-children-skip=patt1,patt2,... 

        当--trace-children=yes时,这个开关允许valgrind不对满足条件(patt1,patt2,....)的当前进程的子进程进行跟踪。这个也很好理解,因为被调试的进程可能会创建若干子进程,而我们并非关心全部子进程。

        补充说明:patt1,patt2实际上是进程的名字,支持?和*通配符。

        d. --child-silent-after-fork=<yes|no> [default:no]

        如果开启这个开关,valgrind不会输出任何由fork()创建出来的子进程。这个开关通常可以避免子进程输出信息混淆父进程输出信息。

         ===== 以下开关跟GDB相关 =====

        e. --vgdb=<no|yes|full> [default:yes]

        当--vgdb=yes或full时,valgrind将提供gdbserver的功能,允许GDB调试运行在valgrind之上的目标进程。(后面的章节会详细说明)

        f. --vgdb-error=<number> [default:999999999]

        当--vgdb=yes或full时,这个开关才能生效。valgrind检测到的error个数达到指定number时,将挂起目标程序,并允许用户通过GDB调试目标程序。

        如果number指定为0,在valgrind运行目标程序前,会先启动gdbserver。这个很有用,可以允许用户在目标程序启动前,向目标程序插入断点(breakpoints)。

        g. --vgdb-stop-at=<set> [default:none]

        当--vgdb=yes或full时,这个开关才能生效。通常,当valgrind检测到的错误数量达到--vgdb-error指定的错误数时,之后每触发一个错误,gdbserver都将会被调用(invoked)。

        通常,valgrind还允许用户在指定的事件发生时,触发针对gdbserver的调用。如下所示:

        *** 在目标程序启动(startup)、目标程序退出(exit),以及valgrind异常终止(valgrindabexit)时触发。

              注意:startup和--vgdb-error=0都会导致gdbserver在目标程序启动之前被调用。二者之间的不同点在于,--vgdb-error=0还会导致目标程序在启动之后每一个错误发生时,都触发gdbserver的调用。

        *** --vgdb-stop-at=all 等价于 --vgdb-stop-at=startup,exit,valgrindabexit

        *** --vgdb-stop-at=none (默认情况)

    3. Erro-related Options:

        a. --demangle=<yes|no> [default:yes]

        C++中默认会对符号进行名称修饰(name mangling)。默认情况下--demangle=yes,valgrind会将符号还原为未经过名称修饰前的样子。

        b. --num-callers=<number> [default:12]

        这个参数主要指定调用链(call chain)嵌套的深度。默认情况下,valgrind能够识别的调用链嵌套深度为12,能够支持的最大值为500。当--num-caller=500时,valgrind运行速度会下降,内存占用也会上升。对于调用链嵌套很深的程序,这个选项比较有用。

        c. --sigill-diagnostics=<yes|no> [default:yes]

        这个参数主要用于在发生SIGILL信号时,valgrind是否输出必要的诊断信息。通常,使用valgrind调试目标程序时,当valgrind无法decode或translate一条特定的指令时,将产生SIGILL信号。产生SIGILL的根源有两种情况,第一,目标程序本身存在bug;第二,目标程序使用了valgrind无法识别的特殊指令。

        d. --show-below-main=<yes|no> [default:no]

        这个参数如果设置为yes,将会输出C/C++运行时库中检测到的错误。通常,我们并不需要关心运行时库中的错误。

        e. --fullpath-after=<string> [default:don't show source paths]

        默认情况下,valgrind在输出堆栈信息时(statck traceback)仅输出文件名。对于大型工程,不同模块的源代码处于不同目录,可能会带来不便。通过这个参数,用户可以指定源代码所在路径,这样在valgrind输出调用栈信息时,会输出文件所在路径信息。

        f. --extra-debuginfo-path=<path> [default:undefined and unused]

        在Linux发布版本中,系统库一般是不带调试信息的。确切说,二进制文件和调试信息本身是分离的。默认情况下,valgrind会扫描/usr/lib/debug目录,以查找系统库对应的默认调试信息。但是,有些情况下,用户依然系统自己指定二进制文件对应的调试信息目录,此时,这个命令行参数就能派上用场。

        g. --max-stackframe=<number> [default:2000000]

        指定堆栈上每一个栈帧(stack frame)大小上限。如果堆栈指针(stack pointer, esp/rsp)移动超过这个阈值,valgrind将假设程序将切换到另一个栈帧。

        一般情况下,如果一个程序会在堆栈上分配一个很大的数组,则在使用valgrind调试时,可能需要设置这个参数。当然,在栈上分配很大的数组通常不是一个好的做法,因为很容易将堆栈空间耗尽。另外,valgrind memcheck工具针对堆的内存检测,要比栈空间更高效。

        h. --main-stacksize=<number> [default:use current 'ulimit' value]

        指定主线程的堆栈大小。为了简化内存管理,valgrind在启动时,为主线程调用栈预留全部内存空间。这使得在启动时必须确定需要多大的栈空间。

        默认情况下,valgrind将使用ulimit中的stack size,或者16MB,作为默认值。

        注意:--main-stacksize和--main-stackframe时有差别的。前者代表当前线程整个堆栈需要多大的内存空间。后者代表堆栈上某一栈帧最大允许字节。

        i. --max-threads=<number> [default:500]

        默认情况下,valgrind可以同时处理最多500个线程。

    4. Malloc-related Options:

        对于Valgrind中的Memcheck、Massif、Helgrind、DRD等工具,往往需要使用自己定义的malloc、realloc版本。因此,可能会涉及以下选项:

        a. --alignment=<number> [default:8 or 16,depends on the platform]

        对于Valgrind中使用的malloc、realloc,默认情况下,其分配的内存的起始地址为8字节或16字节对齐的。具体时8字节对齐,还是16字节对齐,跟具体的平台相关。该命令行选项允许用户指定一个不同的对齐方式,其中number必须必默认的对齐方式(即8字节或16字节)要大,并且必须小于等于4096。此外,还必须是2的倍数。

        b. --redzone-size=<number> [default:depends on tool]

        Valgrind中使用的malloc和realloc,往往会在每一个从堆(Heap)上分配的bock之前及之后,插入padding block。这些padding block也被称为red zone。Red zone的大小默认16字节。可见,默认情况下,valgrind能够检测出当前block向前及向后16字节内内存读写错误。

        本选项可以设置padding block的大小。将该配置设置得过大,会消耗更多的内存。

    四、关于多线程:

        对于多线程程序,valgrind实际上会将所有线程的执行串行化。也就是说,即使运行环境拥有多CPU或者多核,对于运行在valgrind之上的(多线程)程序,同时只会有一个线程运行,即同时只会占据CPU的一个核。这样做主要是为了简化valgrind设计,避免因考虑多线程而引入不必要的设计上的复杂度。

        Valgrind实际上并不直接调度线程。仅仅是通过一种简单的锁机制,来确保同时只有一个线程运行。真正的线程调度还是由操作系统内核控制。因此,目标程序运行在Valgrind下,同直接运行在操作系统之上相比,将会有截然不同的行为。因为Valgrind将目标程序串行化,因此目标程序运行于Valgrind之上时,将会比正常运行慢很多。

        关于Valgrind线程调度及多线程性能

        线程占据CPU执行之前,首先必须获取锁。执行完一定数量指令之后,运行线程释放锁。其他就绪线程将继续争抢锁。

        命令行选项 --fair-sched 用来设置valgrind使用的锁机制,用来串行化目标程序中所有线程。

        默认情况下,--fair-sched=no,此时valgrind采用基于Pipe的锁机制,适用于所有平台。这种机制不保证线程之间公平性,极有可能出现一个运行线程释放锁后立马又获取锁,即使此刻其他线程已经就绪。使用这种调度策略,目标程序每次运行都将产生截然不同的行为。

        当 --fair-sched=yes 或 --fair-sched=try时,valgrind将采用基于mutex的锁机制,仅适用于部分平台。基于mutex的锁机制可以确保线程间公平调度(Round-Robin,轮询),如果多个线程同时就绪,则锁将分配给第一个就绪的线程。注意,阻塞在系统调用的线程不能请求占用锁,只有从系统调用唤醒后,才能请求占用锁
     

    展开全文
  • 1 valgrind基础知识 1.1 valgrind简介 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。 Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一...
  • Valgrind工具介绍

    2021-11-25 11:17:09
    Valgrind工具介绍 valgrind主要包括以下调试和分析工具,每一个工具具有不同的作用。 Memcheck Mwmcheck能够检测程序中出现的内存问题,主要针对 C 和 C++ 程序。当程序通过Memcheck 运行时,会检查所有内存的读写,...
  • Valgrind 是个开源的工具,功能很多。例如检查内存泄漏工具---memcheck。 Valgrind 安装: 去官网下载: http://valgrind.org/downloads/current.html#current 安装过程:(可以直接查看README文档来确认安装过程...
  • valgrind工具的使用

    2020-05-29 21:35:54
    Valgrind是一款用于内存调试、内存泄漏检测以及性能分析、检测线程错误的软件开发工具Valgrind 是运行在Linux 上的多用途代码剖析和内存调试软件。主要包括Memcheck、Callgrind、Cachegrind 等工具,每个工具都能...
  • Valgrind工具之内存检测

    千次阅读 2018-06-10 15:59:55
    Valgrind安装方法:按顺序执行以下命令:1. wget http://www.valgrind.org/downloads/valgrind-3.10.0.tar.bz2(从valgrind官网上下载压缩包)2. tar xvf valgrind-3.13.0(解压压缩包)3. cd valgrind-3.10.03. ./...
  • valgrind工具使用详解

    千次阅读 2015-01-08 11:33:45
    ...一 valgrind是什么?...Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它
  • Valgrind是用于构建动态分析工具的仪器框架。它附带了一组工具,每个工具都执行某种调试,分析或类似任务,可帮助您改进程序。Valgrind的架构采用模块化设计,因此可以轻松创建新工具,而不会干扰现有结构。 二、...
  • valgrind工具集介绍 valgrind包含下列工具: 1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。 2、callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。 3、cachegrind:分析...
  • 一 Valgrind工具集简绍 Valgrind包含下列工具:  1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。  2、callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。  3、...
  • 2、分析 执行命令:valgrind --tool=massif --time-unit=B ./a.out,./a.out是可执行程序,执行完毕后,massif将分析数据保存在在当前目录下,文件格式是massif.out.PID,PID是进程号 3、查看 使用 ms_print massif...
  • valgrind工具介绍

    2020-12-24 06:05:44
    一、简介Valgrind是一个二进制插桩框架,可以用来制作二进制分析工具。利用Valgrind可以检测二进制程序的内存和线程漏洞。Valgrind框架目前包含以下几种工具:Memcheckis a memory error detector. It helps you ...
  •  Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而...
  • 不过呢,有可能有些同学可能不知道Valgrind有哪些功能,那么我就从Valgrind的官方网站处,摘几段文字吧。 Memcheck Memcheck detects memory-management problems, and is aimed primarily at C and C++ programs. ...
  • Valgrind是用于构建动态分析工具的仪器框架。它附带了一组工具,每个工具都执行某种调试,分析或类似任务,可帮助您改进程序。Valgrind的架构采用模块化设计,因此可以轻松创建新工具,而不会干扰现有结构。 二、...
  • 一、使用valgrind 1、安装 安装超级简单: sudo apt-get install valgrind 2、使用 运行valgrind -h可以...最重要的选项是–tool决定运行哪种Valgrind工具。 例如,使用内存检查工具Memcheck 运行“ls -l”...
  • Valgrind 工具概述

    2017-09-17 16:48:18
    Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具
  • 目录 一、mtrace 命令 ... 二、valgrind 工具 1、下载 2、查看 一、mtrace 命令 $ gcc test.c -o test -g $ ./test $ mtrace test trace.log 1、函数接口 #include <mcheck.h> void m...
  • valgrind是linux下非常强大的工具,通过 NDK编译,让其在安卓环境下定位C/C++的问题。 一、材料 wget http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2 ndk-r14b 二、使用步骤 1.阅读README.android #!/bin...
  • 因为公司服务器上面本身就安装有valgrind,所以我是直接拿过来使用的,并没有自己安装过,需要安装的朋友自己google安装吧。 可以使用 which valgrind 命令来看自己电脑上是否已经安装上valgrind。 useful link: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,829
精华内容 4,331
关键字:

valgrind工具

友情链接: bp_pid.zip