美文网首页
valgrind内存泄漏检测快速上手

valgrind内存泄漏检测快速上手

作者: ShootHzj | 来源:发表于2021-10-17 16:14 被阅读0次

    准备被测程序

    通过-g编译程序来携带debug信息,这样子输出的错误信息就可以包含精确的行号。如果你可以承受程序运行缓慢,那么我们可以使用-O0来编译程序。如果使用-O1,那么输出的行号可能会不准确。不推荐使用-O2及以上,因为 valgrind memcheck 偶尔会报告不存在的未初始化值错误。

    运行程序

    如果平时这么运行

    myprog arg1 arg2
    

    就使用这个命令

    valgrind --leak-check=yes myprog arg1 arg2
    

    Memcheck是默认的valgrind工具,--leak-check打开了内存泄漏检测开关。

    通过这个命令运行,大约会比平时运行慢20到30倍,并且使用更大的内存。Memcheck 将发出它检测到的内存错误和泄漏的信息。

    解释memcheck的输出

    使用样例的C程序,包含一个内存分配错误和内存溢出

    #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;
    }
    

    执行内存检测

    gcc -g demo.c
    valgrind ./a.out
    

    输出信息如下

    ==145== Memcheck, a memory error detector
    ==145== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==145== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info
    ==145== Command: ./a.out
    ==145==
    ==145== Invalid write of size 4
    ==145==    at 0x401144: f (demo.c:6)
    ==145==    by 0x401155: main (demo.c:11)
    ==145==  Address 0x4a27068 is 0 bytes after a block of size 40 alloc'd
    ==145==    at 0x484086F: malloc (vg_replace_malloc.c:380)
    ==145==    by 0x401137: f (demo.c:5)
    ==145==    by 0x401155: main (demo.c:11)
    ==145==
    ==145==
    ==145== HEAP SUMMARY:
    ==145==     in use at exit: 40 bytes in 1 blocks
    ==145==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
    ==145==
    ==145== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==145==    at 0x484086F: malloc (vg_replace_malloc.c:380)
    ==145==    by 0x401137: f (demo.c:5)
    ==145==    by 0x401155: main (demo.c:11)
    ==145==
    ==145== LEAK SUMMARY:
    ==145==    definitely lost: 40 bytes in 1 blocks
    ==145==    indirectly lost: 0 bytes in 0 blocks
    ==145==      possibly lost: 0 bytes in 0 blocks
    ==145==    still reachable: 0 bytes in 0 blocks
    ==145==         suppressed: 0 bytes in 0 blocks
    ==145==
    ==145== For lists of detected and suppressed errors, rerun with: -s
    ==145== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
    
    • 145 是进程号
    • 输出的第一行,即上方的第六行(Invalid write)表明了错误的类型。这里程序往不归它拥有的内存中写入了信息
    • 下方是错误的堆栈信息
    • 代码地址如0x401155通常并不重要,但有时候定位奇怪的问题可能会很关键
    • 一些错误信息会有第二段,用来描述所涉及的内存地址。上例指出写入的内存刚好超过 example.c 的第 5 行使用 malloc() 分配的块的末尾。

    内存泄漏信息

    ==145== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==145==    at 0x484086F: malloc (vg_replace_malloc.c:380)
    ==145==    by 0x401137: f (demo.c:5)
    ==145==    by 0x401155: main (demo.c:11)
    

    堆栈可以表明什么内存泄露了,但memcheck并不能告诉你内存泄漏的原因

    valgrind会提示两种内存泄漏

    • "definitely lost": 绝对泄漏了内存,必须修复
    • "probably lost": 程序可能泄漏了内存,也有可能是一些特定的指针操作(如:指针放到了堆中)

    参考

    https://www.valgrind.org/docs/manual/quick-start.html#quick-start.intro

    https://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.errormsgs

    相关文章

      网友评论

          本文标题:valgrind内存泄漏检测快速上手

          本文链接:https://www.haomeiwen.com/subject/mydwoltx.html