Этот ответ предназначен в качестве общей основы для работы через
проблемы со сценариями Perl CGI, изначально появившиеся в Perlmonks как Устранение неполадок сценариев Perl CGI . Это не полное руководство для каждого
проблема, с которой вы можете столкнуться, ни учебник по исправлению ошибок. Это
это всего лишь кульминация моего опыта отладки CGI-скриптов в течение двадцати (плюс!) лет. На этой странице было много разных домов, и мне кажется,
чтобы забыть, что он существует, поэтому я добавляю его в StackOverflow. Вы
можете присылать мне любые комментарии или предложения по адресу
bdfoy@cpan.org. Это также вики сообщества, но не сходите с ума. :)
Используете ли вы встроенные функции Perl, чтобы помочь вам найти проблемы?
Включите предупреждения, чтобы Perl предупреждал вас о сомнительных частях вашего кода. Вы можете сделать это из командной строки с ключом -w
, чтобы вам не приходилось менять код или добавлять прагму к каждому файлу:
% perl -w program.pl
Однако вы должны заставить себя всегда очищать сомнительный код, добавив прагму warnings
ко всем своим файлам:
use warnings;
Если вам требуется больше информации, чем короткое предупреждающее сообщение, используйте прагму diagnostics
для получения дополнительной информации или посмотрите документацию perldiag :
use diagnostics;
Сначала вы вывели действительный заголовок CGI?
Сервер ожидает, что первый вывод скрипта CGI будет заголовком CGI. Обычно это может быть просто print "Content-type: text/plain\n\n";
или с CGI.pm и его производными print header()
. Некоторые серверы чувствительны к выводу ошибок (на STDERR
), появляющимся перед стандартным выводом (на STDOUT
).
Попробуйте отправить ошибки в браузер
Добавить эту строку
use CGI::Carp 'fatalsToBrowser';
к вашему сценарию. Это также отправляет ошибки компиляции в окно браузера. Обязательно удалите это, прежде чем переходить в производственную среду, так как дополнительная информация может представлять угрозу безопасности.
Что сказал журнал ошибок?
Серверы ведут журналы ошибок (или они должны, по крайней мере).
Ошибка вывода с сервера и из вашего скрипта должна
показать там. Найдите журнал ошибок и посмотрите, что он говорит.
Там нет стандартного места для файлов журнала. Посмотри в
Конфигурация сервера для их расположения, или спросите сервер
админ. Вы также можете использовать такие инструменты, как CGI :: Carp
сохранить свои собственные файлы журнала.
Каковы разрешения скрипта?
Если вы видите такие ошибки, как «Отказано в доступе» или «Способ не разрешен»
реализовано ", это, вероятно, означает, что ваш сценарий не
читаемый и исполняемый пользователем веб-сервера. На вкус
Unix, изменение режима на 755 рекомендуется:
chmod 755 filename
. Никогда не устанавливайте режим на 777!
Вы используете use strict
?
Помните, что Perl автоматически создает переменные, когда
Вы сначала используете их. Это особенность, но иногда может
вызвать ошибки, если вы неправильно набрали имя переменной. Прагма
use strict
поможет вам найти такие
ошибки. Это раздражает, пока вы не привыкнете к этому, но ваш
программирование значительно улучшится через некоторое время и
Вы будете свободны совершать разные ошибки.
Сценарий компилируется?
Вы можете проверить ошибки компиляции, используя -c
переключатель. Сконцентрируйтесь на первых зарегистрированных ошибках. Полоскание,
повторение. Если вы получаете действительно странные ошибки, проверьте
убедитесь, что ваш скрипт имеет правильные окончания строк. если ты
FTP в двоичном режиме, извлечение из CVS или что-то еще, что
не обрабатывает перевод конца строки, веб-сервер может видеть
Ваш сценарий как одна большая строка. Перенести Perl-скрипты в ASCII
режим.
Сценарий жалуется на небезопасные зависимости?
Если ваш скрипт жалуется на небезопасные зависимости, вы
вероятно, используете переключатель -T
для включения режима загрязнения, который
хорошая вещь, поскольку она позволяет передавать непроверенные данные в оболочку. Если
он жалуется, что делает свою работу, чтобы помочь нам написать более безопасные сценарии. любой
данные, происходящие из-за пределов программы (то есть из среды)считается испорченным. Переменные среды, такие как PATH
и
LD_LIBRARY_PATH
особенно хлопотно Вы должны установить их на безопасное значение
или сбросьте их полностью, как я рекомендую. Вы должны использовать абсолют
дорожки в любом случае. Если проверка порчи жалуется на что-то другое,
убедитесь, что у вас нет данных. См perlsec
Страница man для подробностей.
Что происходит, когда вы запускаете его из командной строки?
Выводит ли скрипт то, что вы ожидаете при запуске из
командная строка? Сначала выводится заголовок, а затем
пустая строка? Помните, что STDERR
может быть объединено с STDOUT
если вы находитесь на терминале (например, интерактивный сеанс), и
из-за буферизации может отображаться в беспорядочном порядке. Включи
Функция автоматической промывки в Perl, установив $|
в
истинное значение Обычно вы можете увидеть $|++;
в
CGI программы. После установки, каждая печать и запись будет
немедленно перейти к выводу, а не буферизироваться.
Вы должны установить это для каждого дескриптора файла. Используйте select
для
измените дескриптор файла по умолчанию, например:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
В любом случае, первым выводом должен быть заголовок CGI
сопровождаемый пустой строкой.
Что происходит, когда вы запускаете его из командной строки в среде, подобной CGI?
Среда веб-сервера обычно намного более ограничена
чем ваша среда командной строки, и имеет дополнительные
информация о запросе. Если ваш скрипт работает нормально
из командной строки вы можете попробовать симулировать веб-сервер
среда. Если проблема появляется, у вас есть
проблема окружающей среды.
Сброс или удаление этих переменных
PATH
LD_LIBRARY_PATH
- все
ORACLE_*
переменные
Установить эти переменные
REQUEST_METHOD
(установите в GET
, HEAD
или POST
в зависимости от ситуации)
SERVER_PORT
(обычно устанавливается на 80)
REMOTE_USER
(если вы делаете защищенный доступ)
Последние версии CGI.pm
(> 2,75) требуют флаг -debug
для
получить старое (полезное) поведение, поэтому вам, возможно, придется добавить его в
ваш CGI.pm
импорт.
use CGI qw(-debug)
Вы используете die()
или warn
?
Эти функции выводятся на STDERR
, если вы не переопределили
их. Они также не выводят заголовок CGI. Ты можешь получить
та же функциональность с пакетами, такими как CGI :: Carp
Что происходит после очистки кэша браузера?
Если вы считаете, что ваш сценарий работает правильно, и
когда вы выполняете запрос вручную, вы получаете право
Вывод, браузер может быть виновником. Очистить кеш
и установите размер кэша на ноль во время тестирования. Помни что
некоторые браузеры действительно глупы и не будут перезагружаться
новый контент, даже если вы скажете это сделать. Это
особенно распространены в тех случаях, когда путь URL является
то же самое, но содержимое меняется (например, динамические изображения).
Сценарий, где вы думаете, это?
Путь файловой системы к сценарию не обязательно
напрямую связано с URL-адресом пути к скрипту. Удостовериться
у вас есть правильный каталог, даже если вам нужно написать
короткий тестовый скрипт, чтобы проверить это. Кроме того, вы уверены,
что вы модифицируете правильный файл? Если ты не видишь
любой эффект с вашими изменениями, вы можете изменить
другой файл или загрузка файла в неправильное место.
(Это, кстати, моя самая частая причина таких неприятностей
;) * * 1138
Используете ли вы CGI.pm
или его производное?
Если ваша проблема связана с анализом ввода CGI и вы
не используются широко протестированные модули, такие как CGI.pm
, CGI::Request
,
CGI::Simple
или CGI::Lite
, используйте модуль и продолжайте жить.
CGI.pm
имеет режим совместимости cgi-lib.pl
, который может помочь вам решить ввод
проблемы из-за более старых реализаций CGI-парсера.
Вы использовали абсолютные пути?
Если вы запускаете внешние команды с
system
, обратные тики или другие возможности IPC,
Вы должны использовать абсолютный путь к внешней программе.Не только вы точно знаете, что вы бежите, но вы
также избегайте проблем с безопасностью. Если вы открываете
файлы для чтения или записи, используйте абсолютный путь.
Сценарий CGI может иметь другое представление о текущем
каталог, чем вы. Кроме того, вы можете сделать
Явный chdir()
, чтобы поставить вас в нужное место.
Вы проверяли свои возвращаемые значения?
Большинство функций Perl сообщит вам, работали они или нет
и установит $!
при сбое. Вы проверили
вернуть значение и проверить $!
на наличие сообщений об ошибках? Ты проверил
$@
если вы использовали eval
?
Какую версию Perl вы используете?
Последняя стабильная версия Perl - 5.28 (или нет, в зависимости от того, когда это последний раз редактировалось). Вы используете старую версию? Различные версии Perl могут иметь разные представления о предупреждениях.
Какой веб-сервер вы используете?
Различные серверы могут работать по-разному в одном и том же
ситуация. Один и тот же серверный продукт может работать по-разному с
разные конфигурации. Включите как можно больше этого
информация, как вы можете в любой просьбе о помощи.
Вы проверяли документацию сервера?
Серьезные программисты CGI должны знать как можно больше о
сервер, насколько это возможно - включая не только функции сервера
и поведение, но и локальная конфигурация.
документация для вашего сервера может быть недоступна для вас
если вы используете коммерческий продукт. В противном случае
документация должна быть на вашем сервере. Если это не так, посмотрите
для этого в Интернете.
Это использование полезно, но все хорошие плакаты либо умерли, либо исчезли.
Вполне вероятно, что у кого-то была ваша проблема раньше,
и что кто-то (возможно, я) ответил на это в этом
телеконференция. Хотя эта новостная группа пережила свой расцвет, собранная мудрость прошлого иногда может быть полезна.
Можете ли вы воспроизвести проблему с помощью короткого тестового сценария?
В больших системах может быть трудно отследить ошибку
поскольку так много всего происходит. Попробуйте воспроизвести проблему
поведение с кратчайшим сценарием. Зная проблему
это большая часть исправления. Это, конечно, может занять много времени, но вы
еще не нашли проблему, и у вас заканчиваются варианты. :)
Вы решили пойти посмотреть фильм?
Серьезно. Иногда мы можем быть настолько погружены в проблему, что мы
развить «сужение восприятия» (туннельное зрение). Сделать перерыв,
выпить чашку кофе или убить плохих парней в [Duke Nukem, Quake, Doom, Halo, COD] может дать вам
свежая перспектива, с которой вам нужно заново подойти к проблеме.
Вы озвучили проблему?
Серьезно, снова. Иногда объясняю проблему вслух
приводит нас к нашим собственным ответам. Поговорите с пингвином (плюшевая игрушка), потому что
ваши коллеги не слушают. Если вы заинтересованы в этом
как серьезный инструмент отладки (и я рекомендую его, если у вас нет
нашел проблему к настоящему времени), вы также можете прочитать Психология
компьютерного программирования .