Jawaban ini dimaksudkan sebagai kerangka kerja umum untuk mengatasi masalah dengan skrip Perl CGI dan aslinya muncul di Perlmonks sebagai Pemecahan Masalah Skrip Perl CGI . Ini bukan panduan lengkap untuk setiap masalah yang mungkin Anda temui, atau tutorial tentang bug squashing. Ini hanyalah puncak dari pengalaman saya men-debug skrip CGI selama dua puluh (plus!) Tahun. Halaman ini tampaknya memiliki banyak rumah yang berbeda, dan saya sepertinya lupa bahwa halaman ini ada, jadi saya menambahkannya ke StackOverflow. Anda dapat mengirimkan komentar atau saran apa pun kepada saya di bdfoy@cpan.org. Ini juga wiki komunitas, tetapi jangan terlalu gila. :)
Apakah Anda menggunakan fitur bawaan Perl untuk membantu Anda menemukan masalah?
Aktifkan peringatan agar Perl memperingatkan Anda tentang bagian-bagian kode yang meragukan. Anda dapat melakukan ini dari baris perintah dengan -w
sakelar sehingga Anda tidak perlu mengubah kode apa pun atau menambahkan pragma ke setiap file:
% perl -w program.pl
Namun, Anda harus memaksakan diri untuk selalu membersihkan kode yang dipertanyakan dengan menambahkan warnings
pragma ke semua file Anda:
use warnings;
Jika Anda membutuhkan lebih banyak informasi daripada pesan peringatan singkat, gunakan diagnostics
pragma untuk mendapatkan lebih banyak informasi, atau lihat di dokumentasi perldiag :
use diagnostics;
Apakah Anda mengeluarkan header CGI yang valid terlebih dahulu?
Server mengharapkan keluaran pertama dari skrip CGI menjadi header CGI. Biasanya itu mungkin sesederhana print "Content-type: text/plain\n\n";
atau dengan CGI.pm dan turunannya print header()
,. Beberapa server sensitif terhadap keluaran kesalahan (on STDERR
) yang muncul sebelum keluaran standar (on STDOUT
).
Coba kirim kesalahan ke browser
Tambahkan baris ini
use CGI::Carp 'fatalsToBrowser';
ke skrip Anda. Ini juga mengirimkan kesalahan kompilasi ke jendela browser. Pastikan untuk menghapus ini sebelum pindah ke lingkungan produksi, karena informasi tambahan dapat menimbulkan risiko keamanan.
Apa isi log kesalahan?
Server menyimpan log kesalahan (atau seharusnya, setidaknya). Keluaran kesalahan dari server dan dari skrip Anda seharusnya muncul di sana. Temukan log kesalahan dan lihat isinya. Tidak ada tempat standar untuk file log. Lihat di konfigurasi server untuk lokasinya, atau tanyakan pada admin server. Anda juga dapat menggunakan alat seperti CGI :: Carp
untuk menyimpan file log Anda sendiri.
Apa izin skrip?
Jika Anda melihat kesalahan seperti "Izin ditolak" atau "Metode tidak diterapkan", itu mungkin berarti bahwa skrip Anda tidak dapat dibaca dan dijalankan oleh pengguna server web. Mengenai rasa Unix, disarankan untuk mengubah mode ke 755:
chmod 755 filename
. Jangan pernah menyetel mode ke 777!
Apakah Anda menggunakan use strict
?
Ingatlah bahwa Perl secara otomatis membuat variabel saat Anda pertama kali menggunakannya. Ini adalah fitur, tetapi terkadang dapat menyebabkan bug jika Anda salah mengetik nama variabel. Pragma
use strict
akan membantu Anda menemukan kesalahan semacam itu. Ini menjengkelkan sampai Anda terbiasa, tetapi pemrograman Anda akan meningkat secara signifikan setelah beberapa saat dan Anda akan bebas membuat kesalahan yang berbeda.
Apakah skrip dikompilasi?
Anda dapat memeriksa kesalahan kompilasi dengan menggunakan -c
sakelar. Berkonsentrasi pada kesalahan pertama yang dilaporkan. Bilas, ulangi. Jika Anda mendapatkan kesalahan yang sangat aneh, periksa untuk memastikan bahwa skrip Anda memiliki akhiran baris yang benar. Jika Anda FTP dalam mode biner, checkout dari CVS, atau sesuatu yang lain yang tidak menangani terjemahan akhir baris, server web mungkin melihat skrip Anda sebagai satu baris besar. Transfer skrip Perl dalam mode ASCII.
Apakah skrip mengeluh tentang dependensi yang tidak aman?
Jika skrip Anda mengeluh tentang dependensi yang tidak aman, Anda mungkin menggunakan -T
sakelar untuk mengaktifkan mode taint, yang merupakan hal yang baik karena ini membuat Anda tetap meneruskan data yang tidak dicentang ke shell. Jika ia mengeluh, ia melakukan tugasnya untuk membantu kami menulis skrip yang lebih aman. Setiap data yang berasal dari luar program (yaitu lingkungan) dianggap tercemar. Variabel lingkungan seperti PATH
dan
LD_LIBRARY_PATH
sangat merepotkan. Anda harus mengatur ini ke nilai yang aman atau membatalkannya sepenuhnya, seperti yang saya rekomendasikan. Anda tetap harus menggunakan jalur absolut. Jika pemeriksaan noda mengeluh tentang hal lain, pastikan Anda memiliki data yang tidak ternoda. Lihat
halaman manual perlsec untuk detailnya.
Apa yang terjadi jika Anda menjalankannya dari baris perintah?
Apakah skrip menghasilkan apa yang Anda harapkan saat dijalankan dari baris perintah? Apakah output header lebih dulu, diikuti dengan baris kosong? Ingat bahwa STDERR
mungkin akan digabungkan dengan STDOUT
jika Anda berada di terminal (misalnya sesi interaktif), dan karena buffering mungkin muncul dalam urutan campur aduk. Aktifkan fitur autoflush Perl dengan menyetel $|
ke nilai sebenarnya. Biasanya Anda mungkin melihat $|++;
di program CGI. Setelah disetel, setiap pencetakan dan penulisan akan langsung masuk ke keluaran daripada di-buffer. Anda harus mengatur ini untuk setiap filehandle. Gunakan select
untuk mengubah penanganan file default, seperti:
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
Bagaimanapun, keluaran hal pertama haruslah header CGI diikuti dengan baris kosong.
Apa yang terjadi jika Anda menjalankannya dari baris perintah dengan lingkungan mirip CGI?
Lingkungan server web biasanya jauh lebih terbatas daripada lingkungan baris perintah Anda, dan memiliki informasi tambahan tentang permintaan tersebut. Jika skrip Anda berjalan dengan baik dari baris perintah, Anda dapat mencoba mensimulasikan lingkungan server web. Jika masalah muncul, Anda memiliki masalah lingkungan.
Batalkan pengaturan atau hapus variabel ini
PATH
LD_LIBRARY_PATH
- semua
ORACLE_*
variabel
Tetapkan variabel-variabel ini
REQUEST_METHOD
(set ke GET
, HEAD
atau POST
yang sesuai)
SERVER_PORT
(diatur ke 80, biasanya)
REMOTE_USER
(jika Anda melakukan hal-hal dengan akses yang dilindungi)
Versi terbaru CGI.pm
(> 2.75) memerlukan -debug
flag untuk mendapatkan perilaku lama (berguna), jadi Anda mungkin harus menambahkannya ke CGI.pm
impor Anda .
use CGI qw(-debug)
Apakah Anda menggunakan die()
atau warn
?
Fungsi-fungsi itu mencetak ke STDERR
kecuali Anda telah mendefinisikannya kembali. Mereka juga tidak mengeluarkan header CGI. Anda bisa mendapatkan fungsionalitas yang sama dengan paket seperti CGI :: Carp
Apa yang terjadi setelah Anda menghapus cache browser?
Jika menurut Anda skrip Anda melakukan hal yang benar, dan saat Anda melakukan permintaan secara manual, Anda mendapatkan hasil yang tepat, mungkin browser penyebabnya. Kosongkan cache dan setel ukuran cache ke nol saat pengujian. Ingatlah bahwa beberapa browser sangat bodoh dan tidak benar-benar memuat ulang konten baru meskipun Anda menyuruhnya melakukannya. Ini terutama lazim dalam kasus di mana jalur URL sama, tetapi konten berubah (misalnya gambar dinamis).
Apakah naskahnya sesuai dengan keinginan Anda?
Jalur sistem file ke skrip tidak selalu terkait langsung dengan jalur URL ke skrip. Pastikan Anda memiliki direktori yang benar, meskipun Anda harus menulis skrip pengujian singkat untuk mengujinya. Lebih lanjut, apakah Anda yakin bahwa Anda memodifikasi file yang benar? Jika Anda tidak melihat efek apa pun dengan perubahan Anda, Anda mungkin memodifikasi file lain, atau mengupload file ke tempat yang salah. (Ngomong-ngomong, inilah penyebab saya yang paling sering dari masalah seperti itu;)
Apakah Anda menggunakan CGI.pm
, atau turunannya?
Jika masalah Anda berkaitan dengan parsing input CGI dan Anda tidak menggunakan modul diuji secara luas seperti CGI.pm
, CGI::Request
,
CGI::Simple
atau CGI::Lite
, menggunakan modul dan melanjutkan hidup.
CGI.pm
memiliki cgi-lib.pl
mode kompatibilitas yang dapat membantu Anda memecahkan masalah input karena implementasi parser CGI yang lebih lama.
Apakah Anda menggunakan jalur absolut?
Jika Anda menjalankan perintah eksternal dengan
system
, tanda centang kembali, atau fasilitas IPC lainnya, Anda harus menggunakan jalur absolut ke program eksternal. Anda tidak hanya tahu persis apa yang Anda jalankan, tetapi Anda juga terhindar dari beberapa masalah keamanan. Jika Anda membuka file untuk membaca atau menulis, gunakan jalur absolut. Skrip CGI mungkin memiliki ide yang berbeda tentang direktori saat ini daripada yang Anda lakukan. Atau, Anda dapat melakukan eksplisit chdir()
untuk menempatkan Anda di tempat yang tepat.
Apakah Anda memeriksa nilai pengembalian Anda?
Sebagian besar fungsi Perl akan memberi tahu Anda apakah berfungsi atau tidak dan akan $!
menyebabkan kegagalan. Apakah Anda memeriksa nilai pengembalian dan memeriksa $!
pesan kesalahan? Apakah Anda sudah memeriksa
$@
apakah Anda sedang menggunakan eval
?
Versi Perl mana yang Anda gunakan?
Versi stabil terbaru dari Perl adalah 5.28 (atau tidak, tergantung kapan terakhir kali ini diedit). Apakah Anda menggunakan versi yang lebih lama? Versi Perl yang berbeda mungkin memiliki ide peringatan yang berbeda.
Server web mana yang Anda gunakan?
Server yang berbeda dapat bertindak berbeda dalam situasi yang sama. Produk server yang sama dapat bertindak berbeda dengan konfigurasi yang berbeda. Sertakan sebanyak mungkin informasi ini dalam permintaan bantuan apa pun.
Apakah Anda memeriksa dokumentasi server?
Pemrogram CGI yang serius harus mengetahui sebanyak mungkin tentang server - termasuk tidak hanya fitur dan perilaku server, tetapi juga konfigurasi lokal. Dokumentasi untuk server Anda mungkin tidak tersedia untuk Anda jika Anda menggunakan produk komersial. Jika tidak, dokumentasi harus ada di server Anda. Jika tidak, cari di web.
Ini berguna tetapi semua poster yang bagus telah mati atau hilang.
Sepertinya seseorang pernah mengalami masalah Anda sebelumnya, dan seseorang (mungkin saya) telah menjawabnya di newsgroup ini. Meskipun grup berita ini telah melewati masa kejayaannya, hikmah yang dikumpulkan dari masa lalu terkadang dapat bermanfaat.
Dapatkah Anda mereproduksi masalah dengan skrip pengujian singkat?
Dalam sistem yang besar, mungkin sulit untuk melacak bug karena begitu banyak hal yang terjadi. Cobalah untuk mereproduksi perilaku masalah dengan skrip sesingkat mungkin. Mengetahui masalahnya adalah sebagian besar perbaikannya. Ini mungkin memakan waktu, tetapi Anda belum menemukan masalahnya dan Anda kehabisan pilihan. :)
Apakah Anda memutuskan untuk pergi menonton film?
Sungguh. Terkadang kita bisa begitu terbungkus dalam masalah sehingga kita mengembangkan "perseptual narrowing" (tunnel vision). Istirahat, minum secangkir kopi, atau meledakkan beberapa orang jahat di [Duke Nukem, Quake, Doom, Halo, COD] mungkin memberi Anda perspektif baru bahwa Anda perlu mendekati kembali masalah tersebut.
Sudahkah Anda menyuarakan masalahnya?
Serius lagi. Terkadang menjelaskan masalah dengan lantang membawa kita ke jawaban kita sendiri. Bicaralah dengan penguin (mainan mewah) karena rekan kerja Anda tidak mendengarkan. Jika Anda tertarik dengan ini sebagai alat debugging yang serius (dan saya merekomendasikannya jika Anda belum menemukan masalahnya sekarang), Anda mungkin juga ingin membaca The Psychology of Computer Programming .