内存检测Valgrind
Valgrind是运行在Linux上一套基于仿真技术的程序调试和分析工具,作者是获得过Google-O’Reilly开源大奖的Julian Seward,它包含一个内核──一个软件合成的CPU,和一系列的小工具,每个工具都可以完成一项任务──调试,分析,或测试等,内存检测,我们可以使用它的工具:Memcheck。
Valgrind 安装
-
方法 1. valgrind官网:http://valgrind.org下载
-
方法 2. Ubuntu sudo apt-get install valgrind
Memcheck检测范围
用来检测c/c++程序中出现的内存问题,所有对内存的读写都会被检测到,一切malloc()/free()/new/delete的调用都会被捕获。所以,它能检测以下问题:
-
对未初始化内存的使用;
-
读/写释放后的内存块;
-
读/写超出malloc等分配的动态内存范围;
-
读/写不适当的栈中内存块; 栈中有函数,静态变量,数组等
-
内存泄漏,指向一块内存的指针永远丢失;
-
不正确的malloc/free或new/delete匹配;
-
memcpy()相关函数中的dst和src指针重叠问题。
Memcheck 检查步骤及注意事项
-
在编译程序的时候打开调试模式(gcc编译器的-g选项),以便显示行号,编译时去掉-O1 -O2等优化选项;检查的是C++程序的时候,考虑加上选项: -fno-inline ,这样它函数调用链会很清晰工具泄漏检测使用完整模式 生成的报告 执行程序
-
执行:
valgrind --tool=memcheck --leak-check=full --log-file=./log.txt ./YourProgram
2.1 工具: memcheck --leak-check
2.2 泄漏检测使用完整模式: full --log-file
2.3 生成的报告: ./log.txt
2.4 执行程序: ./YourProgram -
程序运行结束,查看 log.txt 中的结果。
结果分析
Valgrind(memcheck)包含这7类错误,黑体为一般的错误提示:
-
illegal read/illegal write errors 非法读取/非法写入错误
-
use of uninitialised values 使用未初始化的区域
-
use of uninitialised or unaddressable values in system calls 系统调用时使用了未初始化或不可寻址的地址
-
illegal frees 非法的释放
-
when a heap block is freed with an inappropriate deallocation function 分配和释放函数不匹配
-
overlapping source and destination blocks 源和目的内存块重叠
-
memory leak detection 内存泄漏检测
7.1 Still reachable
内存指针还在还有机会使用或者释放,指针指向的动态内存还没有被释放就退出了7.2 Definitely lost
确定的内存泄露,已经不能够访问这块内存7.3 Indirectly lost
指向该内存的指针都位于内存泄露处7.4 Possibly lost
可能的内存泄露,仍然存在某个指针能够访问某块内存,但该指针指向的已经不是该内
存首位置
7.5 Suppressed 某些库产生的错误不予以提示,这些错误会被统计到suppressed项目
一个小栗子:
text.c
#include <stdio.h>
#include <stdlib.h>
void text(){
int *ptr = malloc(sizeof(int) * 10);
ptr[10] = 100;
}
int main(){
text();
return 0;
}
root@cuirui-virtual-machine:/home/cuirui/text_demo/memcheck_text# gcc text.c -o text.exe
root@cuirui-virtual-machine:/home/cuirui/text_demo/memcheck_text# valgrind --tool=memcheck --leak-check=full --log-file=./log.txt ./text.exe
root@cuirui-virtual-machine:/home/cuirui/text_demo/memcheck_text# ls
log.txt text.c text.exe
root@cuirui-virtual-machine:/home/cuirui/text_demo/memcheck_text# cat log.txt
==34669== Memcheck, a memory error detector
==34669== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==34669== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==34669== Command: ./text.exe
==34669== Parent PID: 34504
==34669==
==34669== Invalid write of size 4
==34669== at 0x10916B: text (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669== by 0x109185: main (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669== Address 0x4a51068 is 0 bytes after a block of size 40 alloc'd
==34669== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34669== by 0x10915E: text (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669== by 0x109185: main (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669==
==34669==
==34669== HEAP SUMMARY:
==34669== in use at exit: 40 bytes in 1 blocks
==34669== total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==34669==
==34669== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==34669== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==34669== by 0x10915E: text (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669== by 0x109185: main (in /home/cuirui/text_demo/memcheck_text/text.exe)
==34669==
==34669== LEAK SUMMARY:
==34669== definitely lost: 40 bytes in 1 blocks
==34669== indirectly lost: 0 bytes in 0 blocks
==34669== possibly lost: 0 bytes in 0 blocks
==34669== still reachable: 0 bytes in 0 blocks
==34669== suppressed: 0 bytes in 0 blocks
==34669==
==34669== For lists of detected and suppressed errors, rerun with: -s
==34669== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
root@cuirui-virtual-machine:/home/cuirui/text_demo/memcheck_text#