我继承了大量遗留代码。直到现在,它一直工作得很好。突然在我无法在内部复制的客户试用中,它在malloc中崩溃了。我认为我需要添加仪器,例如在malloc之上,我有我自己的malloc,它存储了关于每个malloc的一些元信息,例如谁进行了malloc调用。当它崩溃时,我可以查看元信息,看看发生了什么。几年前我也做过类似的事情,但现在想不起来了……我相信人们已经想出了更好的主意。如有任何意见,我将很高兴。
谢谢
内存分配是否中断?
valgrind试试。
Malloc仍在崩溃。
好吧,我将不得不假设你的意思是SIGSEGV
(分割故障)在malloc
中触发。这通常是由堆损坏引起的。堆损坏本身不会导致分段错误,它通常是数组访问超出数组边界的结果。这通常离调用malloc
的点很远。
malloc
在"前面存储了一个小的信息头"它返回给你的记忆块。该信息通常包含块的大小和指向下一个块的指针。不用说,更改其中任何一个都将导致问题。通常,下一个块指针被更改为无效地址,并且下次调用malloc
时,它最终解引用坏指针和分段错误。或者它不这样做,并开始将随机内存解释为堆的一部分。最终它的运气耗尽了。
请注意,如果正在释放的块或空闲块列表混乱,free
也会发生同样的事情。
如何捕获这种错误完全取决于您如何访问malloc
返回的内存。单个struct
的malloc
通常不是问题;通常是数组的malloc
。使用负(-1或-2)索引通常会为您提供当前块的块头,并且索引超过数组末尾可以为您提供下一个块的头。两者都是有效的内存位置,因此不会出现分段错误。
首先要做的是范围检查。你提到这出现在客户的网站上;也许是因为他们正在处理的数据集要大得多,或者输入数据损坏(例如,它说分配100个元素,然后初始化101个),或者他们以不同的顺序执行事情(这隐藏了内部测试中的错误),或者做一些你没有测试过的事情。没有更多的细节很难说。您应该考虑编写一些程序来检查输入数据的完整性。
Try Asan
AddressSanitizer(又名ASan)是C/c++的内存错误检测器。它发现:
Use after free (dangling pointer dereference)
Heap buffer overflow
Stack buffer overflow
Global buffer overflow
Use after return
Use after scope
Initialization order bugs
Memory leaks
请找到链接了解更多和如何使用
https://github.com/google/sanitizers/wiki/AddressSanitizer和https://github.com/google/sanitizers/wiki/AddressSanitizerFlags
我知道这是旧的,但这样的问题将继续存在,只要我们有指针。尽管valgrind
是用于此目的的最佳工具,但它有一个陡峭的学习曲线,并且通常结果太吓人而难以理解。
假设您正在使用一些*nux,我可以建议的另一个工具是electricfence
。引言:
Electric Fence帮助您检测两个常见的编程错误:
software that overruns the boundaries of a malloc() memory allocation,
software that touches a memory allocation that has been released by free().
Unlike other malloc() debuggers, Electric Fence will detect read accesses
as well as writes, and it will pinpoint the exact instruction that causes
an error.
用法非常简单。只需将代码与附加库lefence
链接即可当您运行应用程序时,当内存损坏时,将生成一个corefile ,而不是当使用损坏的内存时。