Cette réponse est conçue comme un cadre général pour résoudre les problèmes avec les scripts Perl CGI et est apparue à l'origine sur Perlmonks en tant que Dépannage des scripts Perl CGI . Ce n'est pas un guide complet de tous les problèmes que vous pourriez rencontrer, ni un tutoriel sur la correction des bogues. C'est juste le point culminant de mon expérience de débogage de scripts CGI pendant vingt (plus!) Ans. Cette page semble avoir eu de nombreuses maisons différentes, et je semble oublier qu'elle existe, donc je l'ajoute à StackOverflow. Vous pouvez m'envoyer vos commentaires ou suggestions à bdfoy@cpan.org. C'est aussi un wiki communautaire, mais ne devenez pas trop fou. :)
Utilisez-vous les fonctionnalités intégrées de Perl pour vous aider à trouver des problèmes?
Activez les avertissements pour laisser Perl vous avertir des parties douteuses de votre code. Vous pouvez le faire à partir de la ligne de commande avec le -w
commutateur afin de ne pas avoir à changer de code ou à ajouter un pragma à chaque fichier:
% perl -w program.pl
Cependant, vous devez vous forcer à toujours effacer le code douteux en ajoutant le warnings
pragma à tous vos fichiers:
use warnings;
Si vous avez besoin de plus d'informations que le court message d'avertissement, utilisez le diagnostics
pragma pour obtenir plus d'informations, ou consultez la documentation de perldiag :
use diagnostics;
Avez-vous d'abord sorti un en-tête CGI valide?
Le serveur s'attend à ce que la première sortie d'un script CGI soit l'en-tête CGI. En règle générale qui pourrait être aussi simple que print "Content-type: text/plain\n\n";
ou avec CGI.pm et ses dérivés, print header()
. Certains serveurs sont sensibles à la sortie d'erreur (surSTDERR
) apparaissant avant la sortie standard (activée STDOUT
).
Essayez d'envoyer des erreurs au navigateur
Ajouter cette ligne
use CGI::Carp 'fatalsToBrowser';
à votre script. Cela envoie également des erreurs de compilation à la fenêtre du navigateur. Veillez à le supprimer avant de passer à un environnement de production, car les informations supplémentaires peuvent constituer un risque pour la sécurité.
Que dit le journal des erreurs?
Les serveurs conservent des journaux d'erreurs (ou ils devraient, au moins). La sortie d'erreur du serveur et de votre script devrait apparaître là-haut. Trouvez le journal des erreurs et voyez ce qu'il dit. Il n'y a pas d'espace standard pour les fichiers journaux. Recherchez leur emplacement dans la configuration du serveur ou demandez à l'administrateur du serveur. Vous pouvez également utiliser des outils tels que CGI :: Carp
pour conserver vos propres fichiers journaux.
Quelles sont les autorisations du script?
Si vous voyez des erreurs telles que «Autorisation refusée» ou «Méthode non implémentée», cela signifie probablement que votre script n'est pas lisible et exécutable par l'utilisateur du serveur Web. Sur les versions d'Unix, en changeant le mode 755 est recommandé:
chmod 755 filename
. Ne définissez jamais un mode sur 777!
Utilisez-vous use strict
?
N'oubliez pas que Perl crée automatiquement des variables lorsque vous les utilisez pour la première fois. Ceci est une fonctionnalité, mais peut parfois causer des bogues si vous saisissez mal un nom de variable. Le pragma
use strict
vous aidera à trouver ce genre d'erreurs. C'est ennuyeux jusqu'à ce que vous vous y habituiez, mais votre programmation s'améliorera considérablement après un certain temps et vous serez libre de faire différentes erreurs.
Le script se compile-t-il?
Vous pouvez vérifier les erreurs de compilation en utilisant le -c
commutateur. Concentrez-vous sur les premières erreurs signalées. Rincez, répétez. Si vous rencontrez des erreurs vraiment étranges, vérifiez que votre script a les bonnes fins de ligne. Si vous effectuez un FTP en mode binaire, une extraction depuis CVS ou quelque chose d'autre qui ne gère pas la traduction de fin de ligne, le serveur Web peut voir votre script comme une seule grande ligne. Transférez les scripts Perl en mode ASCII.
Le script se plaint-il de dépendances non sécurisées?
Si votre script se plaint de dépendances non sécurisées, vous utilisez probablement le -T
commutateur pour activer le mode taint, ce qui est une bonne chose car il vous permet de continuer à transmettre des données non vérifiées au shell. S'il se plaint, il fait son travail pour nous aider à écrire des scripts plus sécurisés. Toute donnée provenant de l'extérieur du programme (c'est-à-dire de l'environnement) est considérée comme corrompue. Les variables d'environnement telles que PATH
et
LD_LIBRARY_PATH
sont particulièrement gênantes. Vous devez les définir sur une valeur sûre ou les désactiver complètement, comme je le recommande. Vous devriez de toute façon utiliser des chemins absolus. Si la vérification de l'altération se plaint d'autre chose, assurez-vous que vous n'avez pas altéré les données. Voir la
page de manuel de perlsec pour plus de détails.
Que se passe-t-il lorsque vous l'exécutez à partir de la ligne de commande?
Le script produit-il ce que vous attendez lorsqu'il est exécuté à partir de la ligne de commande? L'en-tête est-il sorti en premier, suivi d'une ligne vide? N'oubliez pas que cela STDERR
peut être fusionné avec STDOUT
si vous êtes sur un terminal (par exemple, une session interactive), et qu'en raison de la mise en mémoire tampon, cela peut apparaître dans un ordre confus. Activez la fonction autoflush de Perl en définissant $|
une valeur vraie. En règle générale, vous pouvez voir $|++;
dans les programmes CGI. Une fois définies, chaque impression et écriture ira immédiatement à la sortie plutôt que d'être mise en mémoire tampon. Vous devez définir ceci pour chaque descripteur de fichier. Utilisez select
pour changer le descripteur de fichier par défaut, comme ceci:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
Dans tous les cas, la première sortie doit être l'en-tête CGI suivi d'une ligne vide.
Que se passe-t-il lorsque vous l'exécutez à partir de la ligne de commande avec un environnement de type CGI?
L'environnement du serveur Web est généralement beaucoup plus limité que votre environnement de ligne de commande et contient des informations supplémentaires sur la demande. Si votre script s'exécute correctement à partir de la ligne de commande, vous pouvez essayer de simuler un environnement de serveur Web. Si le problème apparaît, vous avez un problème d'environnement.
Annuler ou supprimer ces variables
PATH
LD_LIBRARY_PATH
- toutes les
ORACLE_*
variables
Définissez ces variables
REQUEST_METHOD
(fixé à GET
, HEAD
ou POST
selon le cas)
SERVER_PORT
(défini sur 80, généralement)
REMOTE_USER
(si vous faites des choses à accès protégé)
Les versions récentes de CGI.pm
(> 2.75) nécessitent l' -debug
indicateur pour obtenir l'ancien comportement (utile), vous devrez donc peut-être l'ajouter à vos CGI.pm
importations.
use CGI qw(-debug)
Utilisez-vous die()
ou warn
?
Ces fonctions s'impriment STDERR
sauf si vous les avez redéfinies. Ils ne produisent pas non plus d'en-tête CGI. Vous pouvez obtenir la même fonctionnalité avec des packages tels que CGI :: Carp
Que se passe-t-il après avoir vidé le cache du navigateur?
Si vous pensez que votre script fait la bonne chose et que lorsque vous exécutez la requête manuellement, vous obtenez le bon résultat, le navigateur peut être le coupable. Videz le cache et définissez la taille du cache sur zéro pendant le test. N'oubliez pas que certains navigateurs sont vraiment stupides et ne rechargeront pas réellement le nouveau contenu même si vous leur dites de le faire. Ceci est particulièrement répandu dans les cas où le chemin de l'URL est le même, mais le contenu change (par exemple les images dynamiques).
Le script est-il là où vous pensez qu'il se trouve?
Le chemin du système de fichiers vers un script n'est pas nécessairement directement lié au chemin de l'URL du script. Assurez-vous d'avoir le bon répertoire, même si vous devez écrire un court script de test pour le tester. De plus, êtes-vous sûr de modifier le bon fichier? Si vous ne voyez aucun effet avec vos modifications, vous êtes peut-être en train de modifier un autre fichier ou de télécharger un fichier au mauvais endroit. (C'est d'ailleurs ma cause la plus fréquente de tels problèmes;)
Utilisez-vous CGI.pm
ou un dérivé de celui-ci?
Si votre problème est lié à l' analyse de l'entrée de CGI et vous n'êtes pas en utilisant un module largement testé comme CGI.pm
, CGI::Request
,
CGI::Simple
ou CGI::Lite
, utilisez le module et se concentrer sur la vie.
CGI.pm
a un cgi-lib.pl
mode de compatibilité qui peut vous aider à résoudre les problèmes d'entrée dus aux anciennes implémentations de l'analyseur CGI.
Avez-vous utilisé des chemins absolus?
Si vous exécutez des commandes externes avec
system
, des graduations inverses ou d'autres fonctions IPC, vous devez utiliser un chemin absolu vers le programme externe. Non seulement vous savez exactement ce que vous exécutez, mais vous évitez également certains problèmes de sécurité. Si vous ouvrez des fichiers en lecture ou en écriture, utilisez un chemin absolu. Le script CGI peut avoir une idée différente de la vôtre sur le répertoire actuel. Alternativement, vous pouvez faire un explicite chdir()
pour vous mettre au bon endroit.
Avez-vous vérifié vos valeurs de retour?
La plupart des fonctions Perl vous diront si elles ont fonctionné ou non et seront activées $!
en cas d'échec. Avez-vous vérifié la valeur de retour et examiné $!
les messages d'erreur? Avez-vous vérifié
$@
si vous utilisiez eval
?
Quelle version de Perl utilisez-vous?
La dernière version stable de Perl est la 5.28 (ou non, selon la date de la dernière modification). Utilisez-vous une ancienne version? Différentes versions de Perl peuvent avoir différentes idées d'avertissement.
Quel serveur Web utilisez-vous?
Différents serveurs peuvent agir différemment dans la même situation. Le même produit serveur peut agir différemment avec différentes configurations. Incluez autant de ces informations que possible dans toute demande d'aide.
Avez-vous vérifié la documentation du serveur?
Les programmeurs CGI sérieux doivent en savoir autant que possible sur le serveur - y compris non seulement les fonctionnalités et le comportement du serveur, mais également la configuration locale. La documentation de votre serveur peut ne pas être disponible si vous utilisez un produit commercial. Sinon, la documentation doit être sur votre serveur. Si ce n'est pas le cas, recherchez-le sur le Web.
Cette utilisation était utile, mais toutes les bonnes affiches sont soit mortes, soit errantes.
Il est probable que quelqu'un ait déjà eu votre problème et que quelqu'un (peut-être moi) y ait répondu dans ce groupe de discussion. Bien que ce groupe de discussion ait passé son apogée, la sagesse recueillie du passé peut parfois être utile.
Pouvez-vous reproduire le problème avec un court script de test?
Dans les grands systèmes, il peut être difficile de localiser un bogue car il se passe tellement de choses. Essayez de reproduire le problème avec le script le plus court possible. Connaître le problème est l'essentiel du correctif. Cela peut certainement prendre du temps, mais vous n'avez pas encore trouvé le problème et vous manquez d'options. :)
Avez-vous décidé d'aller voir un film?
Sérieusement. Parfois, nous pouvons être tellement absorbés par le problème que nous développons un «rétrécissement perceptif» (vision tunnel). Prendre une pause, prendre une tasse de café ou faire exploser des méchants dans [Duke Nukem, Quake, Doom, Halo, COD] pourrait vous donner la nouvelle perspective dont vous avez besoin pour ré-aborder le problème.
Avez-vous exprimé le problème?
Sérieusement encore. Parfois, expliquer le problème à haute voix nous conduit à nos propres réponses. Parlez au pingouin (peluche) parce que vos collègues n'écoutent pas. Si cela vous intéresse en tant qu'outil de débogage sérieux (et je le recommande si vous n'avez pas encore trouvé le problème), vous pouvez également lire The Psychology of Computer Programming .