为什么这个PHP函数会导致分段错误(SIGSEGV)?

3
我写了以下代码。
<?php
function f(){
  return f();
}
f();

并获取输出结果

$ php test.php
Segmentation fault

为什么?我没有使用任何指针。
这是StackOverflow吗?

2
f调用f调用f调用f调用f调用f调用f......我也会尖叫分段错误。 - Dan Lugg
2
我会尖叫:“致命错误:函数嵌套层级达到'100',终止!”或者“PHP致命错误:在命令行代码中尝试分配261900字节时耗尽了1073741824字节的内存限制”。 - binaryLV
1
xdebug 有一个限制吗?它是100吗? - Dan Lugg
@TomcatExodus,是的,它确实会这样做。无论如何,没有xdebug,我会得到第二个错误消息,指出内存用尽了。使用5.3.5,无论是Windows还是Linux。 - binaryLV
4个回答

7
这是无限递归的一个例子,但并不是具体的原因。这是堆栈溢出。当你进行递归时,无论是否无限,都有一个最大的深度可以递归(添加到堆栈中),它基于堆栈的大小(以字节为单位)。
从技术上讲,这是无限的,但你要很长时间才能收到任何错误提示:
<?php
function f(){
  sleep(1);
  return f();
}
f();

你需要的是递归中的“基本情况”,以便在消耗整个堆栈之前停止它。
<?php
function f($i){
  if($i == 10)
    return;

  echo $i;

  return f(++$i);
}
f(0);

这将打印0到9。

分段错误错误来自操作系统,报告PHP应用程序在添加到堆栈时遇到问题。由于在系统级别上组成PHP的二进制文件失败,因此不会传递到您的脚本。


1

这不是无限递归吗?你想要实现什么?


是的,这是一个无限循环。肯定会导致 PHP 报错。 - Raptor
是的,没错。但 SIGSEGV 只会在 C/C++ 代码中出现,不是吗? - freddiefujiwara
3
PHP是用C语言编写的,这里PHP出现了段错误。 - mu is too short
@freddiefujiwara:没错,就是这样...mu 给了我们答案 :) - Vern

1

这是来自于 XDebug 扩展。

运行 GDB,你会看到:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff41f7e48 in xdebug_add_stack_frame (zdata=Cannot access memory at address 0x7fffff5fefa8
) at /build/buildd/xdebug-2.1.0/build-php5/xdebug_stack.c:772
772 /build/buildd/xdebug-2.1.0/build-php5/xdebug_stack.c: No such file or directory.
    in /build/buildd/xdebug-2.1.0/build-php5/xdebug_stack.c

如果禁用了XDebug,它将一直执行,直到达到memory_limit。如果您的memory_limit太高,可能会耗尽RAM并开始交换,导致机器冻结/崩溃。

0

您设置的无限递归会不断添加堆栈帧,直到超出 PHP 进程调用堆栈分配的内存量,此时您会收到 “分割错误”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接