【问题标题】:How to debug, and protect against, infinite loops in PHP?如何调试和防止 PHP 中的无限循环?
【发布时间】:2009-07-16 19:08:34
【问题描述】:

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

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

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

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

【问题讨论】:

  • 这个问题对我的印象与一般的“我们如何编写无错误软件”问题没有什么不同......
  • @gahooa,这就是你;我对没有错误的软件不感兴趣,因为它永远不会到达那里。我只是想要解决这个问题的提示,前几天让我措手不及。

标签: php apache debugging infinite-loop


【解决方案1】:

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

Xdebug - Debugger and Profiler Tool for PHP

你也可以设置

max_execution_time

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

【讨论】:

  • 我完全忘记了 xdebug。谢谢!
【解决方案2】:

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

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

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

  ...
}

$max_loop_iterations 的合理值可能基于:

  • 在运行时设置的常量值
  • 基于输入大小的计算值
  • 或者可能是基于相对运行时速度的计算值

希望这会有所帮助, - 不

【讨论】:

    【解决方案3】:

    单元测试也可能是个好主意。你可能想试试 PHPUnit。

    【讨论】:

    • 好主意,但我的代码虽然可测试,但会使单元测试崩溃。
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      编写简单的代码,这样错误会更明显吗?我想知道您的无限循环是否是由于一些人类无法理解的荒谬控制结构毛线球。所以你当然把它搞砸了。

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

      【讨论】:

      • 这是一个 100 行代码库;没有什么可以挂断我的。麻烦在于重写一对相互交织的例程中的一个例程,并颠倒调用流程。 a->b->c 变成了a<->b
      猜你喜欢
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      相关资源
      最近更新 更多