valgrind简介和使用

2017-12-30 11:21:02来源:http://www.yangguanjun.com/2017/12/29/valgrind-intro-usage/作者:ForTech人点击

分享


最近有需求要分析定位下开发的文件存储网关的内存泄露问题,对比了几款后选择了valgrind
这款工具,功能很是强大,这里我还只使用了一些基本的功能,记录如下。



Valgrind
支持很多工具:Memcheck
,Addrcheck
,Cachegrind
,Massif
,Helgrind
和Callgrind
等。



官网:http://valgrind.org/


安装
$ wget ftp://sourceware.org/pub/valgrind/valgrind-3.13.0.tar.bz2
$ bzip2 -d valgrind-3.13.0.tar.bz2
$ tar -xf valgrind-3.13.0.tar
$ cd valgrind-3.13.0/
$ ./configure
$ make
$ sudo make install
使用与分析
$ valgrind --help
usage: valgrind [options] prog-and-args
...
常用的一些options有:
--trace-children=no|yes Valgrind-ise child processes (follow execve)? [no]
--log-file=<file> log messages to <file>
--leak-check=no|summary|full search for memory leaks at exit?[summary]
--show-reachable=yes same as --show-leak-kinds=all
--show-reachable=no --show-possibly-lost=yes
same as --show-leak-kinds=definite,possible
--show-reachable=no --show-possibly-lost=no
same as --show-leak-kinds=definite

常用命令格式:


$ /usr/local/bin/valgrind --log-file=mylog ./file-gateway


valgrind
的memcheck
组件支持的内存泄露检查大概有:


读写非法的内存
访问未初始化的内存
访问已经释放了的内存
申请的内存没有释放
重复释放内存
释放非法内存
source
和destination
内存的重叠
uninitialised byte(s)

检查出程序中未初始化而访问的变量


==1350634== Thread 14:
==1350634== Syscall param setxattr(value) points to uninitialised byte(s)
==1350634==at 0x6D9EB8A: setxattr (in /usr/lib64/libc-2.17.so)
==1350634==by 0x487268: VFS::file_setxattr(std::string, std::string, void*, int) (vfs.cc:64)
==1350634==by 0x488066: FileGwVFS::file_setxattr(std::string, std::string, void*, int) (vfs.cc:175)
==1350634==by 0x459583: FileGateway::set_file_xattr(std::string, sgwd_xattr*) (file_gateway.cc:742)
==1350634==by 0x463706: FileGwRedisWorkItem::update_file_xattr_status(gateway_file_status) (redis_work_item.cc:703)
==1350634==by 0x4641B1: FileGwRedisWorkItem::file_upload() (redis_work_item.cc:793)
==1350634==by 0x45F89E: FileGwRedisWorkItem::process() (redis_work_item.cc:190)
==1350634==by 0x486532: WorkThread::process_work_item() (work_thread.cc:49)
==1350634==by 0x486850: ShardedWorkThread::entry() (work_thread.cc:112)
==1350634==by 0x481B58: Thread::_entry_func(void*) (thread.cc:74)
==1350634==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1350634==by 0x6D9FCEC: clone (in /usr/lib64/libc-2.17.so)
==1350634==Address 0x115d95a4 is on thread 14's stack
==1350634==in frame #4, created by FileGwRedisWorkItem::update_file_xattr_status(gateway_file_status) (redis_work_item.cc:697)
==1350634== Thread 19:
==1350634== Conditional jump or move depends on uninitialised value(s)
==1350634==at 0x465155: FileGwRedisWorkItem::callback(void*) (redis_work_item.cc:946)
==1350634==by 0x481021: FileGwS3WorkItem::postProcess() (s3_work_item.cc:244)
==1350634==by 0x486551: WorkThread::process_work_item() (work_thread.cc:50)
==1350634==by 0x48666E: WorkThread::entry() (work_thread.cc:78)
==1350634==by 0x481B58: Thread::_entry_func(void*) (thread.cc:74)
==1350634==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1350634==by 0x6D9FCEC: clone (in /usr/lib64/libc-2.17.so)
Invalid read/write

读取非法地址,通常是继续访问释放后的内存空间


==1346085== Thread 14:
==1346085== Invalid read of size 4
==1346085==at 0x4E40BB0: pthread_mutex_unlock (in /usr/lib64/libpthread-2.17.so)
==1346085==by 0x4559FC: __gthread_mutex_unlock(pthread_mutex_t*) (gthr-default.h:778)
==1346085==by 0x45B6C1: std::mutex::unlock() (mutex:152)
==1346085==by 0x489CA8: std::lock_guard<std::mutex>::~lock_guard() (mutex:420)
==1346085==by 0x4895BB: WorkItemCompletion::finish() (thread_work_item.cc:47)
==1346085==by 0x48971E: ThreadWorkItem::postProcess() (thread_work_item.cc:70)
==1346085==by 0x45F721: RedisWorkItem::postProcess() (redis_work_item.cc:139)
==1346085==by 0x45FFED: FileGwRedisWorkItem::postProcess() (redis_work_item.cc:234)
==1346085==by 0x486761: WorkThread::process_work_item() (work_thread.cc:50)
==1346085==by 0x486A60: ShardedWorkThread::entry() (work_thread.cc:112)
==1346085==by 0x481D68: Thread::_entry_func(void*) (thread.cc:74)
==1346085==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1346085==Address 0xabd3788 is 24 bytes inside a block of size 88 free'd
==1346085==at 0x4C2B1CD: operator delete(void*) (vg_replace_malloc.c:576)
==1346085==by 0x489253: WorkItemCompletion::~WorkItemCompletion() (thread_work_item.cc:29)
==1346085==by 0x4572E4: FileGateway::issue_filegw_redis_workitem(FileOp*, FileInfo*, bool, bool, void (*)(void*), void*) (file_gateway.cc:298)
==1346085==by 0x457D31: FileGateway::do_read(FileOp*) (file_gateway.cc:455)
==1346085==by 0x455298: GatewayWorkItem::process() (gateway_work_item.cc:74)
==1346085==by 0x486742: WorkThread::process_work_item() (work_thread.cc:49)
==1346085==by 0x48687E: WorkThread::entry() (work_thread.cc:78)
==1346085==by 0x481D68: Thread::_entry_func(void*) (thread.cc:74)
==1346085==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1346085==by 0x6D9FCEC: clone (in /usr/lib64/libc-2.17.so)
==1346085==Block was alloc'd at
==1346085==at 0x4C2A243: operator new(unsigned long) (vg_replace_malloc.c:334)
==1346085==by 0x457171: FileGateway::issue_filegw_redis_workitem(FileOp*, FileInfo*, bool, bool, void (*)(void*), void*) (file_gateway.cc:286)
==1346085==by 0x457D31: FileGateway::do_read(FileOp*) (file_gateway.cc:455)
==1346085==by 0x455298: GatewayWorkItem::process() (gateway_work_item.cc:74)
==1346085==by 0x486742: WorkThread::process_work_item() (work_thread.cc:49)
==1346085==by 0x48687E: WorkThread::entry() (work_thread.cc:78)
==1346085==by 0x481D68: Thread::_entry_func(void*) (thread.cc:74)
==1346085==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1346085==by 0x6D9FCEC: clone (in /usr/lib64/libc-2.17.so)
SUMMARY


在valgrind
最后会有内存分析的总结


==1366931== HEAP SUMMARY:
==1366931== in use at exit: 41,110 bytes in 1,019 blocks
==1366931== total heap usage: 1,275,222 allocs, 1,274,203 frees, 334,495,820 bytes allocated
==1366931==
==1366931== LEAK SUMMARY:
==1366931==definitely lost: 11,632 bytes in 191 blocks
==1366931==indirectly lost: 80 bytes in 2 blocks
==1366931==possibly lost: 608 bytes in 1 blocks
==1366931==still reachable: 28,790 bytes in 825 blocks
==1366931== of which reachable via heuristic:
==1366931== stdstring: 145 bytes in 4 blocks
==1366931== suppressed: 0 bytes in 0 blocks
==1366931== Rerun with --leak-check=full to see details of leaked memory
==1366931==
==1366931== For counts of detected and suppressed errors, rerun with: -v
==1366931== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)


LEAK SUMMARY
:内存泄露信息的总结,详细信息从前面的log中查找


definitely lost
: 肯定丢失的内存,这部分必须处理
indirectly lost
: 间接丢失的内存,可能是一个structure
里指向的内存
possibly lost
: 可能丢失的部分,这是由于C/C++语言指针处理的特点造成的,可能不太准确
still reachable
: 程序可能是ok的,可以配置--show-reachable=no
不显示这部分


若想显示泄露内存的详细信息,使用参数--leak-check=full



/usr/local/bin/valgrind --leak-check=full --log-file=mylog ./flle-gateway


==1373210== HEAP SUMMARY:
==1373210== in use at exit: 30,758 bytes in 843 blocks
==1373210== total heap usage: 405,641 allocs, 404,798 frees, 44,538,821 bytes allocated
==1373210==
==1373210== 608 bytes in 1 blocks are possibly lost in loss record 605 of 613
==1373210==at 0x4C2B9B5: calloc (vg_replace_malloc.c:711)
==1373210==by 0x4011DE4: _dl_allocate_tls (in /usr/lib64/ld-2.17.so)
==1373210==by 0x4E3E960: [email protected]@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
==1373210==by 0x489969: libsgsvc_init (in /home/yangguanjun3/storage-file-gateway/userspace/build/storage-flle-gw)
==1373210==by 0x456B06: FileGateway::init_netlink() (file_gateway.cc:218)
==1373210==by 0x456CA4: FileGateway::init() (file_gateway.cc:234)
==1373210==by 0x4537A2: main (main.cc:79)
==1373210==
==1373210== 1,360 bytes in 17 blocks are definitely lost in loss record 611 of 613
==1373210==at 0x4C29C23: malloc (vg_replace_malloc.c:299)
==1373210==by 0x4785C7: Aws::Utils::Stream::PreallocatedStreamBuf* Aws::New<Aws::Utils::Stream::PreallocatedStreamBuf, Aws::Utils::Array<unsigned char>*, unsigned long>(char const*, Aws::Utils::Array<unsigned char>*&&, unsigned long&&) (AWSMemory.h:70)
==1373210==by 0x473446: S3BackendStorage::put_object_from_file_slice(std::basic_string<char, std::char_traits<char>, Aws::Allocator<char> >, std::basic_string<char, std::char_traits<char>, Aws::Allocator<char> >, std::string const&, unsigned long, unsigned long) (s3_storage.cc:294)
==1373210==by 0x480110: FileGwS3WorkItem::file_upload() (s3_work_item.cc:147)
==1373210==by 0x480C0D: FileGwS3WorkItem::process() (s3_work_item.cc:221)
==1373210==by 0x486316: WorkThread::process_work_item() (work_thread.cc:49)
==1373210==by 0x486452: WorkThread::entry() (work_thread.cc:78)
==1373210==by 0x48193C: Thread::_entry_func(void*) (thread.cc:74)
==1373210==by 0x4E3DDC4: start_thread (in /usr/lib64/libpthread-2.17.so)
==1373210==by 0x6D9FCEC: clone (in /usr/lib64/libc-2.17.so)
==1373210==
==1373210== LEAK SUMMARY:
==1373210==definitely lost: 1,360 bytes in 17 blocks
==1373210==indirectly lost: 0 bytes in 0 blocks
==1373210==possibly lost: 608 bytes in 1 blocks
==1373210==still reachable: 28,790 bytes in 825 blocks
==1373210== of which reachable via heuristic:
==1373210== stdstring: 145 bytes in 4 blocks
==1373210== suppressed: 0 bytes in 0 blocks
==1373210== Reachable blocks (those to which a pointer was found) are not shown.
==1373210== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==1373210==
==1373210== For counts of detected and suppressed errors, rerun with: -v
==1373210== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
参考


http://valgrind.org/docs/manual/manual.html



http://www.oschina.net/translate/valgrind-memcheck


https://www.ibm.com/developerworks/cn/linux/l-cn-valgrind/

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台