Yazılım bug'ları için bir sınıflandırma

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
21,544
Eğer basit örnek programlar değil de, gerçek bir problemi çözen programlardan bahsedersek, bu programlar doğaları gereği karmaşıktır. Bu karmaşıklığın sonucunda da, bazı şartlar altında beklenmedik davranışlar gösterebilirler. Programlardaki karmaşıklığı gidermek mümkün değildir ve bu karmaşıklık, zamanla daha güçlü programların geliştirilmesiyle daha da artacaktır. Bir programcı olarak hedefimiz, bu beklenmedik davranışları (bugları) mümkün olduğunca azaltmaktır.

Şimdi bu bugları, zorluk derecelerine göre en basitinden en zoruna doğru sıralayalım.
 
=== STATİK BUGLAR ===

Bug'ların en kolayı, program çalıştırıldığı anda, veya programın belirli bir özelliği kullanıldığı anda, hemen bariz olarak kendini belli eden buglar'dır. Mesela ekrana yanlış bir bilgi yazar, hesaplanan şeyin sonucu yanlıştır. Grafik arayüzlü program ise, görünüm ile ilgili bir sıkıntı vardır, veya bir butona basınca hiçbirşey olmuyordur vesaire. Bu bugları tekrar tekrar oluşturabiliriz ve her denemede aynı hatalı davranışı gösterirler, o yüzden bunlara "statik bug" diyorum. Eğer programın yazıldığı programlama diline hakim iseniz, programın kullandığı kütüphaneleri de tanıyorsanız, bir "debugger" kullanarak veya kaynak kodu inceleyerek problemi giderebilirsiniz.
 
=== AMORF BUGLAR ===

Bu buglar, ayni statik buglarda olduğu gibi, programı çalıştırdıktan hemen sonra veya belirli bir özelliği kullandıktan sonra ortaya çıkar. Ama statik bug'dan farklı olarak, problem kendisini her seferinde aynı şekilde göstermez. Bir denemede program çökebilir, diğer denemede program takılır kalır, sonraki denemede, ekranda saçma sapan birşeyler yazılır, ekrandaki grafik görüntü bozulabilir vesaire.

Amorf bugların en önemli sebebi, yazılan programın, işlemci "stack" ini bozmasıdır. Modern masaüstü bilgisayar işlemcileri, bozulan stack neticesinde programın yaptığı geçersiz işlemleri kısa süre içinde tespit eder ve programı zorla sonlandırır. Ama gömülü sistemlerdeki kısıtlı işlemciler üzerinde kod yazıyorsanız, o işlemcilerin çoğunda böyle bir özellik yoktur. O yüzden basit işlemcilerde stack hatası meydana geldiğinde, program tamamen rayından çıkacak ve rastgele çalışmaya başlayacaktır.

Stack problemleri, assembly dilinde ve C/C++ dillerinde ortaya çıkar. Daha üst seviye dillerde, dilin özelliği gereği stack'te bu şekilde bozulmaya yol açacak bir kodun yazılması mümkün değildir.

Eğer bir amorf bug ile karşılaşırsanız, bunu gene debugger ile ve kaynak kodunu inceleyerek çözebilirsiniz. Özellikle array kullanımlarına bakıp, array sınırlarını aşan bir yazma yapılıyor mu incelenmeli. Fonksiyonlara verilen "buffer" pointer'larının da geçerli olup olmadığı, ve bu pointer'lere ne kadar veri yazıldığı, veya buralardan ne kadar veri okunduğu test edilmeli.
 
=== DİNAMİK BUGLAR ===

Dinamik bugları çözmek kolay değildir, çünkü bunlar bazan kendini gösterir, bazan göstermez. Bazan programı birkaç gün kullanırsınız sorun çıkmaz, bazan 10 dakika sonra program çöker veya yanlış davranışı gösterir.

Bu buglar, en yaygın olarak "multithreaded" programlarda ortaya çıkar. Birden fazla thread aynı anda çalışıyor ve birbirleri ile hiç öngörülemez bir zamanlama ile etkileşiyorlar. Problemi ortaya çıkaran zamanlamanın meydana gelmesi de çok uzun süre alabiliyor.

Bu tip bugların çözümünde debugger'lar pek işe yaramaz. Burada yapılması gereken, iyi bir "tracing" kütüphanesi ile programın çalışması esnasında olan biteni bir text dosyaya yazdırmak. Sonra problemin olmasını bekleyip, olduktan sonra da trace dosyasını inceleyip oradan problemi anlamaya çalışmak. Bu, düşen uçaktan çıkarılan kara kutunun incelenmesi gibidir.

Dinamik bug'ları çözmek zaman alır, ve bu zamanın da en büyük bölümü, problemin olmasını beklemek, veya problemin ortaya çıkması için programı kurcalamakla geçer. Problem olduktan sonra, trace incelenir, birşeyden şüphelenilir, onu kanıtlamak için yeni trace'ler eklenir koda, sonra program tekrar çalıştırılıp problemin tekrar olması beklenir.

Eğer çok disiplinli, modüler ve olabildiğince basit kod yazmazsanız, dinamik buglar yüzünden projeniz iptal edilebilir, hatta yaptığınız işten hayır gelmediğini düşünen müdürünüz sizi işten çıkarabilir.
 
=== HEİSENBUG ===

Heisenbug, bir çeşit dinamik bug'dır. Bu bug, ismini Heisenberg denen fizikçiden alır. Heisenberg'in meşhur bir belirsizlik ilkesi vardır, eğer bir parçacığın konumunu biliyorsanız, hızını bilemezsiniz, hızını biliyorsanız konumunu bilemezsiniz gibi birşey. Bu bug da öyle birşeydir. En pis tarafı, problemi çözmek için koda "trace" ler eklediğiniz anda, problem artık ya ortaya çıkmaz, yada çok daha nadir ortaya çıkmaya başlar. Yani heisenberg ilkesindeki gibi, bir bug'ı ya görüsünüz ama debug edemezsiniz, yada debug edersiniz ama bug'ı göremezsiniz :D

Heisenbug'lar da büyük çoğunlukla "multithreaded" programlarda görülür. Veya zamanlamanın çok kritik olduğu firmware uygulamalarında da ortaya çıkabilir. Böyle bir bug ile karşılaştıysanız, Allah kolaylık versin ... Her ne kadar programa trace eklemek bug'ın davranışını değiştirse de, gene de değişik yerlere trace'ler yerleştirip davranışına bakmak lazım. Veya eliminasyon yöntemi kullanarak, programın belli özellikleri devre dışı bırakılır ve bug hala oluşuyor mu oluşmuyor mu bakmak lazım. Ama bu tip bug'larda en etkili çözüm yöntemi, programı incelemek, kafanda simulasyonunu yapıp problemin nasıl olabildiğine dair bir teori ortaya koymak, sonra da bunu kanıtlayacak bir test kodu ekleyip tekrar tekrar test etmek.

Eğer başınıza bir heisenbug geldiyse, bir süre sürünmeye hazır olun :p
 
Son düzenleme:
=== HAYALET BUG ===

Evet, heisenbug ile uğraşıyorsanız, Allah kolaylık versin demiştim. Ama eğer bir "hayalet bug" ile uğraşıyorsanız, heisenbug'lara rahmet okuyacak duruma gelirsiniz! Olabilecek en pis buglar bunlardır, ve gereken bütün yazılım ve donanım geliştirme ekipmanları elinizde olsa bile, sizi haftalarca süründürür!

Hayalet buglar, hem yazılım hem de donanımın beraber geliştirildiği gömülü sistem projelerinde ortaya çıkarlar. Bir bug gözlemlersiniz, "hmm acaba şundan mı oluyor" deyip bir test kodu ilave edersiniz, problemin şekli tamamen değişir. Mesela daha önce takılıyorken, artık rastgele çalışmaya başlar. "haydaa, noldu yav, bir de şuna bakayım" diye bir test kodu daha eklersiniz, gene problemin şekli tamamen değişir. Daha önce çalışmayan bölüm artık çalışıyordur, ama önceden çalışan bölüm şu anda çalışmıyor! Yani bu bug, adeta "kendini aktif koruma" sistemine sahip, her çözüm teşebbüsünde tamamen şekil değiştiriyor. Hatta programdaki fonksiyonların link sıralamasını değiştiriyorsunuz, problem tamamen ortadan kalkıyor.

Bu bugların sebebi, hardware'den kaynaklanan bir sorundur, ve bu bugları en pis bug yapan da budur. Bundan önceki bugların hepsinde, en azında üzerinde çalıştığımız donanımın sorunsuz olduğunu varsayabiliyorduk. Problem varsa, bu bizim yazdığımız programda olmalıydı. Ama hardware sorunlu ise, aslında muhtemelen sizin programda herhangi bir sorun yok, ama hardware'deki sorun nedeniyle sizin program hatalı davranış sergiliyor. İşte bu yüzden de bunlara "hayalet bug" diyorum.

Şimdi benim de başıma gelmiş olan bir hayalet bug hikayesini anlatayım. Üzerinde çalıştığım PCI kart ile ilgili bir sorun rapor edildi. Son versiyon firmware ile program hatalı çalışıyor, bir önce firmware ile sorun yok, sadece son versiyondaki özellik eksik. İkisi arasında da çok az bir fark var. Tek fark, birisi ilave olarak bazı hesaplamalar daha yapıyor ve bunları da bir kenara yazıyor. O hesaplamaları çıkarıyorum, hakkaten sorun çözülüyor. Tekrar geri koyuyorum, problem geri geliyor. Kafayı yiyeceğim! birkaç ilave hesap nasıl firmware'in tamamen farklı davranmasına sebep olur?

Birkaç ilave test kodu ekliyorum, firmware tamamen saçmalıyor, hiç çalışmıyor. Hatta bir keresinde yaptığım değişiklik nedeniyle işlemci aşırı ısınmaya başladı neredeyse yanacak! Programa bir byte'lık NOP komutu (hiçbirşey yapma anlamına gelen komut) bile eklesem, gene sapıtıyor! Haftalarca süründüm ... En sonunda, işlemcinin adres ve data hatlarına lojik analizörü bağladım (bu tip lojik analizörler de son derece pahalı cihazlar) ve kodu bu şekilde çalıştırdım.

Programın assembly listing'ini aldım. Bu listing'de programdaki bütün makina dili görülebiliyor. Sonra da lojik analizörün topladığı makina dili program akışı ile kıyasladım. Problem şuymuş: RAM çipin adres dekoderi sorunlu imiş ve 4000H adresinden bir veri okunduğunda, oradaki gerçek veri değil de, 00H okunuyor!!! :eek:o_O:oops: Yani 4000H adresine programın ne tarafı denk geldiyse, orası yanlış çalışıyor.

Ama nasıl böğürüyorum laboratuvarda ... Hardware'in tasarımını yapan elemanı buldum, adamı neredeyse boğacağım. Biraz sakinleştikten sonra elemana yediği haltı anlattım ve tüm ekibe yemek ısmarlattım!
 
Son düzenleme:
olası başka bug çeşitleri için reserve
 
Last edited by a moderator:
=== HAYALET BUG ===

Evet, heisenbug ile uğraşıyorsanız, Allah kolaylık versin demiştim. Ama eğer bir "hayalet bug" ile uğraşıyorsanız, heisenbug'lara rahmet okuyacak duruma gelirsiniz! Olabilecek en pis buglar bunlardır, ve gereken bütün yazılım ve donanım geliştirme ekipmanları elinizde olsa bile, sizi haftalarca süründürür!

Hayalet buglar, hem yazılım hem de donanımın beraber geliştirildiği gömülü sistem projelerinde ortaya çıkarlar. Bir bug gözlemlersiniz, "hmm acaba şundan mı oluyor" deyip bir test kodu ilave edersiniz, problemin şekli tamamen değişir. Mesela daha önce takılıyorken, artık rastgele çalışmaya başlar. "haydaa, noldu yav, bir de şuna bakayım" diye bir test kodu daha eklersiniz, gene problemin şekli tamamen değişir. Daha önce çalışmayan bölüm artık çalışıyordur, ama önceden çalışan bölüm şu anda çalışmıyor! Yani bu bug, adeta "kendini aktif koruma" sistemine sahip, her çözüm teşebbüsünde tamamen şekil değiştiriyor. Hatta programdaki fonksiyonların link sıralamasını değiştiriyorsunuz, problem tamamen ortadan kalkıyor.

Bu bugların sebebi, hardware'den kaynaklanan bir sorundur, ve bu bugları en pis bug yapan da budur. Bundan önceki bugların hepsinde, en azında üzerinde çalıştığımız donanımın sorunsuz olduğunu varsayabiliyorduk. Problem varsa, bu bizim yazdığımız programda olmalıydı. Ama hardware sorunlu ise, aslında muhtemelen sizin programda herhangi bir sorun yok, ama hardware'deki sorun nedeniyle sizin program hatalı davranış sergiliyor. İşte bu yüzden de bunlara "hayalet bug" diyorum.

Şimdi benim de başıma gelmiş olan bir hayalet bug hikayesini anlatayım. Üzerinde çalıştığım PCI kart ile ilgili bir sorun rapor edildi. Son versiyon firmware ile program hatalı çalışıyor, bir önce firmware ile sorun yok, sadece son versiyondaki özellik eksik. İkisi arasında da çok az bir fark var. Tek fark, birisi ilave olarak bazı hesaplamalar daha yapıyor ve bunları da bir kenara yazıyor. O hesaplamaları çıkarıyorum, hakkaten sorun çözülüyor. Tekrar geri koyuyorum, problem geri geliyor. Kafayı yiyeceğim! birkaç ilave hesap nasıl firmware'in tamamen farklı davranmasına sebep olur?

Birkaç ilave test kodu ekliyorum, firmware tamamen saçmalıyor, hiç çalışmıyor. Hatta bir keresinde yaptığım değişiklik nedeniyle işlemci aşırı ısınmaya başladı neredeyse yanacak! Programa bir byte'lık NOP komutu (hiçbirşey yapma anlamına gelen komut) bile eklesem, gene sapıtıyor! Haftalarca süründüm ... En sonunda, işlemcinin adres ve data hatlarına lojik analizörü bağladım (bu tip lojik analizörler de son derece pahalı cihazlar) ve kodu bu şekilde çalıştırdım.

Programın assembly listing'ini aldım. Bu listing'de programdaki bütün makina dili görülebiliyor. Sonra da lojik analizörün topladığı makina dili program akışı ile kıyasladım. Problem şuymuş: RAM çipin adres dekoderi sorunlu imiş ve 4000H adresinden bir veri okunduğunda, oradaki gerçek veri değil de, 00H okunuyor!!! :eek:o_O:oops: Yani 4000H adresine programın ne tarafı denk geldiyse, orası yanlış çalışıyor.

Ama nasıl böğürüyorum laboratuvarda ... Hardware'in tasarımını yapan elemanı buldum, adamı neredeyse boğacağım. Biraz sakinleştikten sonra elemana yediği haltı anlattım ve tüm ekibe yemek ısmarlattım!
Hahahha mükemmel bi anlatım olmuş kafayı yedirmiş ama sonuç muazzam tüm ekibe yemek :popcorn1:
 

Forum istatistikleri

Konular
5,656
Mesajlar
97,295
Üyeler
2,438
Son üye
İbrahimSönmez

Son kaynaklar

Son profil mesajları

cemalettin keçeci wrote on HaydarBaris's profile.
barış kardeşim bende bu sene akıllı denizaltı projesine girdim ve sensörleri arastırıyorum tam olarak hangi sensör ve markaları kullandınız yardımcı olabilir misin?
m.white wrote on Altair's profile.
İyi akşamlar.Arabanız ne marka ve sorunu nedir.Ben araba tamircisi değilim ama tamirden anlarım.
* En mühim ve feyizli vazifelerimiz millî eğitim işleridir. Millî eğitim işlerinde mutlaka muzaffer olmak lâzımdır. Bir milletin hakikî kurtuluşu ancak bu suretle olur. (1922)
Kesici/Spindle hızı hesaplamak için SpreadSheet UDF'leri kullanın, hesap makinesi çok eski kalan bir yöntem :)
Dr. Bülent Başaran,
Elektrik ve Elektronik Mühendisi
Yonga Tasarım Özdevinimcisi
Üç güzel "çocuk" babası
Ortahisar/Ürgüp/Konya/Ankara/Pittsburgh/San Francisco/Atlanta/Alaçatı/Taşucu...

Back
Top