2009-07-16 5 views
5

Recentemente mi sono imbattuto in un problema che sfidava le mie capacità di programmazione, ed era un ciclo infinito molto casuale. Avevo riscritto un codice per asciugarlo e cambiato una funzione che veniva ripetutamente chiamata dai metodi esatti che chiamava; un problema elementare, certamente. Apache ha deciso di risolvere il problema arrestandosi in modo anomalo e il registro non ha rilevato nient'altro che "processo figlio generato". Il problema era che non ho mai finito di fare il debugging del problema quel giorno, è saltato fuori nel pomeriggio e ho dovuto risolverlo oggi.Come eseguire il debug e la protezione da loop infiniti in PHP?

Alla fine, la mia soluzione era semplice: registrare la logica manualmente e vedere cosa è successo. Il problema era immediatamente evidente quando avevo un file di registro costituito da due linee univoche, seguite da due righe che venivano ripetute circa duecento volte l'una.

Quali sono alcuni modi per proteggerci da loop infiniti? E quando ciò fallisce (e lo sarà), qual è il modo più veloce per rintracciarlo? È davvero il file di registro che è più efficace o qualcos'altro?

La tua risposta potrebbe essere indipendente dal linguaggio se fosse una buona pratica, ma preferirei attenermi alle tecniche e al codice specifici di PHP.

+1

Questa domanda non mi sembra diversa dalla domanda generale "come scrivere software privi di bug" ... – gahooa

+0

@gahooa, sei solo tu; Non sono interessato a software privo di bug perché non ci arriverà mai. Voglio solo suggerimenti per cogliere questo problema, che mi ha colto di sorpresa l'altro giorno. –

risposta

15

È possibile utilizzare un debugger come xdebug e scorrere il codice che si sospetta contenga il ciclo infinito.

Xdebug - Debugger and Profiler Tool for PHP

è anche possibile impostare

max_execution_time 

per limitare il tempo del ciclo infinito brucerà prima di schiantarsi.

+0

Mi ero completamente dimenticato di xdebug. Grazie! –

0

scrivere codice semplice, quindi i bug saranno più evidenti? Mi chiedo se il tuo ciclo infinito sia dovuto a una ridicola palla filata di strutture di controllo che nessun essere umano può mai capire. Quindi, naturalmente, l'hai inventato.

tutti gli anelli infiniti non sono male (ad esempio while (!quit)).

+0

Questo era in un codebase di 100 righe; non molto lì per impiccarmi. Il problema stava riscrivendo una routine di una coppia di routine intrecciate e invertendo il flusso di chiamate. 'a-> b-> c' è diventato' a <-> b'. –

1

I test di unità potrebbero essere una buona idea. Potresti provare PHPUnit.

+0

Buona idea, ma il mio codice, pur testabile, avrebbe fatto crashare i test unitari. –

3

A volte trovo che il metodo più sicuro sia quello di incorporare un controllo limite nel ciclo. Il tipo di costrutti di loop non ha importanza. In questo esempio ho scelto un 'po' affermazione:

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

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

    ... 
} 

un valore ragionevole per $ max_loop_iterations potrebbe essere basata su:

  • un valore costante impostato in fase di esecuzione
  • un valore calcolato in base al dimensioni di un ingresso
  • o forse un valore calcolato basato sulla velocità relativa runtime

speranza t i suoi aiuti, - N

0

è possibile tracciare l'esecuzione e scaricare un grafico di chiamata? i loop infiniti saranno ovvi, e puoi facilmente scegliere quelli che sono apposta (un enorme mainloop) contro un incidente (abababa locale ...loop o loop che non ritorna mai al mainloop)

ho sentito parlare di software che lo fa per programmi complessi di grandi dimensioni, ma non sono riuscito a trovare uno screenshot per te. Qualcuno ha tracciato un programma come 3dsmax e scaricato un grafo di chiamate davvero carino.