2009-07-16 27 views
5

Recientemente me topé con un problema que desafió mis habilidades de programación, y fue un ciclo infinito muy accidental. Reescribí un código para secarlo y cambié una función a la que llamaban repetidamente los métodos exactos que llamaba; una cuestión elemental, sin duda. Apache decidió resolver el problema al estrellarse, y el registro no notó nada más que "proceso hijo engendrado". El problema fue que en realidad nunca terminé de depurar el problema ese día, apareció por la tarde y tuve que resolverlo hoy.¿Cómo depurar y proteger contra los bucles infinitos en PHP?

Al final, mi solución fue simple: registrar la lógica manualmente y ver qué sucedió. El problema fue inmediatamente aparente cuando tenía un archivo de registro que constaba de dos líneas únicas, seguidas de dos líneas que se repetían unas doscientas veces cada una.

¿Cuáles son algunas formas de protegernos contra ciclos infinitos? Y, cuando eso falla (y lo hará), ¿cuál es la forma más rápida de rastrearlo? ¿Es realmente el archivo de registro el más efectivo o algo más?

Su respuesta podría ser independiente del idioma si fuera una mejor práctica, pero prefiero seguir con las técnicas y el código específicos de PHP.

+1

Esta pregunta no me parece diferente a la pregunta general "¿cómo escribimos el software libre de errores? ... – gahooa

+0

@gahooa, eso es solo usted; No me interesa el software libre de errores porque nunca llegará. Solo quiero consejos para detectar este problema, lo que me tomó por sorpresa el otro día. –

Respuesta

15

Puede usar un depurador como xdebug, y recorrer el código que sospecha que contiene el ciclo infinito.

Xdebug - Debugger and Profiler Tool for PHP

También puede establecer

max_execution_time 

para limitar el tiempo del bucle infinito se quemará antes de estrellarse.

+0

Me había olvidado por completo de xdebug. ¡Gracias! –

0

escribe un código simple, por lo que los errores serán más evidentes? Me pregunto si su ciclo infinito se debe a una ridícula bola de fibras de estructuras de control que ningún ser humano puede comprender. Por lo tanto, por supuesto que lo hiciste.

todos los bucles infinitos no están mal (por ejemplo, while (!quit)).

+0

Esto estaba en una base de código de 100 líneas; no hay mucho allí para colgarme. El problema fue reescribir una rutina de un par de rutinas entrelazadas e invertir el flujo de llamadas. 'a-> b-> c' se convirtió en' a <-> b'. –

1

Las pruebas unitarias también pueden ser una buena idea. Es posible que desee probar PHPUnit.

+0

Buena idea, pero mi código, aunque puede probarse, habría bloqueado las pruebas unitarias. –

3

A veces encuentro que el método más seguro es incorporar una verificación de límite en el ciclo. El tipo de construcción de bucle no importa. En este ejemplo he elegido un 'mientras que' declaración:

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

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

    ... 
} 

Un valor razonable para $ max_loop_iterations podría basarse en:

  • un valor constante ajustado en tiempo de ejecución
  • un valor calculado en base a la tamaño de una entrada
  • o tal vez un valor calculado basado en velocidad de ejecución en relación

Hope t su ayuda, - N

0

puede usted trazar la ejecución y volcar un gráfico de llamadas? los bucles infinitos serán obvios, y puede elegir fácilmente los que son a propósito (un gran cruce) contra un accidente (abababa local ...loop o loop que nunca regresa al mainloop)

He oído hablar del software que hace esto para programas grandes y complejos, pero no pude encontrar una captura de pantalla para usted. Alguien trazó un programa como 3dsmax y arrojó un gráfico de llamadas realmente bonito.

Cuestiones relacionadas