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