检测出口处释放的C内存“泄漏” [英] Detect C memory 'leaks' that are freed on exit

查看:174
本文介绍了检测出口处释放的C内存“泄漏”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个C程序(在Linux下运行),它处理许多数据结构,一些复杂的数个结构可以增长和缩小,但通常不会随着时间的推移而增长。随着时间的推移,程序被观察到RSS逐渐增加(比内存碎片可以解释更多)。我想找出什么在泄漏。在 valgrind 下运行是一个明显的建议,但 valgrind (带 - leak-check =完整 - show-reachables = yes )显示没有泄漏。我相信这是因为数据结构本身在退出时正确地被释放,但其中一个在程序生命周期中正在增长。例如,可能有一个链接列表随着时间的推移正在线性增长,有人忘记删除列表上的资源,但退出清理正确地释放了退出时列表上的所有项目。有一个哲学问题,当它们被释放时它们是否实际上是泄漏,当然是(因此问题中的引号)。



有没有有用的工具来衡量这一点?我最喜欢的是能够在 valgrind 下运行,并使其产生一个当前分配的报告,就像它在退出时一样,但要在一个信号上发生这种情况让程序继续。



我可以可靠地从 gdb中获得一个漂亮的大型'核心'文件加上 generate-core-file ;有没有办法来分析离线,如果说我编写了一个方便的 malloc()调试库来检测 malloc()

我可以完全访问源代码,并且可以对其进行修改,但我不想手动测试每个数据结构,而且我对这个问题的一般解决方案感兴趣(例如 valgrind ),而不是如何解决这个问题。



<我已经在这里寻找类似的问题,但他们似乎都是:




  • 为什么我的程序泄漏内存?
  • >
  • 如何检测退出时的内存泄漏? (对我没有用处)

  • 如何从核心文件中检测内存泄漏? (很好,但没有一个满意的答案)



如果我在Solaris下运行,我猜测答案是'use this方便 dtrace 脚本'。

解决方案

Valgrind包含一个gdbserver。这基本上意味着你可以使用gdb来连接它,例如发出泄漏转储,或在运行时显示所有可访问的内存。当然,您必须判断是否存在内存泄漏,因为valgrind无法知道应用程序逻辑中是否存在未能释放内存的错误,但仍然保留引用。



使用--vgdb = yes标志运行valgrind,然后运行命令:

  valgrind --vgdb = yes --leak-check = full --show-reachable = yes ./yourprogram 
gdb ./yourprogram
(gdb)target remote | vgdb
(gdb)monitor leak_check完全可达任何

请参阅文档以获取更多信息, a href =http://valgrind.org/docs/manual/mc-manual.html>这里和这里



您也可以这样做在程序中以编程方式

  #include   

并在代码中的适当位置执行:

  VALGRIND_DO_LEAK_CHECK; 

(iirc会显示可达内存,只要valgrind使用--show-可达性=是

Assume I have a C program (running under Linux) which manipulates many data structures, some complex, several of which can grow and shrink but should not in general grow over time. The program is observed to have a gradually increasing RSS over time (more so than can be explained by memory fragmentation). I want to find what is leaking. Running under valgrind is the obvious suggestion here, but valgrind (with --leak-check=full and --show-reachables=yes) shows no leak. I believe this to be because the data structures themselves are correctly being freed on exit, but one of them is growing during the life of the program. For instance, there might be a linked list which is growing linearly over time, with someone forgetting to remove the resource on the list, but the exit cleanup correctly freeing all the items on the list at exit. There is a philosophical question as to whether these are in fact 'leaks' if they are freed, of course (hence the quote marks in the question).

Are there any useful tools to instrument this? What I'd love is the ability to run under valgrind and have it produce a report of current allocations just as it does on exit, but to have this happen on a signal and allow the program to continue. I could then look for what stack trace signatures had growing allocations against them.

I can reliably get a nice large 'core' file from gdb with generate-core-file; is there some way to analyse that off-line, if say I compiled with a handy malloc() debugging library that instrumented malloc()?

I have full access to the source, and can modify it, but I don't really want to instrument every data structure manually, and moreover I'm interested in a general solution to the problem (like valgrind provides) rather than how to address this particular issue.

I've looked for similar questions on here but they appear all to be:

  • Why does my program leak memory?
  • How do I detect memory leaks at exit? (no use for me)
  • How do I detect memory leaks from a core file? (great, but none has a satisfactory answer)

If I was running under Solaris I'm guessing the answer would be 'use this handy dtrace script'.

解决方案

Valgrind includes a gdbserver. This basically means you can use gdb to connect to it, and e.g. issue a leak dump, or to show all reachable memory while running. Ofcourse, you have to judge whether there is a "memory leak" or not, as valgrind can't know if there's a bug in the application logic that fails to release memory, but still keep references to it.

Run valgrind with the --vgdb=yes flag and then run the commands:

valgrind --vgdb=yes --leak-check=full --show-reachable=yes ./yourprogram 
gdb ./yourprogram
(gdb) target remote | vgdb
(gdb) monitor leak_check full reachable any

See the docs for more info, here and here

You can also do this programatically in your program

#include <valgrind/memcheck.h>

and at an appropriate place in the code do:

 VALGRIND_DO_LEAK_CHECK;

(iirc that'll show reachable memory too, as long as valgrind is run with --show-reachable=yes

这篇关于检测出口处释放的C内存“泄漏”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆