简体   繁体   English

如何在PHP中调试和防范无限循环?

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

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". Apache决定通过崩溃来解决问题,而日志只注明“衍生出来的子进程”。 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. 问题是我当天从未真正调试过这个问题,它在下午出现,并且今天不得不解决它。

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. 当我有一个由两条独特的线组成的日志文件时,问题立即显现出来,接下来是两条线,每条线重复约两百次。

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特定的技术和代码。

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. 限制无限循环在崩溃前燃烧的时间。

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.

Unit tests might be a good idea, too. 单元测试也可能是一个好主意。 You might want to try PHPUnit. 您可能想尝试PHPUnit。

write simple code, so bugs will be more apparent? 编写简单的代码,这样bug会更明显吗? 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. 因此,你当然会把它搞定。

all infinite loops aren't bad (eg while (!quit) ). 所有无限循环都不错(例如while (!quit) )。

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 ...循环或循环,永远不会返回到mainloop)

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这样的程序并抛出了一个非常漂亮的调用图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM