Diese Antwort ist als allgemeiner Rahmen für die Behebung von Problemen mit Perl-CGI-Skripten gedacht und wurde ursprünglich in Perlmonks als Fehlerbehebung bei Perl-CGI-Skripten angezeigt . Es ist weder eine vollständige Anleitung zu jedem Problem, auf das Sie stoßen könnten, noch ein Tutorial zum Squashing von Fehlern. Es ist nur der Höhepunkt meiner Erfahrung mit dem Debuggen von CGI-Skripten über zwanzig (plus!) Jahre. Diese Seite scheint viele verschiedene Häuser gehabt zu haben, und ich scheine zu vergessen, dass es sie gibt, also füge ich sie dem StackOverflow hinzu. Sie können mir Kommentare oder Vorschläge an bdfoy@cpan.org senden. Es ist auch Community-Wiki, aber nicht zu verrückt. :) :)
Verwenden Sie die integrierten Funktionen von Perl, um Probleme zu finden?
Aktivieren Sie Warnungen, damit Perl Sie vor fragwürdigen Teilen Ihres Codes warnt. Sie können dies über die Befehlszeile mit dem -w
Schalter tun, sodass Sie keinen Code ändern oder jeder Datei ein Pragma hinzufügen müssen:
% perl -w program.pl
Sie sollten sich jedoch zwingen, immer fragwürdigen Code zu löschen, indem Sie warnings
allen Ihren Dateien das Pragma hinzufügen :
use warnings;
Wenn Sie mehr Informationen als die kurze Warnmeldung benötigen, verwenden Sie das diagnostics
Pragma, um weitere Informationen zu erhalten, oder lesen Sie die perldiag- Dokumentation:
use diagnostics;
Haben Sie zuerst einen gültigen CGI-Header ausgegeben?
Der Server erwartet, dass die erste Ausgabe eines CGI-Skripts der CGI-Header ist. In der Regel ist dies so einfach wie print "Content-type: text/plain\n\n";
oder mit CGI.pm und seinen Derivaten print header()
. Einige Server reagieren empfindlich auf Fehlerausgaben (ein STDERR
), die vor der Standardausgabe (ein ) angezeigt werden STDOUT
.
Versuchen Sie, Fehler an den Browser zu senden
Fügen Sie diese Zeile hinzu
use CGI::Carp 'fatalsToBrowser';
zu Ihrem Skript. Dadurch werden auch Kompilierungsfehler an das Browserfenster gesendet. Entfernen Sie dies unbedingt, bevor Sie in eine Produktionsumgebung wechseln, da die zusätzlichen Informationen ein Sicherheitsrisiko darstellen können.
Was hat das Fehlerprotokoll gesagt?
Server führen Fehlerprotokolle (oder sollten es zumindest). Dort sollte eine Fehlerausgabe vom Server und von Ihrem Skript angezeigt werden. Suchen Sie das Fehlerprotokoll und sehen Sie, was darin steht. Es gibt keinen Standardplatz für Protokolldateien. Suchen Sie in der Serverkonfiguration nach ihrem Speicherort oder fragen Sie den Serveradministrator. Sie können auch Tools wie CGI :: Carp verwenden
, um Ihre eigenen Protokolldateien zu speichern.
Was sind die Berechtigungen des Skripts?
Wenn Fehler wie "Berechtigung verweigert" oder "Methode nicht implementiert" angezeigt werden, bedeutet dies wahrscheinlich, dass Ihr Skript vom Webserverbenutzer nicht lesbar und ausführbar ist. Bei Unix-Versionen wird empfohlen, den Modus auf 755 zu ändern :
chmod 755 filename
. Stellen Sie niemals einen Modus auf 777 ein!
Benutzt du use strict
?
Denken Sie daran, dass Perl bei der ersten Verwendung automatisch Variablen erstellt. Dies ist eine Funktion, kann jedoch manchmal Fehler verursachen, wenn Sie einen Variablennamen falsch eingeben. Das Pragma
use strict
hilft Ihnen dabei, diese Art von Fehlern zu finden. Es ist ärgerlich, bis Sie sich daran gewöhnt haben, aber Ihre Programmierung wird sich nach einer Weile erheblich verbessern und Sie können verschiedene Fehler machen.
Kompiliert das Skript?
Sie können mit dem -c
Schalter nach Kompilierungsfehlern suchen . Konzentrieren Sie sich auf die ersten gemeldeten Fehler. Spülen, wiederholen. Wenn Sie wirklich seltsame Fehler erhalten, überprüfen Sie, ob Ihr Skript die richtigen Zeilenenden hat. Wenn Sie im Binärmodus FTP ausführen, aus CVS auschecken oder etwas anderes, das die Übersetzung am Zeilenende nicht verarbeitet, sieht der Webserver Ihr Skript möglicherweise als eine große Zeile. Übertragen Sie Perl-Skripte im ASCII-Modus.
Beschwert sich das Skript über unsichere Abhängigkeiten?
Wenn sich Ihr Skript über unsichere Abhängigkeiten beschwert, verwenden Sie wahrscheinlich den -T
Schalter, um den Taint-Modus zu aktivieren. Dies ist eine gute Sache, da Sie weiterhin ungeprüfte Daten an die Shell übergeben. Wenn es sich beschwert, macht es seine Arbeit, um uns zu helfen, sicherere Skripte zu schreiben. Alle Daten, die von außerhalb des Programms (dh der Umgebung) stammen, gelten als fehlerhaft. Umgebungsvariablen wie PATH
und
LD_LIBRARY_PATH
sind besonders problematisch. Sie müssen diese auf einen sicheren Wert setzen oder sie vollständig deaktivieren, wie ich empfehle. Sie sollten sowieso absolute Pfade verwenden. Wenn sich die Verschmutzungsprüfung über etwas anderes beschwert, stellen Sie sicher, dass Sie die Daten nicht beschmutzt haben. Weitere Informationen finden Sie in der Perlsec-
Manpage.
Was passiert, wenn Sie es über die Befehlszeile ausführen?
Gibt das Skript das aus, was Sie erwarten, wenn es über die Befehlszeile ausgeführt wird? Wird der Header zuerst ausgegeben, gefolgt von einer Leerzeile? Denken
Sie daran, dass dies STDERR
möglicherweise zusammengeführt wird, STDOUT
wenn Sie sich in einem Terminal befinden (z. B. in einer interaktiven Sitzung), und aufgrund der Pufferung möglicherweise in einer durcheinandergebrachten Reihenfolge angezeigt wird. Aktivieren Sie die Autoflush-Funktion von Perl, indem Sie $|
einen echten Wert festlegen . Normalerweise wird dies $|++;
in CGI-Programmen angezeigt. Einmal eingestellt, geht jeder Druck und jedes Schreiben sofort zur Ausgabe, anstatt gepuffert zu werden. Sie müssen dies für jedes Dateihandle einstellen. Verwenden Sie select
diese Option, um das Standard-Dateihandle wie folgt zu ändern:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
In jedem Fall sollte als erstes der CGI-Header gefolgt von einer Leerzeile ausgegeben werden.
Was passiert, wenn Sie es über die Befehlszeile in einer CGI-ähnlichen Umgebung ausführen?
Die Webserverumgebung ist normalerweise viel eingeschränkter als Ihre Befehlszeilenumgebung und enthält zusätzliche Informationen zu der Anforderung. Wenn Ihr Skript über die Befehlszeile einwandfrei ausgeführt wird, können Sie versuchen, eine Webserverumgebung zu simulieren. Wenn das Problem auftritt, liegt ein Umgebungsproblem vor.
Deaktivieren oder entfernen Sie diese Variablen
PATH
LD_LIBRARY_PATH
- alle
ORACLE_*
Variablen
Stellen Sie diese Variablen ein
REQUEST_METHOD
(auf GET
, HEAD
oder POST
wie geeignet)
SERVER_PORT
(normalerweise auf 80 eingestellt)
REMOTE_USER
(wenn Sie Sachen mit geschütztem Zugriff machen)
Neuere Versionen von CGI.pm
(> 2.75) erfordern, dass das -debug
Flag das alte (nützliche) Verhalten erhält, sodass Sie es möglicherweise zu Ihren CGI.pm
Importen hinzufügen müssen .
use CGI qw(-debug)
Benutzt du die()
oder warn
?
Diese Funktionen werden gedruckt, STDERR
sofern Sie sie nicht neu definiert haben. Sie geben auch keinen CGI-Header aus. Sie können die gleiche Funktionalität mit Paketen wie CGI :: Carp erhalten
Was passiert, nachdem Sie den Browser-Cache geleert haben?
Wenn Sie der Meinung sind, dass Ihr Skript das Richtige tut und Sie die Anforderung manuell ausführen, erhalten Sie die richtige Ausgabe. Möglicherweise ist der Browser der Schuldige. Leeren Sie den Cache und setzen Sie die Cache-Größe beim Testen auf Null. Denken Sie daran, dass einige Browser wirklich dumm sind und keine neuen Inhalte neu laden, obwohl Sie dies anweisen. Dies ist besonders häufig der Fall, wenn der URL-Pfad identisch ist, sich der Inhalt jedoch ändert (z. B. dynamische Bilder).
Ist das Skript dort, wo Sie denken, dass es ist?
Der Dateisystempfad zu einem Skript steht nicht unbedingt in direktem Zusammenhang mit dem URL-Pfad zum Skript. Stellen Sie sicher, dass Sie das richtige Verzeichnis haben, auch wenn Sie ein kurzes Testskript schreiben müssen, um dies zu testen. Sind Sie außerdem sicher, dass Sie die richtige Datei ändern? Wenn Sie bei Ihren Änderungen keine Auswirkungen sehen, ändern Sie möglicherweise eine andere Datei oder laden eine Datei an die falsche Stelle hoch. (Dies ist übrigens meine häufigste Ursache für solche Probleme;)
Verwenden Sie CGI.pm
oder ein Derivat davon?
Wenn Ihr Problem bezieht sich die CGI - Eingabe zu parsen und Sie sind nicht ein weit getestetes Modul wie mit CGI.pm
, CGI::Request
,
CGI::Simple
oder CGI::Lite
, um das Modul verwenden und mit dem Leben auszukommen.
CGI.pm
verfügt über einen cgi-lib.pl
Kompatibilitätsmodus, mit dem Sie Eingabeprobleme aufgrund älterer CGI-Parser-Implementierungen lösen können.
Hast du absolute Pfade benutzt?
Wenn Sie externe Befehle mit system
, Back-Ticks oder anderen IPC-Funktionen ausführen
, sollten Sie einen absoluten Pfad zum externen Programm verwenden. Sie wissen nicht nur genau, was Sie ausführen, sondern vermeiden auch einige Sicherheitsprobleme. Wenn Sie Dateien zum Lesen oder Schreiben öffnen, verwenden Sie einen absoluten Pfad. Das CGI-Skript hat möglicherweise eine andere Vorstellung vom aktuellen Verzeichnis als Sie. Alternativ können Sie eine explizite chdir()
Aktion ausführen , um Sie an den richtigen Ort zu bringen.
Haben Sie Ihre Rückgabewerte überprüft?
Die meisten Perl-Funktionen zeigen an, ob sie funktioniert haben oder nicht, und setzen $!
auf Fehler. Haben Sie den Rückgabewert überprüft und $!
auf Fehlermeldungen überprüft ? Haben Sie überprüft,
$@
ob Sie verwendet haben eval
?
Welche Perl-Version verwenden Sie?
Die neueste stabile Version von Perl ist 5.28 (oder nicht, je nachdem, wann diese zuletzt bearbeitet wurde). Verwenden Sie eine ältere Version? Verschiedene Versionen von Perl haben möglicherweise unterschiedliche Vorstellungen von Warnungen.
Welchen Webserver verwenden Sie?
Verschiedene Server können in derselben Situation unterschiedlich handeln. Das gleiche Serverprodukt kann bei verschiedenen Konfigurationen unterschiedlich funktionieren. Nehmen Sie so viele dieser Informationen wie möglich in jede Hilfeanforderung auf.
Haben Sie die Serverdokumentation überprüft?
Seriöse CGI-Programmierer sollten so viel wie möglich über den Server wissen - einschließlich nicht nur der Serverfunktionen und des Serververhaltens, sondern auch der lokalen Konfiguration. Die Dokumentation für Ihren Server steht Ihnen möglicherweise nicht zur Verfügung, wenn Sie ein kommerzielles Produkt verwenden. Andernfalls sollte sich die Dokumentation auf Ihrem Server befinden. Wenn dies nicht der Fall ist, suchen Sie im Web danach.
Dies war früher nützlich, aber alle guten Plakate sind entweder gestorben oder abgewandert.
Es ist wahrscheinlich, dass jemand Ihr Problem schon einmal hatte und dass jemand (möglicherweise ich) es in dieser Newsgroup beantwortet hat. Obwohl diese Newsgroup ihre Blütezeit hinter sich hat, kann die gesammelte Weisheit aus der Vergangenheit manchmal nützlich sein.
Können Sie das Problem mit einem kurzen Testskript reproduzieren?
In großen Systemen kann es schwierig sein, einen Fehler aufzuspüren, da so viele Dinge passieren. Versuchen Sie, das Problemverhalten mit dem kürzestmöglichen Skript zu reproduzieren. Das Problem zu kennen ist der größte Teil der Lösung. Dies mag sicherlich zeitaufwändig sein, aber Sie haben das Problem noch nicht gefunden und haben keine Optionen mehr. :) :)
Hast du dich entschieden, einen Film anzusehen?
Ernsthaft. Manchmal sind wir so in das Problem verwickelt, dass wir eine "Wahrnehmungsverengung" (Tunnelblick) entwickeln. Wenn Sie eine Pause einlegen, eine Tasse Kaffee trinken oder ein paar Bösewichte in [Duke Nukem, Quake, Doom, Halo, COD] in die Luft jagen, erhalten Sie möglicherweise die neue Perspektive, die Sie benötigen, um das Problem erneut anzugehen.
Haben Sie das Problem ausgesprochen?
Wieder ernsthaft. Manchmal führt uns eine laute Erklärung des Problems zu unseren eigenen Antworten. Sprechen Sie mit dem Pinguin (Plüschtier), weil Ihre Mitarbeiter nicht zuhören. Wenn Sie sich für dieses ernsthafte Debugging-Tool interessieren (und ich empfehle es, wenn Sie das Problem bis jetzt noch nicht gefunden haben), lesen Sie vielleicht auch The Psychology of Computer Programming .