Konsola / stdout'a yazdırma iyi bir hata ayıklama stratejisi midir?


11

Diyelim ki böyle bir fonksiyonumuz var:

public void myStart()
{
    for (int i = 0; i<10; i++) myFunction(i); 
}


private int myFunction(int a)
{

    a = foo(a);
    a = bar(a);
    return a; 
}

private int foo(int a)
{
    //do something here

    //something gnarly here

    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Şimdi her ne sebeple olursa olsun, kodumuz çalışmıyor. Belki bir hata atıyor, belki yanlış değeri döndürüyor, belki sonsuz bir döngüde sıkışmış.

Herhangi bir ilk yıl programcı ilk şey, konsol / std out, (bir hata ayıklayıcı kullanmayı öğrenmeden önce Hello World yazdırmayı öğrendim).

Örneğin bu kodda hata ayıklamak için aşağıdakileri yapabilirler:

private int myFunction(int a)
{
    print("before foo: a=" + a); 
    a = foo(a);
    print("before bar: a=" + a);
    a = bar(a);

    return a; 
}

private int foo(int a)
{
    //do something here
    print ("foo step1: a=" + a); 

    //something gnarly here
    print ("foo step2: a=" + a + " someOtherValue="+ someOtherValue + " array.length= " + someArray.length()); 
    //etc
    return aValue;
}

private int bar(int a)
{
    // do something here
    //return aValue;
}

Şimdi kodu çalıştırıyorlar, büyük bir konsol çıktısı alıyorlar, bu da işlerin yanlış gittiğini izlemek için geçebiliyorlar.

Elbette bir alternatif, kesme noktaları ayarlamak ve her noktada kod boyunca adım atmaktır.

Konsolda yazdırmanın en büyük avantajlarından biri, geliştiricinin adımların tıklanması gerekmeden değerlerin akışını tek seferde görebilmesidir.

Ama dezavantajı, daha sonra kaldırılması gereken tüm bu basılı ifadeler ile kodunuzu bilmece.

(Hata ayıklayıcıya bir günlüğe yalnızca belirli değerleri yazdırmasını söylemek mümkün mü?, Kesme noktaları kodu gerçekten değiştirmeden kolayca eklenebilir veya kaldırılabilir.)

Hala konsol baskısını birincil hata ayıklama yöntemi olarak kullanıyorum, bunun başka bir şeyle karşılaştırıldığında bunun ne kadar yaygın / etkili olduğunu merak ediyorum.


1
Bir hata ayıklayıcıyı nasıl kullanacağınızı ve uygun bir günlük kaydı çerçevesini nasıl kullanacağınızı öğrenmeniz gerekir. Sizi konsola yazdırmaktan çok daha mutlu edecektir (bu her zaman mevcut değildir).

7
Hata ayıklayıcıları kullanmayı öğrenmek önemlidir, ancak printf hata ayıklamanın kullanılabilir tek hata ayıklama yöntemi olduğu durumlarda karşılaşabileceğiniz birçok durum vardır.
23'te whatsisname

Yanıtlar:


26

Basılı deyimler ve hata ayıklayıcı birbirini dışlamaz. Bunlar, hataları bulmak / tanımlamak için kullanabileceğiniz farklı araçlardır. Hiçbir zaman hata ayıklayıcıya nasıl dokunmadıklarını iddia edecekler ve yazdıkları kodun herhangi bir yerinde tek bir günlük / yazdırma ifadesi olmayanlar var. Benim tavsiyem, bu gruplardan birinde olmak istememeniz.

Bunun yerine günlüğe kaydetmeyi ve bir hata ayıklayıcı kullanmayı öğrenin. Tecrübe ile (neredeyse düşünmek zorunda kalmadan) doğru aracı seçecek ve işi doğru ve verimli bir şekilde yapacaksınız. Deneyim olmadan, bazen birini diğerinden seçersiniz ve belki de değişkenleri araştırmak veya günlük dosyalarını elemek biraz daha uzun sürer, ancak hepsi öğrenme sürecinin bir parçasıdır.

Yani, özel sorunuza cevap vermek için. Evet. Yürütmeyi izlemek için baskıları kullanmak iyi ve yaygın olarak kullanılan hata ayıklama stratejisidir. Ancak...

Yazdırma deyimlerini kullanmak yerine, bir günlük kaydı çerçevesi kullanmayı düşünün. Günlük çerçeveleri, günlük düzeyleri kavramına sahiptir, böylece bir dizi günlük mesajı ekleyebilir, ancak her biri için bir düzey seçebilirsiniz. Başvurunuz normal koşullar altında çalışırken, düzeyiniz HATA veya UYARI olur, böylece yalnızca önemli şeyler raporlanır. Bununla birlikte, kod boyunca izlediğinizde ve yürütme akışını anlamanız gerektiğinde, kaydediciyi INFO veya DEBUG olarak değiştirebilirsiniz ve şimdi kodda bulunan tüm bu "print" ifadeleri ek bilgi raporlayacaktır.

Bir günlük çerçevesi kullanma ...

  1. işiniz bittikten sonra tüm baskıları silmenize gerek yoktur.
  2. kodda bıraktığınız baskılar, size veya başka bir geliştiricinin gelecekte aynı kodda hata ayıklamasına yardımcı olabilir
  3. sildiğiniz baskıları eklemek için her seferinde yeniden oluşturmak zorunda kalmadan bu koddaki alanda hata ayıklayabilirsiniz.
  4. günlük iletilerini yalnızca bir konsolu değil, istediğiniz yere yeniden yönlendirebilirsiniz. Bir dosyaya, syslog, DB, soket vb.

Güncelleme: Sonunda, "Hata ayıklayıcıya yalnızca belirli değerleri bir günlüğe yazdırmasını söylemek mümkün mü?" Hangi hata ayıklayıcıyı kullandığınıza bağlı olarak. Birçok modern hata ayıklayıcı, bir kesme noktasına çarpıldığında çağrılacak bir eylem tanımlamanızı sağlar. Bazılarında (bunu VS ve WinDbg'de yaptım), "bunu yazdır ve devam et" belirtmek mümkündür. Visual Studio onları "kesme noktaları" yerine "izleme noktaları" olarak adlandırır


İlk paragraf için +1. Hata ayıklayıcılar ve günlükler iki farklı sorunu çözer.
Blrfl

1
Ancak, günlük ifadelerini kodda bırakmanın çirkinleştiğini kabul etmiyor musunuz?
dwjohnston

1
ne tür günlük ifadelerini yerinde bıraktığınıza bağlıdır. Bunu bulup kaldırdım: "logger.error (" NE ")". Aksi takdirde, günlük kodunu kodumun geri kalanı gibi ele alıyorum. Biçimlendirin, güzel görünmesini sağlayın ve bilgilendirici hale getirin. Evet, her iki hatta bir baskı bildirisi serpmek biraz fazla ve buna başvurmam gereken zamanlar vardı. Ancak genel olarak, tüm dosyada 10-20 günlük deyimine sahip olmak (dosyalar / sınıflar makul büyüklükte ve devasa değil) hiç de fena değil.
DXM

Sana bu kadar alıştığınız gibi çeşitli önemli değişkenler günlüğe kaydediyor isteyebilirsiniz bir üretim sistemini varsa bazı hata varsa bazı günlük ifadeleri bırakarak, örneğin yararlı olabileceğini olsun mu size üretimde yaşanan hemen görebilirsiniz çıkabilirler ortamı. Bununla birlikte, kalkınma bağlamı için dağınık görünüyor. Örneğin, ayrıştırma işlevinizi yazıyorsunuz ve regex'inizi doğru şekilde bilmiyorsunuz - bu yüzden neler olup bittiğini kontrol etmek ve sonunda çözmek için bir dizi günlük ifadesi koyuyorsunuz. Onları bırakmak için ileri giderek değer kattığını düşünmüyorum.
dwjohnston

1
@Izkata: bunların hepsi, özel hatanızın özelliklerine ve kodunuzun ne kadar günlüğe kaydedildiğine bağlıdır. Karşılaşmaya çalıştığım nokta, her zaman günlük ifadelerine sahip olmanın ve bunları farklı düzeylerde almanın değeri olduğudur: ERR -> WARN ... -> DEBUG. Çok özel bir şey için daha fazlasına ihtiyacınız varsa, elbette baskı ifadeleri eklemeye başlayın. Ancak, günlük kaydı ifadesi olarak "print" kullanan birine yanıtım her zaman bir çerçeveye geçecek ve kullanmaya başlayacaktır.
DXM

3

Loging / baskı ve hata ayıklayıcılar, farklı güçlü ve zayıf yönleri olan tamamlayıcı tekniklerdir - her ikisini de kullanmak en iyisidir. Ancak genel olarak, hata ayıklayıcıların çoğu durumda üstün bir araç olduğunu ve ilk önce kullanılmaları gerektiğini söyleyebilirim, günlük / baskı yalnızca aslında daha iyi olduğu şeyler için kullanılır.

Hata ayıklayıcıların avantajları:

  • Yalnızca önceden yazdırmayı düşündüğünüz değerleri değil, tüm program durumunu inceleyebilirsiniz. Bu , geri besleme döngüsünü bir saniyeden daha aza indirerek hata ayıklama işlemini büyük ölçüde hızlandırabilir. Böceğe ulaşmak biraz zaman aldığında özellikle önemlidir.
  • Çağrıların nereden geldiğini görebilir ve hatta yığın izlemedeki değerleri inceleyebilirsiniz.
  • Yalnızca derlenmiş ikili veya bayt koduna sahip olduğunuz için kolayca değiştiremediğiniz (dile / platfrom'a bağlı olarak bir dereceye kadar) hata ayıklama kodu yapabilirsiniz.

Günlük / baskı avantajları:

  • Özel bir hata ayıklama derlemesi veya yapılandırması gerektirmez. Her zaman çalışır.
  • Çoğaltılması zor ve nadiren meydana gelen hataları analiz etmek için kullanılabilir
  • Hata ayıklayıcının neden olduğu duraklamanın hatayı kolayca yok edebileceği zamanlamaya bağlı hataları analiz etmek için kullanılabilir.
  • Boş zamanlarınızda analiz edebileceğiniz kalıcı bilgiler verir. Program akışındaki farklı noktalardaki çıktılar arasında ileri geri atlayabilirsiniz.

Günlüğe kaydetmenin başka bir avantajı, kodunuzdan sadece onüçüncü geçişte karşılaştığınız ve gerçekten oraya nasıl geldiğinizin bazı geri izlerini kullanabileceğinizdir. Çoğu hata ayıklayıcının ters düğmesi yoktur, ancak daha üst düzey bir işlevin çağrıldığı değerlerin günlüğe kaydedilmesi işe yarayacaktır ve çoğu zaman sizi en azından küçük bir yeniden üretilebilir kasaya yaklaştıracaktır.
Christopher Creutzig

1

Bir şekilde standart çıktıya yazdırmak, kodunuzun hatalarını ayıklamak için iyi bir strateji olabilir, örneğin

  • özellikle hatayı tam olarak anlamadıysam, kodumun farklı düzeylerinde neler olduğunu görmek için birçok yazdırma ifadesi kullanıyorum

  • ya da hatada, kodun tam olarak hangi soruna neden olduğuna işaret edebilecek ayrıntılı bir bilgi bulunmuyor olabilir.

Ancak, hata ayıklama araçlarına alışmanız gerekir, hangi dili veya platformu kullandığınıza bağlı olarak orada birçok şey vardır.

Ayrıca başka bir yöntem günlüğe kaydetme, Android uygulamalarında çalışırken her zaman hataları günlüğe kaydeder, ayrıca istisna işleme ile, bir istisna işleminin bir yığın izlemesini veya hata mesajını kolayca kaydedebilirsiniz.


3
bu yazıyı okumak oldukça zor (metnin duvarı). Sakıncası var düzenleyebilir daha iyi bir şekle ing?
gnat

Biraz okunabilir yaptım. Önceki için üzgünüm!
Plaix
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.