【发布时间】:2011-11-11 17:55:12
【问题描述】:
一个假设性的问题供大家思考......
我最近回答了关于 SO 的另一个问题,其中 PHP 脚本出现了段错误,这让我想起了我一直想知道的事情,所以让我们看看是否有人能对此有所了解。
考虑以下几点:
<?php
function segfault ($i = 1) {
echo "$i\n";
segfault($i + 1);
}
segfault();
?>
显然,这个(无用的)函数无限循环。最终,将耗尽内存,因为对函数的每次调用都会在前一次调用完成之前执行。有点像没有分叉的分叉炸弹。
但是...最终,在 POSIX 平台上,脚本会随着 SIGSEGV 而死(它也会在 Windows 上死掉,但更优雅 - 就我极其有限的低级调试技能而言)。循环的数量取决于系统配置(分配给 PHP、32 位/64 位等的内存)和操作系统,但我真正的问题是 - 为什么会发生段错误?
- 这仅仅是 PHP 处理“内存不足”错误的方式吗?肯定有更优雅的方式来处理这个问题吗?
- 这是 Zend 引擎中的错误吗?
- 有什么方法可以在 PHP 脚本中更优雅地控制或处理这种情况?
- 是否有任何设置通常控制函数中可以进行的最大递归调用数?
【问题讨论】:
-
According to PHP,这是预期行为。
-
@NullUserException 这很有趣,我确实搜索了 PHP 错误,但没有发现......他们说它是
known recursion limit似乎很奇怪,但没有说明限制该限制,或提供任何方式来控制它。正如那个 bug 的报告者所说,如果你编写有 bug 的代码,这只会导致问题,但如果知道边界在哪里就好了。 -
我希望所有被炸毁的函数都将自己重命名为
segfault- 这肯定会在办公室节省一些漫长的夜晚! -
@Lawrence Cherone 在某些情况下,代码不打算用完堆栈但确实(比如说一个完美的递归算法,它遇到了一个退化的情况;你知道一个正常的“漏洞”)。 PHP 只是有一个不可接受的“解决方案”,IMOHO。 (Ruby、Perl 和 Python —— 3 个动态竞争者施加了更理智但有些武断的限制。)
-
@Lawrence 将段错误称为“非常好的错误代码”有点过分,嗯?