Sayfalar

Cumartesi, Mart 10, 2007

Böcek Avı yahut Debugging





Debugging kelime manası Böceklerden arındırmadır. Hikayesi de 1945 de Mark II adlı Askeri devasa bilgisayarlarında programların düzgün çalışmasını engelleyen gerçek, fiziksel bir böcek bulan Dr. Grace Murray Hopper bilgisayar hatası anlamına da gelen "böcek" ("bug", "debugging", vs.) terimini de kültürümüze armağan etti. Yukardaki resim O ilk Bug'a ait.
Ben hata ayıklama diyeceğim. Ve Basit bir örnek vereceğim.

Genetik metodla 4 Bilinmiyenli Denklem Çözümü yazımın sonunda "FGA'nın Threadlı versiyonunu kullanın düz olan kısmında problem var." demiştim. Bu konuda FGA nın yazarına
e-posta attım. Bir süre sonra cevap geldi. özetle
"Hata ayıklamak için yeterli vaktim yok ama zannederim problem sizin yazdığınız fonksiyonlardaki hafıza yönetim kısımlarındadır."
diyordu. Bu durum da iş başa düşmüştü. Bir fırsat bulduğumda kolları sıvadım.
Yaptıklarım adım adım yazıyorum.

1) CodeBllocks 'da Denklem projesini açıyoruz.
2) Programın Build Target kısmını Debug olarak seçili olup olmadığına bakıyoruz Debug değilse Debug olarak seçip tekrar derliyoruz.
3) F8 ile yada Menüden Debug ->Start ile çalıştırıp Hata ayıklamaya başlıyoruz.
4) Program bir süre sonra Program received signal SIGSEGV, Segmentation fault
hatasını veriyor.

5) Backtrace 'i görmek siteyip istemediğimizi soruyor evet deyip CallStack penceresine geçiyoruz.

6) hata memcpy () fonksiyonunda oluşmuş. sebep olan satıra tıklayıp koda ulaşıyoruz
memcpy(child0, parent0, length * sizeof(GeneType));
7) Demek ki child0 yada parent0 işaretcilerinden -pointer- biri yada her ikisi NULL
8) Kodda biraz yukarıya çıkıp bakıyoruz ki child0'ın değeri new ile alınmış, hafızayı bukadar kısa süre de tüketmiş olamıyacağımızdan parent0 işaretçisine yöneliyoruz. parent işaretçisi değerini select fonksiyonundan alıyor.
9) CodeBlocks'un imkanlarından faydalanarak ilgili yere zıplayıveriyoruz.

10) Bir de ne görelim

inline GeneType *Population::select()
{
switch (select_type) {
case SELECT_UNIFORM:
return select_uniform();
default:
float choice = (float)rand() / RAND_MAX * total_score;
float position = 0;
for (int i = 0; i <>= choice)
return chromosome[i];
else
position += score[i];
}
return NULL;
}

switch'in default kısmında for döngüsüyle seçimin muhakkak yapılacağı varsayılmış seçim yapılmadığı durumda fonksiyon NULL değerini döndürüyor.

11) Emin olmak için return NULL; satırından önce puts("Returning NULL!!!"); satırını ekleyip. Menuden Debug->Stop Debugger ile debugger'ı durduruyoruz.

12) Yeniden, derleyip çalıştırıyoruz. Ve program çakılmadan önce bizim yazdığımız mesajı alıp
Emin oluyoruz. Vee Mutlu son.

Bundan sonrası için konuyu detayıyla yazıp Presto'ya mail attım.

ve cevabını buraya orjinal haliyle alıyorum.

the problem is the following:
sometimes the fitness function returns that small values around 10^-39 and so, if "choice" is maximum, "position + score[i]" never reaches choice this is due to a limit of binary representation of floating point
numbers on computers: they have to be approximated because not all
rational numbers can be represented
try to compile and execute this code and you'll know what I mean:


#include
using namespace std;

main()
{

float sum = 0.0;
for (int i = 0; i <> sum += 0.001;
if (sum == 1)
cout << "sum is exactly 1" <<>
else
cout << "sum is NOT exactly 1" <<>
cout << "sum is " <<>
cout << "but 1000 * 0.001 is " <<>
}


so, to avoid this problem, instead of return NULL in fga.hpp, select function, try to write return chromosome[n - 1]

this should fix the problem, since in the case that the floating point
representation fails it is because it doesn't completely reach choice,
but we know for sure that the last chromosome should be selected

I'll update the FGA code on sourceforge soon

thanks for your detailed info

kısaca fga.hpp de select kısmında sondaki
"return NULL;"
satırı yerine
return chromosome[n - 1];
kullanmamız problemi çözüyor.

3 yorum:

Adsız dedi ki...

selam.
Bug konusunda bir noktaya dikkatinizi çekmek istiyoru. resimde first actual bug.... diye gidiyor.
yani bundan öncesindede bug terimi kullanılıyor olabilir.
;)

birol kuyumcu dedi ki...

dikkatiniz için teşekkürler
fakat
bu konuda çeşitli rivayetler var.
bakınız
http://sozluk.sourtimes.org/show.asp?id=198099
http://en.wikipedia.org/wiki/Debugging#Origin
http://en.wikipedia.org/wiki/Computer_bug#Etymology

Adsız dedi ki...

sn:derin deli mavi;
hakikaten ilginç bu bug meselesi....