问题
我编写了一个php扩展(PHP5.3),它在简单的测试中似乎运行良好,但是当我开始多次调用它时,我开始看到错误:
zend_mm_heap腐蚀
通常通过控制台或apache错误日志,我有时也会看到错误。
清华6月19日16:12:31.934289 2014年pid 560 PHP致命错误:允许134217728字节内存耗尽(试图分配139678164955264字节)在第0行未知
我想做什么,
我试图找到问题发生的确切位置,但它似乎发生在调用扩展的php类的析构函数之间,但在构造函数运行构造函数的第一行之前(注意,我主要使用phpunit来诊断这个问题,如果我在浏览器中运行它,它通常会工作一次,然后在下次尝试时将错误抛给日志,在浏览器窗口中使用‘连接被重置’,所以没有输出。
我尝试过用memory_get_usage添加调试行并安装扩展memprof,但是所有输出都没有显示出任何严重的内存问题,而且我从未见过超过8mb的内存使用量。
我看过其他关于更改php设置以处理zend_mm_corrupted问题的堆栈溢出帖子,禁用/启用垃圾收集而没有取得任何程度的成功。
我在找什么
我意识到这里没有足够的信息来知道是什么导致了我的记忆泄漏,所以我想知道的是,我的问题的可能和可能的原因是什么,以及我如何去诊断这个问题,找出问题所在。
注意:
我尝试过使用--启用-调试来构建我的扩展,但它是一个未被识别的参数。
编辑: Valgrind
我对它进行了验证,得到了以下输出:
--24803-- REDIR: 0x4ebde30 (__GI_strncmp)重定向到0x4c2dd20 (__GI_strncmp) -24803-- REDIR: 0x4ec1820 (__GI_stpcpy)重定向到0x4c2f860 (__GI_stpcpy) 分段故障(堆芯倾弃) ==24803== ==24803==堆摘要: 在出口处使用的==24803==:72个块中的2,401字节 ==24803==总堆使用率:73个分配程序,1个空闲,2,417字节分配 ==24803== ==24803==搜索指向72个未释放的块的指针 ==24803==检查了92,624字节 ==24803== ==24803==泄漏摘要: ==24803==肯定丢失了:0块中的0字节 ==24803==间接丢失:0块中的0字节 ==24803==可能丢失:0块中的0字节 ==24803==仍可访问:72个块中的2,401字节 ==24803==被抑制:0块中的0字节 未显示==24803==可达块(找到指针的块)。 要查看它们,请重新运行: ==24803== ==24803==错误摘要:0来自0上下文的错误(抑制:2来自2) -24803-- -24803-- used_suppression: 2 dl-hack3-cond-1 ==24803== ==24803==错误摘要:0来自0上下文的错误(抑制:2来自2)
这表明,也许这个问题不是内存泄漏,但对此并不确定。
发布于 2014-06-20 02:48:38
在我看来,您的程序确实存在堆内存损坏。通过查找代码片段或错误的调用堆栈,很难找到这一点。您可能希望在一些动态工具(Val差发、WindDBG/Page堆)下运行您的程序来跟踪实际的错误来源。
$ valgrind工具=记忆检查-db-附加=是。/a.out
这样,当检测到第一个内存错误时,Val差尔就会将您的程序附加到调试器中,以便您可以进行实时调试(GDB)。这应该是理解和解决问题的最好方法。
允许内存大小为134217728字节,耗尽(试图分配139678164955264字节)在第0行中未知
看起来,在您的程序中,签名为无符号转换的某个地方正在执行。通常分配器具有无符号类型的大小参数,因此它将负值解释为非常大的类型,在这种情况下,分配将失败。
https://stackoverflow.com/questions/24319017
复制相似问题