如何在PHP中捕获递归失控脚本?

时间:2011-10-22 18:14:10

标签: php apache recursion

我的Apache有时因为内存不足而被杀死。这并没有发生。我在这个项目中有几百个PHP文件。

我怀疑创建了一个无意的递归 - 不只是一个函数调用自身,而是函数A调用B然后再次调用A.

我尝试过阅读代码并找到这样的递归,但没有运气。

有没有办法告诉PHP跟踪所有递归,或者在内部堆栈超过一定大小时发出警告?

1 个答案:

答案 0 :(得分:3)

  

我的Apache有时因为内存不足而被杀死。

那至少是一个重要的开始点。我可以在你的问题中读到你怀疑是由PHP脚本引起的。

要找出哪一个,你需要进一步了解。我能想到的一种方法是启用PHP错误记录。然后将memory_limit设置为较低的值,以便在发生大量内存消耗时引发错误。您可以在错误日志中找到发生这种情况的行(另请参阅Protocol of some PHP Memory Stretching Fun)。

这应该会给你一些潜在的地方。

我不确定递归是否必须引起这种情况,而你自己写道,你只能假设这一点。要检测递归,可以使用xdebug并限制递归深度:

xdebug.max_nesting_level=<your preferred value>

这应该会在错误日志中提供更多有用的信息。

如果内存和递归都不是这种情况,它可能与PHP或PHP segaults无关,并且您的Web服务器无法处理这种情况。不知道mod_php如何处理段错误,但你还没有指定你正在使用的SAPI。

然而,PHP段错误的典型来源是在触发pcre递归限制之前启动PHP的正则表达式。如果您在代码中使用正则表达式,则可以reduce the recursion limit使用较低的值,并测试是否有帮助。但是,根据你的问题,目前尚不清楚这是否是一个原因。所以你首先需要了解更多。