Questa risposta è intesa come una struttura generale per risolvere i problemi con gli script CGI Perl ed è apparsa originariamente su Perlmonks come Risoluzione dei problemi degli script CGI Perl . Non è una guida completa a tutti i problemi che potresti incontrare, né un tutorial su come eliminare i bug. È solo il culmine della mia esperienza di debug di script CGI per venti (più!) Anni. Questa pagina sembra aver avuto molte case diverse e mi sembra di dimenticare che esiste, quindi la sto aggiungendo a StackOverflow. Puoi inviarmi commenti o suggerimenti a bdfoy@cpan.org. È anche un wiki della comunità, ma non impazzire. :)
Stai usando le funzionalità integrate di Perl per aiutarti a trovare i problemi?
Attiva gli avvisi per consentire a Perl di avvisarti delle parti discutibili del tuo codice. Puoi farlo dalla riga di comando con l' -w
interruttore in modo da non dover modificare alcun codice o aggiungere un pragma a ogni file:
% perl -w program.pl
Tuttavia, dovresti sforzarti di chiarire sempre il codice discutibile aggiungendo il warnings
pragma a tutti i tuoi file:
use warnings;
Se hai bisogno di più informazioni rispetto al breve messaggio di avviso, usa il diagnostics
pragma per ottenere maggiori informazioni o guarda nella documentazione di perldiag :
use diagnostics;
Hai emesso prima un'intestazione CGI valida?
Il server si aspetta che il primo output di uno script CGI sia l'intestazione CGI. Tipicamente che potrebbe essere semplice come print "Content-type: text/plain\n\n";
o con CGI.pm e suoi derivati, print header()
. Alcuni server sono sensibili all'output di errore (attivato STDERR
) visualizzato prima dell'output standard (attivato STDOUT
).
Prova a inviare errori al browser
Aggiungi questa linea
use CGI::Carp 'fatalsToBrowser';
al tuo script. Questo invia anche errori di compilazione alla finestra del browser. Assicurati di rimuoverlo prima di passare a un ambiente di produzione, poiché le informazioni aggiuntive possono rappresentare un rischio per la sicurezza.
Cosa diceva il registro degli errori?
I server conservano i log degli errori (o almeno dovrebbero). L'output di errore dal server e dal tuo script dovrebbe essere visualizzato lì. Trova il registro degli errori e guarda cosa dice. Non esiste una posizione standard per i file di registro. Cerca nella configurazione del server la loro posizione o chiedi all'amministratore del server. Puoi anche usare strumenti come CGI :: Carp
per mantenere i tuoi file di registro.
Quali sono i permessi dello script?
Se vedi errori come "Autorizzazione negata" o "Metodo non implementato", probabilmente significa che il tuo script non è leggibile ed eseguibile dall'utente del server web. Su versioni di Unix, cambiando la modalità a 755 è raccomandato:
chmod 755 filename
. Non impostare mai una modalità su 777!
Stai usando use strict
?
Ricorda che Perl crea automaticamente le variabili quando le usi per la prima volta. Questa è una caratteristica, ma a volte può causare bug se digiti erroneamente il nome di una variabile. Il pragma
use strict
ti aiuterà a trovare questo tipo di errori. È fastidioso finché non ti ci abitui, ma la tua programmazione migliorerà notevolmente dopo un po 'e sarai libero di fare errori diversi.
Lo script si compila?
È possibile verificare la presenza di errori di compilazione utilizzando l' -c
opzione. Concentrati sui primi errori segnalati. Risciacquare, ripetere. Se ricevi errori davvero strani, controlla che lo script abbia le terminazioni di riga corrette. Se utilizzi FTP in modalità binaria, esegui il checkout da CVS o qualcos'altro che non gestisce la traduzione di fine riga, il server web potrebbe vedere il tuo script come un'unica grande riga. Trasferisci script Perl in modalità ASCII.
Lo script si lamenta di dipendenze insicure?
Se il tuo script si lamenta di dipendenze non sicure, probabilmente stai usando l' -T
interruttore per attivare la modalità di contaminazione, il che è una buona cosa poiché ti fa passare dati non controllati alla shell. Se si lamenta, sta facendo il suo lavoro per aiutarci a scrivere script più sicuri. Tutti i dati provenienti dall'esterno del programma (cioè l'ambiente) sono considerati contaminati. Le variabili ambientali come PATH
e
LD_LIBRARY_PATH
sono particolarmente fastidiose. Devi impostarli su un valore sicuro o disattivarli completamente, come ti consiglio. Dovresti comunque usare percorsi assoluti. Se il controllo della contaminazione si lamenta di qualcos'altro, assicurati di aver contaminato i dati. Vedere la
pagina man di perlsec per i dettagli.
Cosa succede quando lo esegui dalla riga di comando?
Lo script restituisce ciò che ti aspetti quando viene eseguito dalla riga di comando? L'output dell'intestazione è prima, seguito da una riga vuota? Ricorda che STDERR
potrebbe essere unito a STDOUT
se sei su un terminale (ad esempio una sessione interattiva) e, a causa del buffering, potrebbe apparire in un ordine confuso. Attiva la funzione autoflush di Perl impostando $|
un valore vero. Tipicamente potresti vedere $|++;
nei programmi CGI. Una volta impostata, ogni stampa e scrittura andrà immediatamente all'output anziché essere memorizzata nel buffer. Devi impostarlo per ogni filehandle. Utilizzare select
per modificare il filehandle predefinito, in questo modo:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
In ogni caso, la prima cosa in uscita dovrebbe essere l'intestazione CGI seguita da una riga vuota.
Cosa succede quando lo esegui dalla riga di comando con un ambiente simile a CGI?
L'ambiente del server Web è generalmente molto più limitato rispetto all'ambiente della riga di comando e contiene informazioni aggiuntive sulla richiesta. Se lo script viene eseguito correttamente dalla riga di comando, potresti provare a simulare un ambiente di server web. Se il problema appare, hai un problema ambientale.
Annulla o rimuovi queste variabili
PATH
LD_LIBRARY_PATH
- tutte le
ORACLE_*
variabili
Imposta queste variabili
REQUEST_METHOD
(impostato GET
, HEAD
o POST
se del caso)
SERVER_PORT
(impostato su 80, di solito)
REMOTE_USER
(se stai facendo cose di accesso protetto)
Le versioni recenti di CGI.pm
(> 2.75) richiedono il -debug
flag per ottenere il vecchio (utile) comportamento, quindi potrebbe essere necessario aggiungerlo alle CGI.pm
importazioni.
use CGI qw(-debug)
Stai usando die()
o warn
?
Queste funzioni vengono stampate a STDERR
meno che non siano state ridefinite. Non producono neanche un'intestazione CGI. Puoi ottenere la stessa funzionalità con pacchetti come CGI :: Carp
Cosa succede dopo aver svuotato la cache del browser?
Se pensi che il tuo script stia facendo la cosa giusta e quando esegui la richiesta manualmente ottieni l'output giusto, il browser potrebbe essere il colpevole. Svuota la cache e imposta la dimensione della cache su zero durante il test. Ricorda che alcuni browser sono davvero stupidi e non ricaricano effettivamente nuovi contenuti anche se gli dici di farlo. Ciò è particolarmente diffuso nei casi in cui il percorso dell'URL è lo stesso, ma il contenuto cambia (ad es. Immagini dinamiche).
La sceneggiatura è dove pensi che sia?
Il percorso del file system di uno script non è necessariamente correlato direttamente al percorso dell'URL dello script. Assicurati di avere la directory giusta, anche se devi scrivere un breve script di test per verificarlo. Inoltre, sei sicuro di voler modificare il file corretto? Se non vedi alcun effetto con le tue modifiche, potresti modificare un file diverso o caricare un file nel posto sbagliato. (Questa è, tra l'altro, la mia causa più frequente di tali problemi;)
Stai usando CGI.pm
o un suo derivato?
Se il problema è legato al parsing all'ingresso CGI e non si utilizza un modulo ampiamente testato come CGI.pm
, CGI::Request
,
CGI::Simple
o CGI::Lite
, utilizzare il modulo e andare avanti con la vita.
CGI.pm
ha una cgi-lib.pl
modalità di compatibilità che può aiutarti a risolvere i problemi di input dovuti alle vecchie implementazioni del parser CGI.
Hai usato percorsi assoluti?
Se stai eseguendo comandi esterni con
system
, segni di spunta o altri servizi IPC, dovresti usare un percorso assoluto al programma esterno. Non solo sai esattamente cosa stai eseguendo, ma eviti anche alcuni problemi di sicurezza. Se stai aprendo file per la lettura o la scrittura, usa un percorso assoluto. Lo script CGI potrebbe avere un'idea diversa di te sulla directory corrente. In alternativa, puoi fare un esplicito chdir()
per metterti nel posto giusto.
Hai controllato i valori di ritorno?
La maggior parte delle funzioni Perl ti dirà se hanno funzionato o meno e si imposteranno $!
in caso di fallimento. Hai controllato il valore restituito ed esaminato $!
i messaggi di errore? Hai controllato
$@
se stavi usando eval
?
Quale versione di Perl stai usando?
L'ultima versione stabile di Perl è la 5.28 (o meno, a seconda di quando è stata modificata l'ultima volta). Stai usando una versione precedente? Versioni differenti di Perl possono avere idee differenti sugli avvertimenti.
Quale server web stai utilizzando?
Server diversi possono agire in modo diverso nella stessa situazione. Lo stesso prodotto server può agire in modo diverso con configurazioni diverse. Includere quante più informazioni possibile in qualsiasi richiesta di aiuto.
Hai controllato la documentazione del server?
I programmatori CGI seri dovrebbero conoscere il più possibile il server, comprese non solo le caratteristiche e il comportamento del server, ma anche la configurazione locale. La documentazione per il server potrebbe non essere disponibile se si utilizza un prodotto commerciale. Altrimenti, la documentazione dovrebbe essere sul tuo server. In caso contrario, cercalo sul web.
Questo era utile, ma tutti i buoni poster sono morti o si sono allontanati.
È probabile che qualcuno abbia già avuto il tuo problema e che qualcuno (forse io) abbia risposto in questo newsgroup. Sebbene questo newsgroup abbia superato il suo periodo di massimo splendore, la saggezza raccolta dal passato a volte può essere utile.
Puoi riprodurre il problema con un breve script di prova?
In sistemi di grandi dimensioni, potrebbe essere difficile rintracciare un bug poiché stanno accadendo così tante cose. Prova a riprodurre il comportamento del problema con lo script più breve possibile. Conoscere il problema è la maggior parte della soluzione. Questo può certamente richiedere molto tempo, ma non hai ancora trovato il problema e stai esaurendo le opzioni. :)
Hai deciso di andare a vedere un film?
Sul serio. A volte possiamo essere così presi dal problema che sviluppiamo un "restringimento percettivo" (visione a tunnel). Fare una pausa, prendere una tazza di caffè o far esplodere alcuni cattivi in [Duke Nukem, Quake, Doom, Halo, COD] potrebbe darti la nuova prospettiva di cui hai bisogno per affrontare nuovamente il problema.
Hai vocalizzato il problema?
Di nuovo sul serio. A volte spiegare il problema ad alta voce ci porta alle nostre risposte. Parla con il pinguino (peluche) perché i tuoi colleghi non stanno ascoltando. Se sei interessato a questo come uno strumento di debug serio (e lo consiglio se non hai ancora trovato il problema), potresti anche leggere The Psychology of Computer Programming .