Ta odpowiedź ma służyć jako ogólne ramy do rozwiązywania problemów ze skryptami Perl CGI i pierwotnie pojawiła się w Perlmonks jako Rozwiązywanie problemów ze skryptami Perl CGI . Nie jest to kompletny przewodnik po każdym napotkanym problemie ani samouczek dotyczący usuwania błędów. To tylko kulminacja mojego doświadczenia w debugowaniu skryptów CGI przez dwadzieścia (plus!) Lat. Wygląda na to, że ta strona miała wiele różnych domów i wydaje mi się, że zapomniałem, że istnieje, więc dodaję ją do StackOverflow. Możesz przesłać mi wszelkie uwagi lub sugestie na adres bdfoy@cpan.org. To także wiki społeczności, ale nie zwariuj. :)
Czy używasz wbudowanych funkcji Perla, aby pomóc Ci znaleźć problemy?
Włącz ostrzeżenia, aby Perl ostrzegał Cię o wątpliwych częściach kodu. Możesz to zrobić z wiersza poleceń za pomocą -w
przełącznika, więc nie musisz zmieniać żadnego kodu ani dodawać pragmy do każdego pliku:
% perl -w program.pl
Powinieneś jednak zmusić się do zawsze wyjaśniania wątpliwego kodu, dodając warnings
pragmę do wszystkich swoich plików:
use warnings;
Jeśli potrzebujesz więcej informacji niż krótki komunikat ostrzegawczy, skorzystaj z diagnostics
pragmy, aby uzyskać więcej informacji, lub zajrzyj do dokumentacji perldiag :
use diagnostics;
Czy najpierw wyprowadziłeś prawidłowy nagłówek CGI?
Serwer oczekuje, że pierwszym wyjściem ze skryptu CGI będzie nagłówek CGI. Typowo, które mogą być proste, jak print "Content-type: text/plain\n\n";
i z CGI.pm i jego pochodnych print header()
. Niektóre serwery są wrażliwe na błąd wyjścia (on STDERR
) pojawiający się przed standardowym wyjściem (on STDOUT
).
Spróbuj wysłać błędy do przeglądarki
Dodaj tę linię
use CGI::Carp 'fatalsToBrowser';
do swojego skryptu. Spowoduje to również wysłanie błędów kompilacji do okna przeglądarki. Pamiętaj, aby usunąć to przed przejściem do środowiska produkcyjnego, ponieważ dodatkowe informacje mogą stanowić zagrożenie dla bezpieczeństwa.
Co zawiera dziennik błędów?
Serwery przechowują dzienniki błędów (a przynajmniej powinny). Powinien tam pojawić się błąd wyjściowy z serwera i skryptu. Znajdź dziennik błędów i zobacz, co zawiera. Nie ma standardowego miejsca na pliki dziennika. Sprawdź w konfiguracji serwera ich lokalizację lub zapytaj administratora serwera. Możesz także użyć narzędzi takich jak CGI :: Carp
aby zachować własne pliki dziennika.
Jakie są uprawnienia skryptu?
Jeśli widzisz błędy, takie jak „Odmowa uprawnień” lub „Metoda nie zaimplementowana”, prawdopodobnie oznacza to, że Twój skrypt nie jest czytelny i nie może być wykonywany przez użytkownika serwera WWW. W przypadku wersji Unix zaleca się zmianę trybu na 755:
chmod 755 filename
. Nigdy nie ustawiaj trybu na 777!
Czy używasz use strict
?
Pamiętaj, że Perl automatycznie tworzy zmienne, gdy używasz ich po raz pierwszy. Jest to funkcja, ale czasami może powodować błędy, jeśli błędnie wpiszesz nazwę zmiennej. Pragma
use strict
pomoże ci znaleźć tego rodzaju błędy. Jest to denerwujące, dopóki się do tego nie przyzwyczaisz, ale po pewnym czasie programowanie znacznie się poprawi i będziesz mógł popełniać różne błędy.
Czy skrypt się kompiluje?
Możesz sprawdzić błędy kompilacji za pomocą -c
przełącznika. Skoncentruj się na pierwszych zgłoszonych błędach. Spłucz, powtórz. Jeśli otrzymujesz naprawdę dziwne błędy, sprawdź, czy Twój skrypt ma prawidłowe zakończenia linii. Jeśli korzystasz z FTP w trybie binarnym, wyewidencjonujesz z CVS lub coś innego, co nie obsługuje tłumaczenia końca linii, serwer WWW może zobaczyć twój skrypt jako jedną dużą linię. Prześlij skrypty Perla w trybie ASCII.
Czy skrypt narzeka na niezabezpieczone zależności?
Jeśli twój skrypt narzeka na niezabezpieczone zależności, prawdopodobnie używasz -T
przełącznika do włączania trybu skażenia, co jest dobrą rzeczą, ponieważ zapewnia przekazywanie niezaznaczonych danych do powłoki. Jeśli narzeka, wykonuje swoją pracę, pomagając nam pisać bezpieczniejsze skrypty. Wszelkie dane pochodzące spoza programu (tj. Ze środowiska) są uważane za skażone. Zmienne środowiskowe, takie jak PATH
i
LD_LIBRARY_PATH
są szczególnie kłopotliwe. Musisz ustawić je na bezpieczną wartość lub całkowicie je wyłączyć, tak jak zalecam. I tak powinieneś używać ścieżek bezwzględnych. Jeśli sprawdzanie skażeń narzeka na coś innego, upewnij się, że dane zostały oczyszczone. Szczegółowe informacje można znaleźć na
stronie podręcznika perlsec .
Co się stanie, gdy uruchomisz go z wiersza poleceń?
Czy skrypt wyświetla to, czego oczekujesz po uruchomieniu z wiersza poleceń? Czy najpierw wyjście nagłówka, po którym następuje pusty wiersz? Pamiętaj, że STDERR
może zostać scalone z, STDOUT
jeśli jesteś na terminalu (np. Sesja interaktywna), a ze względu na buforowanie może pojawić się w pomieszanej kolejności. Włącz funkcję autoflush Perla, ustawiając $|
wartość true. Zwykle można to zobaczyć $|++;
w programach CGI. Po ustawieniu każde drukowanie i zapis będzie natychmiast trafiać na wyjście, a nie być buforowane. Musisz to ustawić dla każdego uchwytu pliku. Użyj, select
aby zmienić domyślny uchwyt pliku, na przykład:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
Tak czy inaczej, pierwszym wyjściem powinien być nagłówek CGI, po którym powinien znajdować się pusty wiersz.
Co się stanie, gdy uruchomisz go z wiersza poleceń w środowisku podobnym do CGI?
Środowisko serwera WWW jest zwykle dużo bardziej ograniczone niż środowisko wiersza poleceń i zawiera dodatkowe informacje o żądaniu. Jeśli twój skrypt działa dobrze z wiersza poleceń, możesz spróbować zasymulować środowisko serwera WWW. Jeśli pojawi się problem, masz problem ze środowiskiem.
Cofnij ustawienie lub usuń te zmienne
PATH
LD_LIBRARY_PATH
- wszystkie
ORACLE_*
zmienne
Ustaw te zmienne
REQUEST_METHOD
(wartość GET
, HEAD
lubPOST
, jak w tym przypadku)
SERVER_PORT
(zwykle ustawione na 80)
REMOTE_USER
(jeśli robisz rzeczy z chronionym dostępem)
Najnowsze wersje CGI.pm
(> 2.75) wymagają -debug
flagi, aby uzyskać stare (przydatne) zachowanie, więc może być konieczne dodanie jej do CGI.pm
importu.
use CGI qw(-debug)
Czy używasz die()
lubwarn
?
Te funkcje są drukowane, STDERR
chyba że zostały przedefiniowane. Nie wyświetlają też nagłówka CGI. Możesz uzyskać tę samą funkcjonalność dzięki pakietom takim jak CGI :: Carp
Co się dzieje po wyczyszczeniu pamięci podręcznej przeglądarki?
Jeśli uważasz, że twój skrypt działa właściwie, a gdy wykonujesz żądanie ręcznie, otrzymasz odpowiednie dane wyjściowe, przyczyną może być przeglądarka. Wyczyść pamięć podręczną i ustaw jej rozmiar na zero podczas testowania. Pamiętaj, że niektóre przeglądarki są naprawdę głupie i nie ładują ponownie nowej zawartości, mimo że każesz im to zrobić. Jest to szczególnie powszechne w przypadkach, gdy ścieżka adresu URL jest taka sama, ale zmienia się zawartość (np. Dynamiczne obrazy).
Czy scenariusz jest tam, gdzie myślisz?
Ścieżka systemu plików do skryptu niekoniecznie jest bezpośrednio związana ze ścieżką adresu URL do skryptu. Upewnij się, że masz właściwy katalog, nawet jeśli musisz napisać krótki skrypt testowy, aby to przetestować. Ponadto, czy na pewno modyfikujesz właściwy plik? Jeśli nie widzisz żadnego efektu swoich zmian, być może modyfikujesz inny plik lub przesyłasz plik w niewłaściwe miejsce. (Nawiasem mówiąc, to moja najczęstsza przyczyna takich kłopotów;)
Używasz tego CGI.pm
czy jest to pochodna?
Jeśli problem jest związany z parsowania wejście CGI i nie używasz szeroko przetestowany moduł jak CGI.pm
, CGI::Request
,
CGI::Simple
lub CGI::Lite
użyć modułu i zabrać się za życia.
CGI.pm
macgi-lib.pl
tryb zgodności, który może pomóc w rozwiązywaniu problemów z wejściem ze względu na starsze implementacje parsera CGI.
Czy korzystałeś ze ścieżek bezwzględnych?
Jeśli używasz poleceń zewnętrznych z
system
zaznaczeniami wstecznymi lub innymi udogodnieniami IPC, powinieneś użyć bezwzględnej ścieżki do programu zewnętrznego. Nie tylko wiesz dokładnie, co uruchamiasz, ale także unikasz niektórych problemów związanych z bezpieczeństwem. Jeśli otwierasz pliki do odczytu lub zapisu, użyj ścieżki bezwzględnej. Skrypt CGI może mieć inne pojęcie o bieżącym katalogu niż ty. Alternatywnie możesz zrobić wyraźną wiadomość, chdir()
aby umieścić Cię we właściwym miejscu.
Czy sprawdziłeś wartości zwracane?
Większość funkcji Perla powie ci, czy zadziałały, czy nie, i ustawią się $!
w przypadku awarii. Czy sprawdziłeś wartość zwracaną i sprawdziłeś $!
komunikaty o błędach? Czy sprawdziłeś,
$@
czy używałeś eval
?
Której wersji Perla używasz?
Najnowsza stabilna wersja Perla to 5.28 (lub nie, w zależności od tego, kiedy była ostatnio edytowana). Czy używasz starszej wersji? Różne wersje Perla mogą mieć różne koncepcje ostrzeżeń.
Z jakiego serwera WWW korzystasz?
W tej samej sytuacji różne serwery mogą działać inaczej. Ten sam produkt serwerowy może działać inaczej w różnych konfiguracjach. Uwzględnij jak najwięcej tych informacji w każdej prośbie o pomoc.
Czy sprawdziłeś dokumentację serwera?
Poważni programiści CGI powinni wiedzieć jak najwięcej o serwerze - w tym nie tylko o funkcjach i zachowaniu serwera, ale także o lokalnej konfiguracji. Dokumentacja serwera może nie być dostępna, jeśli używasz produktu komercyjnego. W przeciwnym razie dokumentacja powinna znajdować się na serwerze. Jeśli tak nie jest, poszukaj go w sieci.
To zastosowanie ma być przydatne, ale wszystkie dobre plakaty albo umarły, albo odeszły.
Jest prawdopodobne, że ktoś miał już wcześniej twój problem i że ktoś (prawdopodobnie ja) odpowiedział na niego w tej grupie dyskusyjnej. Chociaż ta grupa dyskusyjna minęła swój okres świetności, zebrana wiedza z przeszłości może czasami być przydatna.
Czy możesz odtworzyć problem za pomocą krótkiego skryptu testowego?
W dużych systemach może być trudno wyśledzić błąd, ponieważ dzieje się tak wiele rzeczy. Spróbuj odtworzyć problematyczne zachowanie za pomocą możliwie najkrótszego skryptu. Znajomość problemu to większość rozwiązania. Może to być z pewnością czasochłonne, ale nie znalazłeś jeszcze problemu i wyczerpują się opcje. :)
Zdecydowałeś się obejrzeć film?
Poważnie. Czasami możemy być tak pochłonięci problemem, że rozwijamy „zwężenie percepcyjne” (widzenie tunelowe). Przerwa, wypicie filiżanki kawy lub zabicie złych facetów w [Duke Nukem, Quake, Doom, Halo, COD] może dać ci świeżą perspektywę, której potrzebujesz, aby ponownie podejść do problemu.
Czy wypowiedziałeś problem?
Poważnie znowu. Czasami głośne wyjaśnienie problemu prowadzi nas do własnych odpowiedzi. Porozmawiaj z pingwinem (pluszowa zabawka), ponieważ Twoi współpracownicy nie słuchają. Jeśli interesuje Cię to jako poważne narzędzie do debugowania (i polecam je, jeśli do tej pory nie znalazłeś problemu), możesz również przeczytać Psychologię programowania komputerowego .