Ця відповідь призначена як загальна основа для вирішення проблем зі скриптами 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
є особливо клопіткими. Ви повинні встановити їх на безпечне значення або зняти їх повністю, як я рекомендую. Ви все одно повинні використовувати абсолютні шляхи. Якщо під час перевірки на скарги скаржиться на щось інше, переконайтеся, що ви зберегли дані. Докладні відомості див. На
сторінці man perlsec .
Що відбувається, коли ви запустите його з командного рядка?
Чи виводить сценарій те, що ви очікуєте при запуску з командного рядка? Спочатку виводиться заголовок, а потім - порожній рядок? Пам'ятайте, що це 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-адресою до сценарію. Переконайтеся, що у вас є правильний каталог, навіть якщо вам доведеться написати короткий тестовий сценарій, щоб перевірити це. Крім того, ви впевнені, що ви змінюєте правильний файл? Якщо ви не бачите жодного ефекту зі своїми змінами, можливо, ви модифікуєте інший файл або завантажуєте файл в інше місце. (Це, до речі, моя найчастіша причина таких неприємностей;)
Ви використовуєте 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 повинні знати якомога більше про сервер - включаючи не тільки функції та поведінку сервера, але й локальну конфігурацію. Документація для вашого сервера може бути недоступною для вас, якщо ви використовуєте комерційний продукт. В іншому випадку документація повинна бути на вашому сервері. Якщо це не так, шукайте його в Інтернеті.
Це корисне використання, але всі хороші плакати або загинули, або розгубилися.
Цілком імовірно, що хтось раніше мав вашу проблему, і хтось (можливо, я) відповів на це в цій групі новин. Хоча ця група новин минула свій розквіт, зібрана мудрість з минулого часом може бути корисною.
Чи можете ви відтворити проблему за допомогою короткого тестового сценарію?
У великих системах виявити помилку може бути важко, оскільки так багато справ відбувається. Спробуйте відтворити проблемну поведінку за допомогою найкоротшого сценарію. Знання проблеми - це більшість виправлень. Це, можливо, забирає багато часу, але ви ще не знайшли проблему і не вистачає варіантів. :)
Ви вирішили піти фільм?
Серйозно. Іноді ми можемо настільки заплутатися в проблемі, що розвиваємо «перцептивне звуження» (тунельне бачення). Перерва, випити чашку кави чи вибуху поганих хлопців у [Герцог Нукем, Квайк, Дум, Ореол] може дати вам нову перспективу, що вам потрібно знову підійти до проблеми.
Ви проголосили проблему?
Серйозно знову. Іноді пояснення проблеми вголос призводить нас до власних відповідей. Поговоріть з пінгвіном (плюшевою іграшкою), оскільки ваші колеги не слухають. Якщо ви зацікавлені в цьому як серйозний інструмент налагодження (і я рекомендую це, якщо ви до цього часу не знайшли проблеми), ви також можете прочитати «Психологія комп’ютерного програмування» .