简体   繁体   English

检测退出时释放的C内存“泄漏”

[英]Detect C memory 'leaks' that are freed on exit

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. 假设我有一个C程序(在Linux下运行),它操作许多数据结构,一些复杂,其中一些可以增长和缩小,但通常不会随着时间的推移而增长。 The program is observed to have a gradually increasing RSS over time (more so than can be explained by memory fragmentation). 观察到该程序随着时间的推移逐渐增加RSS(比可以通过内存碎片解释的更多)。 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. valgrind下运行是一个明显的建议,但是valgrind (使用--leak-check=full--show-reachables=yes )显示没有泄漏。 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. 我喜欢的是能够在valgrind下运行并让它产生当前分配的报告,就像它在退出时一样,但要在信号上发生这种情况并允许程序继续。 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 ; 我可以通过generate-core-filegdb可靠地获得一个漂亮的大型“核心” 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() ? 有没有办法分析离线,如果说我用一个方便的malloc()调试库编译了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. 我有完全访问源,可以修改它,但我真的不想手动检测每个数据结构,而且我对问题的一般解决方案感兴趣(如valgrind提供)而不是如何解决这个特殊问题。

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'. 如果我在Solaris下运行,我猜测答案是“使用这个方便的dtrace脚本”。

Valgrind includes a gdbserver. Valgrind包含一个gdbserver。 This basically means you can use gdb to connect to it, and eg issue a leak dump, or to show all reachable memory while running. 这基本上意味着您可以使用gdb连接到它,例如发出泄漏转储,或者在运行时显示所有可访问的内存。 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. 当然,你必须判断是否存在“内存泄漏”,因为valgrind无法知道应用程序逻辑中是否存在无法释放内存的错误,但仍然保留对它的引用。

Run valgrind with the --vgdb=yes flag and then run the commands: 使用--vgdb = yes标志运行valgrind,然后运行命令:

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 (只要valgrind与--show-reachable = yes一起运行,iirc也会显示可达内存

There's the Valgrind Massif tool which shows general memory usage of your application, not just for leaked memory. Valgrind Massif工具显示了应用程序的一般内存使用情况,而不仅仅是泄漏的内存。 It breaks down malloc() s and free() s by calling functions and their backtraces, so you can see which functions keep allocating memory without releasing it. 它通过调用函数及其回溯来分解malloc()free() ,因此您可以看到哪些函数在不释放内存的情况下继续分配内存。 This can be an excellent tool for finding leaks of the type you mentioned. 这可以成为查找您提到的类型泄漏的绝佳工具。

Unfortunately the tooling around Massif is a bit weird... The ms_print tool provided with Valgrind is only useful for the most basic tasks; 不幸的是,围绕Massif的工具ms_print ...... Valgrind提供的ms_print工具仅对最基本的任务有用; for real work you probably want something that displays a graph. 对于实际工作,你可能想要一些显示图形的东西。 There are several tools for this strewn around the net - see eg. 网上散布着几种工具 - 参见例如。 Valgrind Massif tool output graphical interface? Valgrind Massif工具输出图形界面? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM