C 你能用gdb(或其他工具)从核心文件中找到内存泄漏吗?

C 你能用gdb(或其他工具)从核心文件中找到内存泄漏吗?,c,linux,memory-leaks,gdb,valgrind,C,Linux,Memory Leaks,Gdb,Valgrind,由于内存泄漏,我遇到了一个崩溃(但它在7层的深处,只在链接列表上移动-没有分配)。 它是相当可复制的,几乎每天都有,所以我总能得到一个新的核心文件。我花了3-5天的时间研究代码,将分配/取消分配配对,但似乎找不到导致它的地方,因为遗留C应用程序非常庞大,到处都是memcpy/alloc/calloc。坦率地说,一个错误的记忆就是一切 我在本地编译了Valgrind,希望从它开始的地方得到一些很好的跟踪,但Valgrind只是使机器无法运行,例如,它必须在服务器室手动重新启动,因为即使是ssh也不

由于内存泄漏,我遇到了一个崩溃(但它在7层的深处,只在链接列表上移动-没有分配)。
它是相当可复制的,几乎每天都有,所以我总能得到一个新的核心文件。我花了3-5天的时间研究代码,将分配/取消分配配对,但似乎找不到导致它的地方,因为遗留C应用程序非常庞大,到处都是memcpy/alloc/calloc。坦率地说,一个错误的记忆就是一切

我在本地编译了Valgrind,希望从它开始的地方得到一些很好的跟踪,但Valgrind只是使机器无法运行,例如,它必须在服务器室手动重新启动,因为即使是ssh也不能使用。由于Valgrind,我们基本上失去了两天的调试时间,所以我不能第三次使用它(除非Memcheck能够以某种方式处理核心文件,也许?)

是否有其他工具可以帮助我分析核心文件中的内存泄漏?带有print命令的gdb并不完全有用

更具体地说,一些核心文件非常庞大—1.5GB(而它们不应该超过0.3GB),因此我希望得到一份占据大部分内存的前2-3个违规者的列表(这将直接提示我下一步应该在哪里查找)

有什么想法吗


哦,至于稳定性——在崩溃之前,它可以正确地处理大约一百万(或更多)的数据请求(有时是几百万),所以在通常崩溃的地方设置一个断点是不可能的。

我会尝试创建一个输入测试集来启动系统,运行大量事务,然后以受控(即,所有东西都应该清理)的方式将其放下。在valgrind管理那间小套房,它至少会给你一些东西去追逐。如果它是一个旧的系统,你很可能有误报追踪。如果到那时你还没有找到它,你将需要提出更多不同的测试

顺便说一句,在运行较小的测试时,您可以限制进程大小(ulimit/limit),以避免大量内存映像和相关的系统稳定性问题。

我认为您将内存泄漏和内存损坏混为一谈。

如果您有内存泄漏,对
malloc()
的调用最终应该返回NULL,并且您的程序应该有代码来检测并记录它。不幸的是,
malloc()。哦,好吧

如果内存损坏(可能通过
memcpy()
,这不会导致内存泄漏),调用任何C内存分配例程都可能导致C库检测到堆损坏并终止应用程序。这应该带有类似“检测到堆损坏/下一个块大小无效”或类似的诊断

与内存泄漏相比,内存损坏的优势在于,越界读/写显然是一个bug,而内存泄漏可能更微妙。

如果valgrind速度太慢,可以使用开销低得多的
AddressSanitizer
来发现内存损坏。

由于核心文件包含进程的原始内存转储(嵌入ELF数据结构中,您可以在此处忽略),您可能可以查看核心文件中的大部分数据,还要注意重复的模式和熟悉的数据(如字符串)。这在中描述得非常好。

获取生产来源,返回测试站点,在valgrind下运行buggy部件,并模拟您的流量,直到它崩溃。对不起,没有其他建议。同时,在重新启动生产系统时,有一个固定的基础知道如何让系统保持稳定。1+对于“您可以限制您的流程大小”,创建导致崩溃的输入集的问题是实时输入是外部的。理论上,有一个硬件层可以承载一个自定义进程,它会在我们的进程中抛出一百万条记录,但如果我们能够做到的话,可能只需要几天就可以启动并运行它。我不是说你必须复制崩溃。只需创建一组测试输入,看看是否有泄漏。如果时间是一个问题,这确实使它更难。然而,你面前还有一段艰难的道路。ulimit/limit可以用来避免Valgrind导致机器停机的情况吗?我刚收到一封电子邮件,说对那台机器的访问受到严重限制(比去服务器室按按钮要复杂得多)。这实际上可能迫使我们尝试模拟将数据推向后端的层。如果我们这样做了,我们可以使用大量其他机器中的任何一台,如果Valgrind将其关闭,这些机器都可以轻松重启。这台机器很可能会颠簸——可用ram的活动内存空间太大。使用ulimit限制进程大小会导致进程在耗尽ram之前崩溃。不过只是一个猜测——我对情况了解得还不够。我不认为我把这两者混在了一起——但编写的代码在没有任何检查的情况下到处都有大量内存,因此完全有可能泄漏和腐败同时发生。我从来没有听说过AddressSanitizer,所以我要看看它——非常感谢你的提示!Valgrind,在那台10年以上的旧服务器上,正在使机器停机,因此它对我来说毫无用处,除非有人知道如何确保它不会使机器停机,因为机器重启实际上是不可访问的(如上所述)。