Советы по отладке

advertisement
Советы по отладке
CGI-программы — не самые простые в отладке, по сложности они способны сравниться лишь с отладкой драйверов. Вся
сложность заключается в том, что скрипт выполняется не как обычная программа. Он выполняется в специальной среде
сервера, которая создается при клиентском запросе, к тому же он исполняется не из под вашего аккаунта, а на
непривилегированном уровне.
Если скрипт не исполняется потому, что вы допустили синтаксические ошибки, то самих этих ошибок вы не увидите, на экране
будет только “Internal Server Error”. Из-за чего она произошла, вы можете только гадать.
Также если вы забыли задать к какому-то файлу нужные права доступа, то тоже будет трудно выяснить в чем причина ошибки
(если конечно к этому вы не готовы).
Приступим к отладке
Начнем с того, что у нас есть скрипт test.cgi, мы уже сделали его исполняемым chmod +x test.cgi. Простейший способ проверить
его на ошибки — это команда perl-c test.cgi.
Ключ -c говорит Perl, что надо только проверить синтаксис. Все сообщения об ошибках вы можете видеть и поправить. Более
тяжелый случай состоит в том, когда Perl встроен в Web-Сервер, причем версии разные. Так до недавнего времени было на
uic’е.
Тот Perl, с которым работаем в командной строке — 4-й версии, а на сервере стоит 5-й версии. Если ваша CGI-программа
использует при этом какие-нибудь преимущества 5-й версии (например, объектно-ориентированные модули), то вы думаете
отладить ее нельзя? Ошибаетесь!
Закомментируйте всю вашу программу, то есть, перед каждой строчкой поставьте символ “#”. Затем добавьте вот такие
строчки:
print "Content-Type: text/html\ n\ n"; print "<HTML>Test</HTML>"; exit;
Должно получиться так:
#!/usr/bin/perl
#test.cgi
print "Content-Type: text/html\ n\ n";
print "<HTML>Test</HTML>";
exit; #Программа как вы понимаете выполняется только до этого места
#
#if($ENV{ ‘REQUEST_METHOD’} eq ‘GET’){ $query=$ENV{ ‘QUERY_STRING’} }
#else{ sysread STDIN,$query,$ENV{ ‘CONTENT_LENGTH’} ;}
#if($query eq ‘’){
# @formfields=split /&/,$query;
# .......
# ........
А теперь запускайте скрипт. Естественно, он выдаст одно слово “Test”. Разкомментируйте несколько строчек. Еще раз запустите
скрипт. Он опять выдаст “Test”. Значит синтаксически эти разкомментированые строчки были правильными. И так далее...
Если в очередной раз после разкомментирования вы запустили скрипт и получили “Internal Server Error” — значит в этих
строках содержалась какая-та синтаксическая ошибка.
Этот способ отловки синтаксических ошибок трудоемок, но к нему придется прибегнуть, если ваш скрипт написан под ту
версию Perl, что на сервере, а не под ту, что у вас.
Узнать версию Perl можно при помощи команды: perl -v
Когда мы отловили в нашем скрипте все синтаксические ошибки, он заработал, но это не значит, что он работает правильно.
Что еще можно посоветовать при отладке ошибок CGI-скриптов, возникающих во время выполнения программы. Допустим,
какой-то файл не открылся. Конечно, показывать перепуганному пользователю эти технические подробности ни к чему,
поэтому заведите себе специальный файл debug.txt, и пусть ваши скрипты пишут в этот файл причины своих ошибок и сбоев,
да и вообще о всех непредвиденных событиях.
Это можно реализовать так:
sub debug_err{
open(DEBUGFILE,">>debug.txt");
print DEBUGFILE $ENV{ ‘SCRIPT_NAME’} .’ ‘.scalar localtime.’ ‘.@_."\ n";
close(DEBUGFILE);
}
Примеры использования (напомню, что встроенная переменная Perl $! содержит сообщение о причине последней ошибки,
поэтому включайте ее всегда в свои сообщения):
open(F,"+<$myfile") || debug_err("Cannot open $myfile $!");
seek(F,0,0) || debug_err("Cannot seek $myfile $!");
connect(SOCKET,$paddr)|| debug_err("Cannot connect to $remote $!");
......
Потом можно периодически заглядывать в этот файл debug.txt и смотреть, какие ошибки встречались при работе ваших
скриптов. Таким образом, ваши скрипты сами помогают в своей отладке.
Также может оказать помощь (может и не оказать) просмотр http’шных логов. Все обращения к URL на сервере, и все
возникающие при этом ошибки идут в логи сервера httpd.
Необходимо сразу предупредить — размеры этих логов (даже на средних размеров сервере) достигает десятков мегабайт.
Поэтому даже не пытайтесь их вот так просто посмотреть. Лучше воспользуйтесь такими утилитами, как grep, head, tail, more,
less.
Кстати, необходимо сказать о причине еще одной (совсем не очевидной) ошибки.
Если вы набрали скрипт у себя дома на компьютере, то полученный скрипт состоит из текста в DOS’ом формате, а не в Unix’ом,
так что имейте это ввиду. Запускать вам его придется в системе Unix, так что следует перевести программный текст в нужный
формат.
Дело в том, что в системах DOS и Windows для разделения строк используется не один — “символ новой строки” (“\ n”), а пара
символов — “возврат каретки” (“\ r”) и “символ новой строки” (“\ n”).
Для простых HTML-файлов это не типично — браузеры игнорируют такие символы при выводе. Но скрипт является программой.
А в программе никаких символов возврата каретки быть не должно! Особенно в первой строке.
Потому что, когда операционная система запускает скрипт, она определяет какое приложение запустить для обработки данного
скрипта именно по первой строке.
В первой строке, как вы знаете содержится #!/usr/bin/perl или #!/usr/local/bin/perl. Поэтому, при запуске скрипта mysrcipt
(это кстати вы можете сами увидеть с помощью команд top и ps), система запускает команду /usr/bin/perl mysript.
А теперь представьте — что будет если не убрать символ возврата каретки из Windows-файла.
Получится
#!/usr/bin/perl<возврат каретки>
и естественно, что такого приложения нет, и, следовательно, попытка выполнить команду
/usr/bin/perl<возврат каретки> mysript
ни к чему не приведет!
Download