apache 如何调试和防止 PHP 中的无限循环?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1139687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 17:54:50  来源:igfitidea点击:

How to debug, and protect against, infinite loops in PHP?

phpapachedebugginginfinite-loop

提问by Robert K

I recently ran up against a problem that challenged my programming abilities, and it was a very accidental infinite loop. I had rewritten some code to dry it up and changed a function that was being repeatedly called by the exact methods it called; an elementary issue, certainly. Apache decided to solve the problem by crashing, and the log noted nothing but "spawned child process". The problem was that I never actually finished debugging the issue that day, it cropped up in the afternoon, and had to solve it today.

我最近遇到了一个挑战我编程能力的问题,这是一个非常偶然的无限循环。我已经重写了一些代码来干掉它,并更改了一个被它调用的确切方法重复调用的函数;一个基本的问题,当然。Apache 决定通过崩溃来解决问题,并且日志只记录了“产生的子进程”。问题是那天我并没有真正调试完这个问题,它在下午突然出现,今天不得不解决它。

In the end, my solution was simple: log the logic manually and see what happened. The problem was immediately apparent when I had a log file consisting of two unique lines, followed by two lines that were repeated some two hundred times apiece.

最后,我的解决方案很简单:手动记录逻辑,看看发生了什么。当我的日志文件由两个独特的行组成时,问题立即显现出来,然后是两行,每行重复了大约 200 次。

What are some ways to protect ourselves against infinite loops? And, when that fails (and it will), what's the fastest way to track it down? Is it indeed the log file that is most effective, or something else?

有哪些方法可以保护自己免受无限循环的影响?而且,当它失败(并且会)时,追踪它的最快方法是什么?它确实是最有效的日志文件,还是其他什么?

Your answer could be language agnostic if it were a best practice, but I'd rather stick with PHP specific techniques and code.

如果这是最佳实践,您的答案可能与语言无关,但我宁愿坚持使用 PHP 特定的技术和代码。

回答by dreadwail

You could use a debugger such as xdebug, and walk through your code that you suspect contains the infinite loop.

您可以使用诸如 xdebug 之类的调试器,并遍历您怀疑包含无限循环的代码。

Xdebug - Debugger and Profiler Tool for PHP

Xdebug - 用于 PHP 的调试器和分析器工具

You can also set

你也可以设置

max_execution_time

to limit the time the infinite loop will burn before crashing.

限制无限循环在崩溃前燃烧的时间。

回答by Nathan

I sometimes find the safest method is to incorporate a limit check in the loop. The type of loop construct doesn't matter. In this example I chose a 'while' statement:

我有时发现最安全的方法是在循环中加入限制检查。循环构造的类型无关紧要。在这个例子中,我选择了一个“while”语句:

$max_loop_iterations = 10000;
$i=0;
$test=true;
while ($test) {

  if ($i++ == $max_loop_iterations) {
    echo "too many iterations...";
    break;
  }

  ...
}

A reasonable value for $max_loop_iterations might be based upon:

$max_loop_iterations 的合理值可能基于:

  • a constant value set at runtime
  • a computed value based upon the size of an input
  • or perhaps a computed value based upon relative runtime speed
  • 在运行时设置的常量值
  • 基于输入大小的计算值
  • 或者可能是基于相对运行速度的计算值

Hope this helps, - N

希望这有帮助,-N

回答by partoa

Unit tests might be a good idea, too. You might want to try PHPUnit.

单元测试也可能是一个好主意。您可能想尝试 PHPUnit。

回答by Dustin Getz

can you trace execution and dump out a call graph? infinite loops will be obvious, and you can easily pick out the ones that are on purpose (a huge mainloop) vs an accident (local abababa... loop or loop that never returns back to mainloop)

您可以跟踪执行并转储调用图吗?无限循环很明显,你可以很容易地挑选出那些是故意的(一个巨大的主循环)和一个意外(本地的abababa......循环或永远不会回到主循环的循环)

i've heard of software that does this for large complex programs, but i couldn't find a screenshot for you. Someone traced a program like 3dsmax and dumped out a really pretty call graph.

我听说过为大型复杂程序执行此操作的软件,但我找不到适合您的屏幕截图。有人跟踪了一个像 3dsmax 这样的程序,并输出了一个非常漂亮的调用图。

回答by Dustin Getz

write simple code, so bugs will be more apparent? I wonder if your infinite loop is due to some ridiculous yarn-ball of control structures that no human being can possibly understand. Thus of course you f'ed it up.

写简单的代码,这样bug会更明显?我想知道你的无限循环是否是由于一些人类无法理解的控制结构的可笑纱线球。所以你当然搞砸了。

all infinite loops aren't bad (e.g. while (!quit)).

所有无限循环都不错(例如while (!quit))。