由于内存泄漏导致崩溃(但它是7层深处,它只是遍布链表 - 没有分配)。
它几乎每天都可以重现,所以我总能获得一个新的核心文件。我花了最近3-5天来讨论代码,配对分配/解除分配,但似乎无法找到导致它的地方,因为遗留的C应用程序非常庞大,并且它到处都是memcpy / alloc / calloc。坦率地说,可能需要一个错误的memcpy。
我经历了在本地编译Valgrind的努力,期待在它开始时得到一些很好的跟踪,但是Valgrind只是让机器无法运行,例如它必须手动重新启动服务器机房,因为甚至不能使用ssh。由于Valgrind,我们基本上失去了两天的调试,所以我不能第三次使用它(除非Memcheck能以某种方式使用核心文件,或许?)
是否有其他工具可以帮助我分析内核泄漏的核心文件?使用print命令的gdb并不完全有用。
更具体地说,一些核心文件真的很大--1.5GB(虽然它们不应该超过0.3GB),所以我希望得到一个占据大部分内存的前2-3名罪犯的列表(这会给我直接暗示下一步的样子。
有什么想法吗?
哦,至于稳定性 - 它可以正常处理大约一百万(左右)的数据请求,然后崩溃(有时几百万),所以只需在通常崩溃的地方放置一个断点即可。问题。
答案 0 :(得分:1)
我尝试创建一组测试输入,使系统启动,运行多个事务,然后以受控(即应该清理的一切)方式将其关闭。在valgrind下运行那个小套件,它至少应该给你追逐的东西。如果它是一个较旧的系统,你可能会有误报追逐。如果到那时你还没有找到它,你将需要进行更多样化的测试。
BTW,在运行较小的测试时,您可以限制进程大小(ulimit / limit)以避免大量内存映像和相关的系统稳定性问题。答案 1 :(得分:0)
我认为你混淆了内存泄漏和内存损坏。
如果您有内存泄漏,最终对malloc()
的调用应该返回NULL,并且您的程序应该有代码来检测并记录它。不幸的是,malloc()
更有可能成功,但是使用内存将导致操作系统OOM杀死您的进程,这更难以调试。哦,好吧。
如果您有内存损坏(可能通过memcpy()
,这不会导致内存泄漏),对任何C内存分配例程的调用可能会导致C库检测到堆损坏并自杀您的应用程序。这应该带有诊断,如“检测到堆损坏/下一个块大小无效”或类似。
内存泄漏的内存损坏的好处是,越界读/写是一个明确的错误,而泄漏的内存可能更微妙。
如果valgrind太慢,则可以使用AddressSanitizer
来查找内存损坏,{{1}}的开销要低得多。
答案 2 :(得分:0)
由于核心文件包含进程的原始内存转储(嵌入在ELF数据结构中,您在此处几乎可以忽略),您可以查看核心文件中的大部分数据,以及注意重复模式和熟悉的数据(如字符串)。这在https://stackoverflow.com/a/8714719/2148773中很好地描述了。