Этот ответ предназначен в качестве общей основы для решения проблем со сценариями Perl CGI и первоначально появился на Perlmonks как Troubleshooting Perl CGI Scripts . Это не полное руководство по каждой проблеме, с которой вы можете столкнуться, и не руководство по устранению ошибок. Это просто кульминация моего опыта отладки скриптов 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
.
Что происходит, когда вы запускаете его из командной строки?
Выводит ли сценарий то, что вы ожидаете, при запуске из командной строки? Сначала выводится заголовок, а за ним - пустая строка? Помните, что это STDERR
может быть объединено, STDOUT
если вы находитесь на терминале (например, в интерактивном сеансе), и из-за буферизации может отображаться в беспорядочном порядке. Включите функцию автозапуска Perl, установив $|
значение true. Обычно вы можете видеть это $|++;
в программах 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-путем к сценарию. Убедитесь, что у вас есть правильный каталог, даже если вам нужно написать короткий тестовый сценарий, чтобы проверить это. Кроме того, уверены ли вы, что изменяете правильный файл? Если вы не видите никакого эффекта от ваших изменений, возможно, вы изменяете другой файл или загружаете файл не в то место. (Это, кстати, самая частая моя причина таких неприятностей;)
Вы используете его 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], вы можете по-новому взглянуть на проблему.
Вы озвучили проблему?
Снова серьезно. Иногда объяснение проблемы вслух приводит нас к нашим собственным ответам. Поговорите с пингвином (плюшевая игрушка), потому что ваши коллеги не слушают. Если вы заинтересованы в этом как в серьезном инструменте отладки (и я рекомендую его, если вы еще не нашли проблему), вы также можете прочитать Психологию компьютерного программирования .