valgrind 做常态内存泄露的检查

本文详细介绍了Valgrind这一强大的内存检测工具,包括如何下载安装、基本使用方法及常见参数配置。通过实例演示了如何查找内存泄漏、检查代码覆盖率和性能分析,并提供了深入解读错误报告的方法。
valgrind是检测内存泄露的比较好的开源项目:
http://valgrind.org/docs/download_docs.html,这是其官方帮助文档,比较全面


另外有个网友写的博文介绍如何使用valgrind,不错,大家可以参考:
http://blog.youkuaiyun.com/zhoujunyi/archive/2007/09/11/1780749.aspx


应该把内存泄露的检测做一个常态的工作,比如说GNOME Power Manager这个开源项目
就是把valgrind作为一个常态检测工具,写了一个脚本:
valrind_gpm.sh


内容如下:
killall gnome-power-manager
export G_SLICE=always-malloc
export G_DEBUG=gc-friendly
valgrind --tool=memcheck --leak-check=full --leak-resolution=high ./gnome-power-manager --verbose --no-daemon --timed-exit &> ./debug-valgrind.log


这样就可以在代码编译完成后,及时的运行以下valgrind_gpm.sh这个脚本,即时的检查
程序修改后的内存异常问题,才能达到及时发现问题,解决问题。程序会越来越稳定。

这很值得我们借鉴,内存检测做到平时,才能解决光吃不吐,消化不良的问题。


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

The Valgrind tool suite provides a number of debugging and profiling tools. The most popular is Memcheck, a memory checking tool which can detect many common memory errors such as:

• Touching memory you shouldn’t (eg. overrunning heap block boundaries, or reading/writing freed memory).

• Using values before they have been initialized.

• Incorrect freeing of memory, such as double-freeing heap blocks.

• Memory leaks.

Where to download

Valgrind do not distribute binaries or RPMs, The releases available on this website contain the source code and have to be compiled in order to be installed on your system. Many Linux distributions come with valgrind these days, so if you do not want to compile your own, go to your distribution's download site.

You can download Valgrind from its official website:  http://valgrind.org/downloads/valgrind-3.3.0.tar.bz2

How to use Valgrind

How to Check Memory leak

For example, if you want to check “appxxx” memory leak, you can use this command as below:

#valgrind --leak-check=full --show-reachable=yes --trace-children= yes /usr/sbin/appxxx 2>logfile

• “--leak-check=full” for the full memory leak check.

• “--show-reachable=yes” for display memory leak address.

• “--trace-children=yes” for follow child processes.

• “2>logfile” will print stderr to logfile.

If the program is a normal process and it could exit after execute, then valgrind will print the memory leak messages automatic after it exit. If the program is a daemon. (like appxxx), you should kill the press manually. (Because valgrind use memcheck tool by default.)

#killall memcheck

Then the program (appxxx) will be killed.

Check codes cover and performance

You can execute program via valgrind:

#valgrind --tool=callgrind /usr/sbin/appxxx

It should generate callgrind.out.pid in current directory. (current generate is callgrind.out.30866). if you want to exit, you should:

#killall callgrind

Then you can check results with:

#callgrind_annotate --auto=yes callgrind.out.30866 > log

#vim log

How to finger out Memory leak

Check report, here is a LEAK SUMMARY at the end of logfile.

==27406== LEAK SUMMARY:

==27406==    definitely lost: 0 bytes in 0 blocks.

==27406==      possibly lost: 19,668 bytes in 16 blocks.

==27406==    still reachable: 63,099 bytes in 2,406 blocks.

==27406==         suppressed: 0 bytes in 0 blocks.

There are several kinds of leaks; the two most important categories are:

• "definitely lost": your program is leaking memory -- fix it!

• "probably lost": your program is leaking memory, unless you’re doing funny things with pointers (such as moving

them to point to the middle of a heap block).

Most error messages look like the following, which describes problem 1, the heap block overrun:

==19182== Invalid write of size 4

==19182== at 0x804838F: f (example.c:6)

==19182== by 0x80483AB: main (example.c:11)

==19182== Address 0x1BA45050 is 0 bytes after a block of size 40 allocd

==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)

==19182== by 0x8048385: f (example.c:5)

==19182== by 0x80483AB: main (example.c:11)

Things to notice:

• There is a lot of information in each error message; read it carefully.

• The 19182 is the process ID; it’s usually unimportant.

• The first line ("Invalid write...") tells you what kind of error it is. Here, the program wrote to some memory it

should not have due to a heap block overrun.

• Below the first line is a stack trace telling you where the problem occurred. Stack traces can get quite large, and

be confusing, especially if you are using the C++ STL. Reading them from the bottom up can help. If the stack  trace is not big enough, use the --num-callers option to make it bigger.

• The code addresses (eg. 0x804838F) are usually unimportant, but occasionally crucial for tracking down weirder bugs.

• Some error messages have a second component which describes the memory address involved. This one shows that the written memory is just past the end of a block allocated with malloc() on line 5 of example.c. It’s worth fixing errors in the order they are reported, as later errors can be caused by earlier errors. Failing to do this is a common cause of difficulty with Memcheck.

Memory leak messages look like this:

==19182== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1

==19182== at 0x1B8FF5CD: malloc (vg_replace_malloc.c:130)

==19182== by 0x8048385: f (a.c:5)

==19182== by 0x80483AB: main (a.c:11)

The stack trace tells you where the leaked memory was allocated. Memcheck cannot tell you why the memory leaked,  unfortunately. (Ignore the "vg_replace_malloc.c", that’s an implementation detail.)

Note: Because of valgrind's design, valgrind can't analysis C++ STL correctly and programs contains STL may got "probably lost" like below. Normally, we can set it as low Priority. Details please refer Valgrind manual document page-126.(4. Valgrind behaves unexpectedly)

==27406== 18,848 bytes in 9 blocks are possibly lost in loss record 27 of 28

==27406==    at 0x401AD55: operator new(unsigned) (vg_replace_malloc.c:224)

==27406==    by 0x466B00C: std::__default_alloc_template<true, 0>::_S_refill(unsigned)

 (in /usr/share/xxxxx/lib/libstdc++.so.5.0.3)

==27406==    by 0x466AB7B: std::__default_alloc_template<true, 0>::allocate(unsigned)

(in /usr/share/xxxxx/lib/libstdc++.so.5.0.3)

==27406==    by 0x4670B77: std::string::_Rep::_S_create(unsigned, std::allocator<char>

 const&) (in /usr/share/xxxxx/lib/libstdc++.so.5.0.3)

==27406==    by 0x46719B4: (within /usr/share/xxxxx/lib/libstdc++.so.5.0.3)

==27406==    by 0x466DC43: std::string::string(char const*, std::allocator<char> const

&) (in /usr/share/xxxxx/lib/libstdc++.so.5.0.3)

==27406==    by 0x8090CB7: __static_initialization_and_destruction_0(int, int) (in /us

r/sbin/appxxx)

==27406==    by 0x8097015: _GLOBAL__I_MAIN_RUN_QUEUE (in /usr/sbin/appxxx)

==27406==    by 0x80A6D54: (within /usr/sbin/appxxx)

==27406==    by 0x804CAE0: (within /usr/sbin/appxxx)

==27406==    by 0x80A6CE1: __libc_csu_init (in /usr/sbin/appxxx)

References

Valgrind still have other useful tools like: “cachegrind” for cache check; “helgrind” to check multithreading, etc.  You could set param by default properties in ~/.valgrindrc.

For more options, please refer:  http://www.valgrind.org/docs/manual/manual-core.html  http://valgrind.org/docs/manual/valgrind_manual.pdf


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值