valgrind的memcheck功能使用手册
valgrind是一个构建动态分析程序的工具集框架,它有一套功能强大的工具集合,包括debug、profiling等,其中最重要和常用的是内存泄漏检测工具memcheck
下载:
wget https://sourceware.org/pub/valgrind/valgrind-3.22.0.tar.bz2 --no-check-certificate
解压后编译安装:
tar xf valgrind-3.22.0.tar.bz2 && cd valgrind-3.22.0
./configure --prefix=`pwd`/bin_install
make -j 20 && make install
注意操作系统需要redhat7以上系统,否则编译会报错。并且运行的系统也要再redhat7以上系统上,否则会出现一些莫名其妙的错误,例如new函数返回NULL,对应的errno是115(Operation now in progress)或者110(Connection timed out)
运行valgrind的memcheck功能方法如下:
- 配置PATH环境变量:
export PATH=/path/to/valgrind-3.22.0/bin_install/bin:$PATH
- 指定参数运行:
valgrind --tool=memcheck --leak-check=full --trace-children=yes --log-file=valgrind.log ./a.out
# --tool指定哪一个valgrind工具去使用,此处用的是memcheck
# --leak-check指定输出具体的内存泄露位置
# --trace-children指定是否追踪子进程
# --log-file指定记录日志文件的名称
# 最后是运行命令的路径以及它的参数
# 相关使用帮助:
# https://valgrind.org/docs/manual/manual-core.html
# https://valgrind.org/docs/manual/mc-manual.html#mc-manual.overview
- 日志结果的解读:
# 开始部分会有如下输出:
# 这部分是在说明如何通过gdb来调试进程,需要通过一个vgdb的中间件工具来开始调试过程
==21045== TO CONTROL THIS PROCESS USING vgdb (which you probably
==21045== don't want to do, unless you know exactly what you're doing,
==21045== or are doing some strange experiment):
==21045== /path/to/valgrind-3.22.0/bin_install/libexec/valgrind/../../bin/vgdb --pid=21045 ...command...
==21045==
==21045== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==21045== /path/to/gdb bin/calEng
==21045== and then give GDB the following command
==21045== target remote | /path/to/valgrind-3.22.0/bin_install/libexec/valgrind/../../bin/vgdb --pid=21045
==21045== --pid is optional if only one valgrind process is running
==21045== HEAP SUMMARY:
==21045== in use at exit: 35,163,487 bytes in 13 blocks
==21045== total heap usage: 2,017 allocs, 2,004 frees, 180,650,623 bytes allocated
==21045==
==21045== Searching for pointers to 13 not-freed blocks
==21045== Checked 54,065,968 bytes
==21045== LEAK SUMMARY:
==21045== definitely lost: 72 bytes in 3 blocks
==21045== indirectly lost: 0 bytes in 0 blocks
==21045== possibly lost: 32,637,056 bytes in 2 blocks
==21045== still reachable: 2,526,359 bytes in 8 blocks
==21045== suppressed: 0 bytes in 0 blocks
==21045== Reachable blocks (those to which a pointer was found) are not shown.
==21045== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==21045== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
--21046-- REDIR: 0x4ab28c0 (libc.so.6:bcmp) redirected to 0x40241c3 (_vgnU_ifunc_wrapper)
--21046-- REDIR: 0x4b8d220 (libc.so.6:__memcmp_sse4_1) redirected to 0x4039890 (__memcmp_sse4_1)
--21046-- REDIR: 0x4b75130 (libc.so.6:__memmove_ssse3) redirected to 0x4037760 (memcpy@GLIBC_2.2.5)
==21046== Warning: set address range perms: large range [0x153cd5040, 0x17ba55500) (undefined)
--21046-- REDIR: 0x597a050 (libstdc++.so.6:operator delete[](void*)) redirected to 0x403324b (operator delete[](void*))
--21046-- REDIR: 0x597a020 (libstdc++.so.6:operator delete(void*)) redirected to 0x4031237 (operator delete(void*))
# 条件判断中使用了未初始化的变量
==21046== Thread 17:
==21046== Conditional jump or move depends on uninitialised value(s)
==21046== at 0x91FA4C: heartbeat(long, int, int, long) (service.cpp:2349)
# 系统调用参数有未初始化的变量
==21046== Thread 16:
==21046== Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
==21046== at 0x4B22ECB: send (in /usr/lib64/libc-2.17.so)
附注:
在使用过程中发现一个现象,作为多线程的高性能应用程序,被valgrind测试memcheck时,CPU利用率基本集中在单线程的valgrind进程上,作为子进程的应用程序基本没有CPU压力,此问题作为后续应用调研的方向。