malloc() 和 malloc_consolidate() 中的段错误
Posted
技术标签:
【中文标题】malloc() 和 malloc_consolidate() 中的段错误【英文标题】:Segfaults in malloc() and malloc_consolidate() 【发布时间】:2011-03-07 05:23:12 【问题描述】:当我查看 gdb 中的回溯时,我的应用程序有时会出现段错误,主要出现在 malloc() 和 malloc_consolidate() 中。
我确认机器有足够的可用内存,它甚至没有开始交换。 我检查了 ulimits 的数据段和最大内存大小,两者都设置为“无限制”。 我还在 valgrind 下运行了应用程序,没有发现任何内存错误。
现在我不知道还有什么可能导致这些段错误。有什么想法吗?
更新: 由于我没有找到任何使用 valgrind(或 ptrcheck)的东西,可能是另一个应用程序正在破坏 libc 的内存结构,还是每个进程都有一个单独的结构?
【问题讨论】:
你有没有在 valgrind 下崩溃过? 不,它没有崩溃。它是一个实时应用程序,在 valgrind 下我只能对其施加非常轻的负载,而它通常只会在较重的负载下崩溃。 这是哪个操作系统?从工具链来看,听起来可能是Linux。在这种情况下,不,其他应用程序不能丢弃您的堆;这是你的应用程序中的东西。如果这只发生在负载下,那当然会变得更加棘手……负载下有什么不同?这怎么会导致您丢弃堆?在 Valgrind 下运行时,尽可能地尝试“折磨”您的应用程序……您如何才能最好地重现负载下存在的条件?也许是无偿分配内存之类的? 【参考方案1】:来自http://www.gnu.org/s/libc/manual/html_node/Heap-Consistency-Checking.html#Heap-Consistency-Checking:
另一种检查和防范使用中的错误的可能性 malloc、realloc和free是设置环境变量 MALLOC_CHECK_。当 MALLOC_CHECK_ 被设置时,一个特殊的(效率较低的) 使用的实现被设计为容忍简单的 错误,例如使用相同参数的两次 free 调用,或 单个字节的溢出(一个错误)。并非所有此类错误都可以 但是,受到保护,可能会导致内存泄漏。如果 MALLOC_CHECK_ 设置为 0,任何检测到的堆损坏都是静默的 忽略;如果设置为 1,则在 stderr 上打印诊断信息;如果设置为 2, 立即调用中止。这可能很有用,因为否则 崩溃可能会在很久以后发生,问题的真正原因是 然后很难追踪。
【讨论】:
【参考方案2】:很可能,您正在破坏堆 - 即,您正在写入超出您分配的一块内存的限制,这会覆盖 malloc()
用于管理堆的数据结构。这会导致malloc()
访问无效地址,并且您的应用程序崩溃。
内存不足不会导致malloc()
崩溃——它只会返回NULL
。如果您不检查NULL
,这可能会导致您的代码崩溃,但崩溃站点不会位于malloc()
。
Valgrind 没有报告任何错误有点奇怪——但是默认的“Memcheck”工具可能会漏掉一些错误。尝试使用 "Ptrcheck" tool 运行 Valgrid。
【讨论】:
但这不应该出现在 valgrind 下吗? (假设我的测试覆盖率足够好。) 您的评论似乎与我的编辑重叠——正如那里所建议的,尝试使用“Ptrcheck”工具运行 Valgrind。如果 malloc() 崩溃了,几乎可以肯定你正在以某种方式破坏堆。 自 Valgrind 3.7.0 版(2011 年 11 月 5 日)起,exp-ptrcheck 工具已被重命名并缩减了功能以检查堆栈溢出和全局数组。它现在称为 exp-sgcheck(“堆栈和全局数组检查”)。 link以上是关于malloc() 和 malloc_consolidate() 中的段错误的主要内容,如果未能解决你的问题,请参考以下文章
C语言中已经有了malloc和free,为啥还需要new和delete?