打开微信,使用扫一扫进入页面后,点击右上角菜单,
点击“发送给朋友”或“分享到朋友圈”完成分享
wget ftp://sourceware.org/pub/valgrind/valgrind-3.17.0.tar.bz2 tar -jxvf valgrind-3.17.0.tar.bz2 cd valgrind-3.17.0 ./configure && make sudo make install
memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。
callgrind:检测程序代码覆盖,以及分析程序性能。
cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。
helgrind:用于检查多线程程序的竞态条件。
massif:堆栈分析器,指示程序中使用了多少堆内存等信息。
程序代码如下,gcc编译时需加-g参数:
void mal0(){ void* array = malloc(sizeof(int)); } int main(){ mal0(); return 0; }
执行valgraind使用memcheck工具:
valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./test_c
得到输出log如下:
==23282== Memcheck, a memory error detector ==23282== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==23282== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==23282== Command: ./test_c ==23282== ==23282== ==23282== HEAP SUMMARY: ==23282== in use at exit: 4 bytes in 1 blocks ==23282== total heap usage: 1 allocs, 0 frees, 4 bytes allocated ==23282== ==23282== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==23282== at 0x4C2F03A: malloc (vg_replace_malloc.c:380) ==23282== by 0x4005F4: mal1 (mal.c:10) ==23282== by 0x400642: main (mal.c:20) ==23282== ==23282== LEAK SUMMARY: ==23282== definitely lost: 4 bytes in 1 blocks ==23282== indirectly lost: 0 bytes in 0 blocks ==23282== possibly lost: 0 bytes in 0 blocks ==23282== still reachable: 0 bytes in 0 blocks ==23282== suppressed: 0 bytes in 0 blocks ==23282== ==23282== For lists of detected and suppressed errors, rerun with: -s ==23282== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
命令分析
--tool=memcheck:此时使用的valgrind工具,默认memcheck --leak-check:指定如何报告内存泄漏 no 不报告 summary 显示简要信息,有多少个内存泄漏。summary是缺省值。 yes 和 full 显示每个泄漏的内存在哪里分配。 show-leak-kinds: 指定显示内存泄漏的类型的组合。类型包括definite, indirect, possible,reachable。也可以指定all或none。缺省值是definite,possible。
log分析
左侧为进程ID 右1为valgrind版本信息等 右2为HEAP SUMMARY,他表示程序在堆上分配内存的情况。当前分析的结果,如图所示:1 allocs, 0 frees, 4 bytes allocated代表申请1次,释放0次,分配了4字节内存。之后会显示详细的代码调用,可知时mal1函数导致了内存泄漏。 右3为当前总结,definitely lost: 4 bytes in 1 blocks代表实锤丢了4个字节 。 Definitely lost:找不到指向该块的指针 Indirectly lost:块间接丢失 possibly lost:存在指向该块的"内部指针"。memcheck无法确定是否为合法 Still reachable:可以找到指向该内存块的"开始指针"。理论上程序退出前,可以通过这些指针来释放内存。
如果使用g++编译,会出现如下情况,出现两次申请未释放
==23363== Memcheck, a memory error detector ==23363== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==23363== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==23363== Command: ./test_c ==23363== ==23363== ==23363== HEAP SUMMARY: ==23363== in use at exit: 72,708 bytes in 2 blocks ==23363== total heap usage: 2 allocs, 0 frees, 72,708 bytes allocated ==23363== ==23363== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==23363== at 0x4C2F03A: malloc (vg_replace_malloc.c:380) ==23363== by 0x4007D4: mal1() (mal.c:11) ==23363== by 0x40081D: main (mal.c:21) ==23363== ==23363== 72,704 bytes in 1 blocks are still reachable in loss record 2 of 2 ==23363== at 0x4C2F03A: malloc (vg_replace_malloc.c:380) ==23363== by 0x4EC8EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21) ==23363== by 0x40106F9: call_init.part.0 (dl-init.c:72) ==23363== by 0x401080A: call_init (dl-init.c:30) ==23363== by 0x401080A: _dl_init (dl-init.c:120) ==23363== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so) ==23363== ==23363== LEAK SUMMARY: ==23363== definitely lost: 4 bytes in 1 blocks ==23363== indirectly lost: 0 bytes in 0 blocks ==23363== possibly lost: 0 bytes in 0 blocks ==23363== still reachable: 72,704 bytes in 1 blocks ==23363== suppressed: 0 bytes in 0 blocks ==23363== ==23363== For lists of detected and suppressed errors, rerun with: -s ==23363== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
log分析
这是因为C++为了提高效率,使用的内存池机制。当程序终止时,其内存才会被操作系统回收,因此valgrind将72,704大小报为reachable。
编写如下代码,带-g编译
valgrind查看:valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./read
log信息
==23850== Memcheck, a memory error detector ==23850== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==23850== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==23850== Command: ./read ==23850== ==23850== Invalid read of size 4 ==23850== at 0x4009B4: read() (read.cpp:7) ==23850== by 0x400A2D: main (read.cpp:11) ==23850== Address 0x5abbc90 is 0 bytes after a block of size 16 alloc'd ==23850== at 0x4C2F75B: operator new(unsigned long) (vg_replace_malloc.c:417) ==23850== by 0x400F95: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (new_allocator.h:104) ==23850== by 0x400EDF: __gnu_cxx::__alloc_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) (alloc_traits.h:182) ==23850== by 0x400DEB: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (stl_vector.h:170) ==23850== by 0x400CC6: void std::vector<int, std::allocator<int> >::_M_initialize_dispatch<int>(int, int, std::__true_type) (stl_vector.h:1249) ==23850== by 0x400B11: std::vector<int, std::allocator<int> >::vector<int>(int, int, std::allocator<int> const&) (stl_vector.h:413) ==23850== by 0x400996: read() (read.cpp:6) ==23850== by 0x400A2D: main (read.cpp:11) ==23850== vas[4]:0 ==23850== ==23850== HEAP SUMMARY: ==23850== in use at exit: 72,704 bytes in 1 blocks ==23850== total heap usage: 3 allocs, 2 frees, 73,744 bytes allocated ==23850== ==23850== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1 ==23850== at 0x4C2F03A: malloc (vg_replace_malloc.c:380) ==23850== by 0x4EC8EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21) ==23850== by 0x40106F9: call_init.part.0 (dl-init.c:72) ==23850== by 0x401080A: call_init (dl-init.c:30) ==23850== by 0x401080A: _dl_init (dl-init.c:120) ==23850== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so) ==23850== ==23850== LEAK SUMMARY: ==23850== definitely lost: 0 bytes in 0 blocks ==23850== indirectly lost: 0 bytes in 0 blocks ==23850== possibly lost: 0 bytes in 0 blocks ==23850== still reachable: 72,704 bytes in 1 blocks ==23850== suppressed: 0 bytes in 0 blocks ==23850== ==23850== For lists of detected and suppressed errors, rerun with: -s ==23850== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
上述log可见,内存越界发生在函数read中,共越界了4个字节,共申请16个字节大小空间
编写如下代码,加-g编译
valgaind查看:valgrind --tool=memcheck --track-origins=yes ./zero
#include <iostream> #include <stdio.h> #include <stdlib.h> int main(){ int x; if (51 == x) printf("51 kuaile\n"); }
log分析:
==29342== Memcheck, a memory error detector ==29342== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==29342== Using Valgrind-3.17.0 and LibVEX; rerun with -h for copyright info ==29342== Command: ./zero ==29342== ==29342== Conditional jump or move depends on uninitialised value(s) ==29342== at 0x400712: main (zero.cpp:7) ==29342== Uninitialised value was created by a stack allocation ==29342== at 0x400706: main (zero.cpp:5) ==29342== ==29342== ==29342== HEAP SUMMARY: ==29342== in use at exit: 72,704 bytes in 1 blocks ==29342== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated ==29342== ==29342== LEAK SUMMARY: ==29342== definitely lost: 0 bytes in 0 blocks ==29342== indirectly lost: 0 bytes in 0 blocks ==29342== possibly lost: 0 bytes in 0 blocks ==29342== still reachable: 72,704 bytes in 1 blocks ==29342== suppressed: 0 bytes in 0 blocks ==29342== Rerun with --leak-check=full to see details of leaked memory ==29342== ==29342== For lists of detected and suppressed errors, rerun with: -s ==29342== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
热门帖子
精华帖子