Bagaimana cara memecahkan masalah skrip Perl CGI saya?

100

Saya memiliki skrip Perl yang tidak berfungsi dan saya tidak tahu bagaimana memulai mempersempit masalah. Apa yang dapat saya?


Catatan: Saya menambahkan pertanyaan karena saya benar-benar ingin menambahkan jawaban saya yang sangat panjang ke Stackoverflow. Saya terus menautkannya secara eksternal di jawaban lain dan itu layak untuk berada di sini. Jangan malu mengedit jawaban saya jika Anda memiliki sesuatu untuk ditambahkan.

brian d foy
sumber
5
@ Evan - maksud saya adalah hanya bahwa bahkan sebagai non-CW masih merupakan diedit - jika Anda memiliki cukup karma; 100 untuk CW, 2k sebaliknya. Jadi sekarang Anda memiliki 2060 Anda harus dapat mengedit posting non-CW.
Marc Gravell
1
@Evan, poin ajaib terdaftar di tooltips di kolom sebelah kanan di sini: stackoverflow.com/privileges
cjm
Jika browser web Anda menampilkan derau baris, mungkin yang mencetak skrip perl sebagai gantinya. Jika demikian, lihat stackoverflow.com/questions/2621161/…
Andrew Grimm

Jawaban:

129

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 [email protected]. 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 -wsakelar 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 warningspragma ke semua file Anda:

 use warnings;

Jika Anda membutuhkan lebih banyak informasi daripada pesan peringatan singkat, gunakan diagnosticspragma 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 -Tsakelar 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 PATHdan 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 STDERRmungkin 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 selectuntuk 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, HEADatau POSTyang 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 -debugflag untuk mendapatkan perilaku lama (berguna), jadi Anda mungkin harus menambahkannya ke CGI.pmimpor Anda .

use CGI qw(-debug)

Apakah Anda menggunakan die()atau warn?

Fungsi-fungsi itu mencetak ke STDERRkecuali 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::Simpleatau CGI::Lite, menggunakan modul dan melanjutkan hidup. CGI.pmmemiliki cgi-lib.plmode 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.

Apakah Anda mencari arsip dari comp.infosystems.www.authoring.cgi?

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 .

brian d foy
sumber
4
Jangan malu mengedit jawaban saya jika Anda memiliki sesuatu untuk ditambahkan.
Brian d foy
Sepertinya Anda mungkin ingin menghapus link ke FAQ meta CGI. Apakah 5.12.1 dianggap "stabil"?
Snake Plissken
1
Mengapa tidak, $|=1bukan $|++?
reinierpost
Mengapa, $|=1bukan $|++? Itu tidak benar-benar membuat perbedaan, dan bahkan kemudian, $|ajaib.
brian d foy
2
Jawaban yang bagus, saya pikir mungkin perlu disebutkan bahwa beberapa solusi ini seharusnya murni untuk pemecahan masalah dan tidak dimasukkan ke dalam kode produksi. use strictumumnya baik untuk digunakan setiap saat, sedangkan penggunaan fatalsToBrowsermungkin tidak disarankan dalam produksi, terutama jika Anda menggunakan die.
vol7ron
10

Saya pikir CGI :: Debug juga layak untuk disebutkan.

Mikael S
sumber
Sayangnya, saya hanya bisa mengedit pertanyaannya, bukan jawabannya.
Mikael S
7

Apakah Anda menggunakan penangan kesalahan saat melakukan debug?

diepernyataan dan kesalahan run-time dan waktu kompilasi fatal lainnya dicetak STDERR, yang mungkin sulit ditemukan dan mungkin digabungkan dengan pesan dari halaman web lain di situs Anda. Saat Anda men-debug skrip Anda, ada baiknya untuk menampilkan pesan kesalahan fatal di browser Anda.

Salah satu cara untuk melakukannya adalah dengan menelepon

   use CGI::Carp qw(fatalsToBrowser);

di bagian atas skrip Anda. Panggilan itu akan menginstal $SIG{__DIE__}penangan (lihat perlvar ) menampilkan kesalahan fatal di browser Anda, menambahkannya dengan header yang valid jika perlu. Trik debugging CGI lain yang saya gunakan sebelum saya pernah mendengar CGI::Carpadalah menggunakan evaldengan DATAdan__END__ fasilitas pada script untuk menangkap kesalahan saat kompilasi:

   #!/usr/bin/perl
   eval join'', <DATA>;
   if ($@) { print "Content-type: text/plain:\n\nError in the script:\n$@\n; }
   __DATA__
   # ... actual CGI script starts here

Teknik yang lebih bertele-tele ini memiliki sedikit keunggulan CGI::Carp karena akan menangkap lebih banyak kesalahan waktu kompilasi.

Pembaruan: Saya belum pernah menggunakannya, tetapi sepertinya CGI::Debug, seperti yang disarankan Mikael S, juga merupakan alat yang sangat berguna dan dapat dikonfigurasi untuk tujuan ini.

mob
sumber
3
@Ether: <DATA>adalah filehandle ajaib yang membaca skrip saat ini dimulai dengan __END__. Gabung menyediakan konteks daftar, jadi <fh> mengembalikan larik, satu baris per item. Kemudian gabung menyatukannya kembali (gabungkan dengan ''). Terakhir, eval.
derobert
@ Lain: Cara yang lebih mudah dibaca untuk menulis baris 2 adalah:eval join(q{}, <DATA>);
derobert
@derobert: sebenarnya, __DATA__ adalah token yang digunakan untuk memulai bagian data, bukan __END__ (Saya rasa itu adalah kebingungan saya).
Eter
1
@ Lain: Sebenarnya, keduanya bekerja di skrip tingkat atas (menurut halaman manual perldata). Tetapi karena DATA lebih disukai, saya telah mengubah jawabannya.
derobert
@derobert: terima kasih untuk tautan dokumennya; Saya tidak tahu tentang perilaku kompatibilitas mundur __END__!
Eter
7

Saya bertanya-tanya kenapa tidak ada yang menyebutkan PERLDB_OPTSopsi yang disebut RemotePort; meskipun memang, tidak banyak contoh yang berfungsi di web ( RemotePortbahkan tidak disebutkan dalam perldebug ) - dan agak bermasalah bagi saya untuk membuat yang ini, tapi ini dia (ini adalah contoh Linux).

Untuk melakukan contoh yang tepat, pertama saya membutuhkan sesuatu yang dapat melakukan simulasi yang sangat sederhana dari server web CGI, sebaiknya melalui satu baris perintah. Setelah menemukan server web baris perintah sederhana untuk menjalankan cgis. (perlmonks.org) , saya menemukan IO :: All - A Tiny Web Server dapat digunakan untuk pengujian ini.

Di sini, saya akan bekerja di /tmpdirektori; skrip CGI akan /tmp/test.pl(disertakan di bawah). Perhatikan bahwa IO::Allserver hanya akan melayani file yang dapat dieksekusi di direktori yang sama dengan CGI, jadi chmod +x test.pldiperlukan di sini. Jadi, untuk melakukan uji coba CGI biasa, saya mengubah direktori ke /tmpdi terminal, dan menjalankan server web satu baris di sana:

$ cd /tmp
$ perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

Perintah server web akan memblokir di terminal, dan sebaliknya akan memulai server web secara lokal (pada 127.0.0.1 atau localhost) - setelah itu, saya dapat membuka browser web, dan meminta alamat ini:

http://127.0.0.1:8080/test.pl

... dan saya harus mengamati apa printyang dibuat olehtest.pl dimuat - dan ditampilkan - di browser web.


Sekarang, untuk men-debug skrip ini RemotePort, pertama-tama kita memerlukan listener di jaringan, yang akan digunakan untuk berinteraksi dengan Perl debugger; kita dapat menggunakan alat baris perintah netcat( nc, lihat di sini: Perl 如何 remote debug? ). Jadi, pertama-tama jalankan netcatlistener di satu terminal - di mana ia akan memblokir dan menunggu koneksi di port 7234 (yang akan menjadi port debug kami):

$ nc -l 7234

Kemudian, kami ingin perlmemulai dalam mode debug dengan RemotePort, ketika test.pltelah dipanggil (bahkan dalam mode CGI, melalui server). Ini, di Linux, dapat dilakukan dengan menggunakan skrip "shebang wrapper" berikut - yang di sini juga perlu dimasukkan /tmp, dan harus dibuat dapat dieksekusi:

cd /tmp

cat > perldbgcall.sh <<'EOF'
#!/bin/bash
PERLDB_OPTS="RemotePort=localhost:7234" perl -d -e "do '$@'"
EOF

chmod +x perldbgcall.sh

Ini agak rumit - lihat skrip shell - Bagaimana saya bisa menggunakan variabel lingkungan di shebang saya? - Unix & Linux Stack Exchange . Tapi, triknya di sini tampaknya bukan untuk memotong perlpenerjemah yang menangani test.pl - jadi begitu kita menekannya, kita tidak melakukannya exec, melainkan kita memanggil perl"dengan jelas", dan pada dasarnya "sumber" test.plskrip kita menggunakan do(lihat Bagaimana cara menjalankan Skrip Perl dari dalam skrip Perl? ).

Sekarang setelah kita perldbgcall.shmasuk /tmp- kita dapat mengubah test.plfile, sehingga merujuk ke file yang dapat dieksekusi ini pada baris shebang-nya (bukan interpreter Perl biasa) - di sini /tmp/test.pldiubah menjadi:

#!./perldbgcall.sh

# this is test.pl

use 5.10.1;
use warnings;
use strict;

my $b = '1';
my $a = sub { "hello $b there" };
$b = '2';
print "YEAH " . $a->() . " CMON\n";
$b = '3';
print "CMON " . &$a . " YEAH\n";

$DB::single=1;  # BREAKPOINT

$b = '4';
print "STEP " . &$a . " NOW\n";
$b = '5';
print "STEP " . &$a . " AGAIN\n";

Sekarang, keduanya test.pldan pawang shebang barunya perldbgcall.sh,, ada di /tmp; dan kami telah ncmendengarkan koneksi debug pada port 7234 - jadi kami akhirnya dapat membuka jendela terminal lain, mengubah direktori ke /tmp, dan menjalankan server web satu-liner (yang akan mendengarkan koneksi web pada port 8080) di sana:

cd /tmp
perl -MIO::All -e 'io(":8080")->fork->accept->(sub { $_[0] < io(-x $1 ? "./$1 |" : $1) if /^GET \/(.*) / })'

Setelah ini selesai, kita bisa pergi ke browser web kita, dan meminta alamat yang sama http://127.0.0.1:8080/test.pl,. Namun, sekarang ketika server web mencoba untuk mengeksekusi skrip, itu akan melakukannya melalui perldbgcall.shshebang - yang akan dimulai perldalam mode debugger jarak jauh. Dengan demikian, eksekusi skrip akan dijeda - dan browser web akan mengunci, menunggu data. Sekarang kita dapat beralih ke netcatterminal, dan kita harus melihat teks debugger Perl yang sudah dikenal - namun, keluaran melalui nc:

$ nc -l 7234

Loading DB routines from perl5db.pl version 1.32
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1):   do './test.pl'
  DB<1> r
main::(./test.pl:29):   $b = '4';
  DB<1>

Seperti yang ditunjukkan cuplikan, sekarang pada dasarnya kita menggunakan ncsebagai "terminal" - jadi kita dapat mengetik r(dan Enter) untuk "run" - dan skrip akan menjalankan pernyataan breakpoint (lihat juga Dalam perl, apa perbedaan antara $ DB :: single = 1 dan 2? ), Sebelum berhenti lagi (perhatikan saat itu, browser akan tetap terkunci).

Jadi, sekarang kita dapat, katakanlah, melewati sisa test.pl, melalui ncterminal:

....
main::(./test.pl:29):   $b = '4';
  DB<1> n
main::(./test.pl:30):   print "STEP " . &$a . " NOW\n";
  DB<1> n
main::(./test.pl:31):   $b = '5';
  DB<1> n
main::(./test.pl:32):   print "STEP " . &$a . " AGAIN\n";
  DB<1> n
Debugged program terminated.  Use q to quit or R to restart,
  use o inhibit_exit to avoid stopping after program termination,
  h q, h R or h o to get additional info.
  DB<1>

... namun, juga pada saat ini, browser mengunci dan menunggu data. Hanya setelah kita keluar dari debugger dengan q:

  DB<1> q
$

... apakah browser berhenti mengunci - dan akhirnya menampilkan output (lengkap) dari test.pl:

YEAH hello 2 there CMON
CMON hello 3 there YEAH
STEP hello 4 there NOW
STEP hello 5 there AGAIN

Tentu saja, jenis debug ini dapat dilakukan bahkan tanpa menjalankan server web - namun, hal yang menarik di sini, adalah kita tidak menyentuh server web sama sekali; kami memicu eksekusi "secara asli" (untuk CGI) dari browser web - dan satu-satunya perubahan yang diperlukan dalam skrip CGI itu sendiri, adalah perubahan shebang (dan tentu saja, kehadiran skrip pembungkus shebang, sebagai file yang dapat dieksekusi dalam direktori).

Yah, semoga ini membantu seseorang - saya pasti akan senang jika tersandung pada ini, daripada menulisnya sendiri :)
Cheers!

sdaau
sumber
5

Bagi saya, saya menggunakan log4perl . Ini cukup berguna dan mudah.

use Log::Log4perl qw(:easy);

Log::Log4perl->easy_init( { level   => $DEBUG, file    => ">>d:\\tokyo.log" } );

my $logger = Log::Log4perl::get_logger();

$logger->debug("your log message");
zawhtut.dll
sumber
1

Jujur saja Anda bisa melakukan semua hal menyenangkan di atas postingan ini. MESKIPUN, solusi paling sederhana dan paling proaktif yang saya temukan adalah hanya "mencetaknya".

Misalnya: (Kode normal)

`$somecommand`;

Untuk melihat apakah itu melakukan apa yang saya benar-benar ingin lakukan: (Trouble shooting)

print "$somecommand";
Ilan Kleiman
sumber
1

Mungkin juga layak untuk disebutkan bahwa Perl akan selalu memberi tahu Anda pada baris apa kesalahan terjadi saat Anda menjalankan skrip Perl dari baris perintah. (Sesi SSH misalnya)

Saya biasanya akan melakukan ini jika semuanya gagal. Saya akan SSH ke server dan secara manual menjalankan script Perl. Sebagai contoh:

% perl myscript.cgi 

Jika ada masalah maka Perl akan memberitahu Anda tentang itu. Metode debugging ini menghilangkan masalah terkait izin file atau masalah browser web atau server web.

gpowr
sumber
Perl tidak selalu memberi tahu Anda nomor baris di mana kesalahan terjadi. Ini memberi tahu Anda nomor baris di mana ia menyadari ada sesuatu yang salah. Kesalahan sepertinya sudah terjadi.
brian d foy
0

Anda dapat menjalankan skrip perl cgi di terminal menggunakan perintah di bawah ini

 $ perl filename.cgi

Itu menafsirkan kode dan memberikan hasil dengan kode HTML. Itu akan melaporkan kesalahan jika ada.

D. Karthikeyan
sumber
1
Maaf, perintah $ perl -c filename.cgi memvalidasi sintaks kode dan melaporkan kesalahan jika ada. Itu tidak akan memberikan kode html dari cgi.
D. Karthikeyan
Memanggil perl -c filenamememang hanya akan memeriksa sintaks. Tapi perl filenamemencetak output HTML. Tidak ada jaminan bahwa tidak akan ada kesalahan 500 CGI, tetapi ini adalah tes pertama yang bagus.
Nagev