Bu cevap, Perl CGI betikleri ile ilgili problemler üzerinde çalışmak için genel bir çerçeve olarak tasarlanmıştır ve ilk olarak Perlmonks'ta Perl CGI Scriptlerinde Sorun Giderme olarak görünmüştür . Karşılaşabileceğiniz her sorun için eksiksiz bir rehber veya hata giderme hakkında bir eğitim değildir. Yirmi (artı!) Yıl boyunca CGI betiklerinde hata ayıklama deneyimimin doruk noktası. Bu sayfanın birçok farklı evi var gibi görünüyor ve var olduğunu unuttuğum için onu StackOverflow'a ekliyorum. Her türlü görüş ve önerinizi bdfoy@cpan.org adresinden bana iletebilirsiniz. Aynı zamanda topluluk wikisi, ama fazla delirmeyin. :)
Sorunları bulmanıza yardımcı olmak için Perl'in yerleşik özelliklerini kullanıyor musunuz?
Perl'in sizi kodunuzun şüpheli kısımları hakkında uyarmasına izin vermek için uyarıları açın. Bunu komut satırından -w
anahtarla yapabilirsiniz, böylece herhangi bir kodu değiştirmeniz veya her dosyaya bir pragma eklemeniz gerekmez:
% perl -w program.pl
Bununla birlikte, warnings
pragmayı tüm dosyalarınıza ekleyerek şüpheli kodu her zaman temizlemeye zorlamalısınız :
use warnings;
Kısa uyarı mesajından daha fazla bilgiye ihtiyacınız varsa, diagnostics
daha fazla bilgi almak için pragma kullanın veya perldiag belgelerine bakın:
use diagnostics;
Önce geçerli bir CGI başlığı çıktınız mı?
Sunucu, bir CGI komut dizisinden ilk çıktının CGI başlığı olmasını bekliyor. Tipik olarak bu print "Content-type: text/plain\n\n";
, CGI.pm ve türevleri kadar basit olabilir print header()
. Bazı sunucular, STDERR
standart çıktıdan (açık STDOUT
) önce gösterilen hata çıktısına (açık ) duyarlıdır .
Tarayıcıya hata göndermeyi deneyin
Bu satırı ekleyin
use CGI::Carp 'fatalsToBrowser';
senaryonuza. Bu ayrıca tarayıcı penceresine derleme hataları gönderir. Ekstra bilgiler güvenlik riski oluşturabileceğinden, üretim ortamına geçmeden önce bunu kaldırdığınızdan emin olun.
Hata günlüğü ne dedi?
Sunucular hata günlüklerini tutar (veya en azından tutmalıdır). Sunucudan ve betiğinizden gelen hata çıktısı orada görünmelidir. Hata günlüğünü bulun ve ne yazdığını görün. Günlük dosyaları için standart bir yer yoktur. Konumları için sunucu yapılandırmasına bakın veya sunucu yöneticisine sorun.
Kendi günlük dosyalarınızı saklamak için CGI :: Carp gibi araçları da kullanabilirsiniz .
Komut dosyasının izinleri nelerdir?
"İzin reddedildi" veya "Yöntem uygulanmadı" gibi hatalar görürseniz, bu muhtemelen komut dizinizin web sunucusu kullanıcısı tarafından okunamaz ve çalıştırılabilir olmadığı anlamına gelir. Unix tatlar günü, 755 'modunu değiştirerek önerilir:
chmod 755 filename
. Asla bir modu 777'ye ayarlamayın!
Kullandığınız use strict
?
Perl'in değişkenleri ilk kullandığınızda otomatik olarak yarattığını unutmayın. Bu bir özelliktir, ancak bazen bir değişken adını yanlış yazarsanız hatalara neden olabilir. Pragma
use strict
bu tür hataları bulmanıza yardımcı olacaktır. Alışana kadar can sıkıcı bir durum, ancak programlamanız bir süre sonra önemli ölçüde gelişecek ve farklı hatalar yapmakta özgür olacaksınız.
Komut dosyası derleniyor mu?
-c
Anahtarı kullanarak derleme hatalarını kontrol edebilirsiniz . Bildirilen ilk hatalara odaklanın. Durulayın, tekrarlayın. Gerçekten tuhaf hatalar alıyorsanız, komut dosyanızın doğru satır sonlarına sahip olduğundan emin olun. İkili modda FTP, CVS'den çıkış veya satır sonu çevirisini işlemeyen başka bir şey yaparsanız, web sunucusu komut dosyanızı tek bir büyük satır olarak görebilir. Perl komut dosyalarını ASCII modunda aktarın.
Senaryo güvensiz bağımlılıklardan mı şikayetçi?
Komut dosyanız güvensiz bağımlılıklardan şikayet ediyorsa, muhtemelen -T
bozuk kipi açmak için anahtarı kullanıyorsunuzdur , bu iyi bir şeydir çünkü kontrol edilmemiş verileri kabuğa aktarmanızı sağlar. Şikayet ediyorsa, daha güvenli komut dosyaları yazmamıza yardımcı olmak için işini yapıyor demektir. Programın dışından (yani çevreden) kaynaklanan herhangi bir veri bozuk kabul edilir. Gibi çevresel değişkenler PATH
ve
LD_LIBRARY_PATH
özellikle güçlük doğurmaktadır. Bunları güvenli bir değere ayarlamanız veya tavsiye ettiğim gibi tamamen kaldırmanız gerekir. Yine de mutlak yollar kullanmalısınız. Başka bir şey hakkında şikayetleri kontrol etmekte sorun yaşıyorsanız, verileri temizlediğinizden emin olun. Ayrıntılar için perlsec
man sayfasına bakın.
Komut satırından çalıştırdığınızda ne olur?
Komut dosyası, komut satırından çalıştırıldığında beklediğinizi çıktı mı? Önce başlık çıktısı sonra boş bir satır mı geliyor? Unutmayın STDERR
ile birleştirilebilir STDOUT
(örn interaktif bir oturum) bir terminal üzerinde ise ve arabelleğe nedeniyle bir karışık sırayla gösterilebilir. $|
Gerçek bir değere ayarlayarak Perl'in autoflush özelliğini açın . Genellikle $|++;
CGI programlarında görebilirsiniz . Ayarlandıktan sonra, her yazdırma ve yazma arabelleğe alınmak yerine hemen çıktıya gidecektir. Bunu her dosya tanıtıcısı için ayarlamalısınız. select
Varsayılan dosya tanıtıcısını şu şekilde değiştirmek için kullanın :
$|++; #sets $| for STDOUT
$old_handle = select( STDERR ); #change to STDERR
$|++; #sets $| for STDERR
select( $old_handle ); #change back to STDOUT
Her iki durumda da, ilk çıktı CGI başlığı ve ardından boş bir satır olmalıdır.
CGI benzeri bir ortamda komut satırından çalıştırdığınızda ne olur?
Web sunucusu ortamı genellikle komut satırı ortamınızdan çok daha sınırlıdır ve istek hakkında ek bilgi içerir. Komut dosyanız komut satırından düzgün çalışıyorsa, bir web sunucusu ortamını simüle etmeyi deneyebilirsiniz. Sorun ortaya çıkarsa, bir çevre sorununuz vardır.
Bu değişkenleri ayarlayın veya kaldırın
PATH
LD_LIBRARY_PATH
- tüm
ORACLE_*
değişkenler
Bu değişkenleri ayarlayın
REQUEST_METHOD
(ayarlandığında GET
, HEAD
ya da POST
uygun olarak)
SERVER_PORT
(genellikle 80'e ayarlanır)
REMOTE_USER
(korumalı erişim işleri yapıyorsanız)
CGI.pm
(> 2.75) ' in son sürümleri -debug
bayrağın eski (kullanışlı) davranışı almasını gerektirir , bu nedenle bunu CGI.pm
içe aktarmalarınıza eklemeniz gerekebilir .
use CGI qw(-debug)
die()
Veya kullanıyor warn
musun?
Yeniden STDERR
tanımlamadığınız sürece bu işlevler yazdırılır . Bir CGI başlığı da vermezler. CGI :: Carp gibi paketlerle aynı işlevselliği elde edebilirsiniz.
Tarayıcı önbelleğini temizledikten sonra ne olur?
Komut dosyanızın doğru şeyi yaptığını düşünüyorsanız ve isteği manuel olarak gerçekleştirdiğinizde doğru çıktıyı alırsanız, suçlu tarayıcı olabilir. Önbelleği temizleyin ve test sırasında önbellek boyutunu sıfıra ayarlayın. Bazı tarayıcıların gerçekten aptal olduğunu ve bunu yapmasını söyleseniz bile yeni içeriği yeniden yüklemeyeceğini unutmayın. Bu, özellikle URL yolunun aynı olduğu, ancak içeriğin değiştiği durumlarda (örneğin dinamik görüntüler) yaygındır.
Senaryo sandığınız yerde mi?
Bir komut dosyasına giden dosya sistemi yolu, komut dosyasının URL yolu ile doğrudan ilişkili olmayabilir. Bunu test etmek için kısa bir test komut dosyası yazmanız gerekse bile doğru dizine sahip olduğunuzdan emin olun. Ayrıca, doğru dosyayı değiştirdiğinizden emin misiniz? Değişikliklerinizde herhangi bir etki görmüyorsanız, farklı bir dosyayı değiştiriyor veya bir dosyayı yanlış yere yüklüyor olabilirsiniz. (Bu arada, bu tür sorunların en sık nedenini bu;)
Kullanıyor musunuz CGI.pm
, yoksa bir türevi mi?
Sorununuz CGI giriş ayrıştırma ile ilgilidir ve benzeri yaygın olarak test modülü kullanmıyorsanız CGI.pm
, CGI::Request
,
CGI::Simple
veya CGI::Lite
modülü kullanmak ve hayatına devam et.
CGI.pm
varcgi-lib.pl
eski CGI ayrıştırıcı uygulamalarından kaynaklanan girdi sorunlarını çözmenize yardımcı olabilecek uyumluluk moduna sahiptir.
Mutlak yollar kullandınız mı?
Harici komutlar system
, geri işaretler veya diğer IPC tesisleri ile çalıştırıyorsanız
, harici programa giden mutlak bir yol kullanmalısınız. Sadece ne çalıştırdığınızı tam olarak bilmekle kalmaz, aynı zamanda bazı güvenlik sorunlarından da kaçınırsınız. Dosyaları okumak veya yazmak için açıyorsanız, mutlak bir yol kullanın. CGI betiğinin mevcut dizin hakkında sizden farklı bir fikri olabilir. Alternatif olarak, sizi chdir()
doğru yere yerleştirmek için açık bir şeyler yapabilirsiniz .
Dönüş değerlerinizi kontrol ettiniz mi?
Çoğu Perl işlevi size çalışıp çalışmadıklarını söyleyecek ve $!
başarısızlık durumunda ayarlanacaktır . Dönüş değerini kontrol edip $!
hata mesajlarını incelediniz mi? Kullanıp $@
kullanmadığınızı kontrol
ettiniz eval
mi?
Perl'in hangi sürümünü kullanıyorsunuz?
Perl'in en son kararlı sürümü 5.28'dir (veya en son ne zaman düzenlendiğine bağlı olarak değildir). Daha eski bir sürüm mü kullanıyorsunuz? Perl'in farklı sürümlerinin farklı uyarı fikirleri olabilir.
Hangi web sunucusunu kullanıyorsunuz?
Aynı durumda farklı sunucular farklı davranabilir. Aynı sunucu ürünü, farklı konfigürasyonlarda farklı davranabilir. Herhangi bir yardım talebinde olabildiğince bu bilgileri ekleyin.
Sunucu belgelerini kontrol ettiniz mi?
Ciddi CGI programcıları, sunucu hakkında olabildiğince çok bilgi sahibi olmalıdır - yalnızca sunucu özellikleri ve davranışı değil, aynı zamanda yerel yapılandırma da dahil. Ticari bir ürün kullanıyorsanız, sunucunuzun belgeleri sizin için mevcut olmayabilir. Aksi takdirde, dokümantasyon sunucunuzda olmalıdır. Değilse, web'de arayın.
Bu yararlı olabilir, ancak tüm iyi posterler ya öldü ya da gözden kayboldu.
Muhtemelen birisi probleminizi daha önce yaşamış ve birisi (muhtemelen ben) bu haber grubunda cevap vermiştir. Bu haber grubu altın çağını geçmiş olsa da geçmişten toplanan bilgelik bazen faydalı olabiliyor.
Kısa bir test komut dosyasıyla sorunu yeniden oluşturabilir misiniz?
Büyük sistemlerde, çok fazla şey olduğu için bir hatayı bulmak zor olabilir. Mümkün olan en kısa komut dosyasıyla sorunlu davranışı yeniden oluşturmaya çalışın. Sorunu bilmek, çözümün çoğudur. Bu kesinlikle zaman alıcı olabilir, ancak sorunu henüz bulamadınız ve seçenekleriniz tükeniyor. :)
Sinemaya gitmeye karar verdin mi?
Ciddi anlamda. Bazen problemin içine o kadar sarılabiliriz ki "algısal daralma" (tünel görüşü) geliştiririz. Bir mola vermek, bir fincan kahve içmek veya [Duke Nukem, Quake, Doom, Halo, COD] 'de bazı kötü adamları patlatmak, size soruna yeniden yaklaşmanız için gereken taze bakış açısını verebilir.
Sorunu dile getirdin mi?
Yine cidden. Bazen sorunu yüksek sesle açıklamak bizi kendi cevaplarımıza götürür. İş arkadaşlarınız dinlemediği için penguenle (peluş oyuncak) konuşun. Bununla ciddi bir hata ayıklama aracı olarak ilgileniyorsanız (ve sorunu şimdiye kadar bulamadıysanız tavsiye ederim), Bilgisayar Programlama Psikolojisi'ni de okumak isteyebilirsiniz .