Home Index Search Links About Us
[LinuxFocus Image]
[Navegation Bar]
  Duyumlar   Belgelikler   Kuruluşlar  Öğütler  

Düzgü (Kod) Yanlışlarının ddd ile Saptanıp Giderilmesi

Yazar: Jose M. Laveda

Çeviri: Osman Kazdal


Giriş

Debugger nedir?

DDD nedir?

GUI Ortamı

Dipten başlangıç

Genel görevler

Son sözler

Giriş

Bu yazının amacı, daha önce hiç debugger kullanmamış kullanıcılara ya da kullanan kullanıcılara bu günlük çalışma için daha hoş bir grafik ortam göstermektir. gdb isimli debugger'ın yapabildikleri ve sağlamlığı hakkında çok şey yazılabilir, ancak, her zaman olduğu gibi öğretici amaçlar için bunları basitleştirmeye karar verdik :)

Debugger nedir?

" Bir zamanlar, tek işi kendi kodu içinde hata bulmak için aşağıdakini kullanan bir programcı vardı:

/*Code*/
(...)
loop
change_a_variable;
show_value_of_variable;
end_loop
(...)

Çalışma zamanı içerisinde, değişkenlerin değerini araştırabilmek için kaynak kodu içine bir çok kez bu satırları eklemeye zorlanmıştı. Bu zor bir görevdi ve programcının hayatını zorlaştırmaktaydı ve kendi kodunda hataları bulmanın zahmeti, o kodu yazmanın zahmetini ikiye katlıyordu.(..)".

Kim kendini daha önce böyle bir durumda bulmadı ki? Sık sık programımızda hata oluşur, her şeyi değiştirmiş ve herşeyi denemişizdir, denenecek az şey kaldığından bu aşamada neredeyse derleyicinin hatalı olduğuna hemen hemen kendi kendimizi ikna etmişizdir... İşte burada hata bulucu yazılımlar devreye girer.

Debugger aşama aşama programınızın çalışmasını kontrol etmenizi sağlar, bu şekilde değişkenlerin durumu, tanımlanması, bazı koşullarda nasıl davrandıkları kolayca takip edilebilir. Bütün bunlar, yine, program çalışırken yapılır. Bu havada kalan tanımlama yeterince açık değilse, bunu yazının ileriki aşamalarında daha açık hale getirmeyi umuyorum.

Öykümüzde programcının spy isminde, aşağıdakileri yapmasını sağlayan bir debugger'ı olsaydı neler olurdu:

jose# spy my_program

ve eğer spy'ı yardıma çağırdıktan sonra, programcımız şunları yapabilseydi:

spy > execute my_program "up to line number 50"
spy > show me the value of the variable <X>
spy > what is the type of variable <X>

Muhtemelen, bu anda, hayali programcımız sevinçten havalara uçmaktadır, çünkü en sonunda hatanın sebebini bulmuştur.

Açıkça, spy adındaki elaygıtı çok kullanışlı olmuştu, çünkü programcının programının çalıştığı sırada değişkenlerin değerlerini ve tanımlanmalarını kontrol edebilmesini sağlamıştır. Bu debugger'ın özüdür, ancak tabii ki kabaca resimlendirilmiştir.

Dikkat !!: Debugger'lar sadece debug parametreleriyle çalışan derleyiciler ile derlenen programlar ile çalışır. GNU gcc derleyicisi örneğinde bu parametre -g dir.

Tüm Linux kullanıcıları için GNU Genel Lisansı ile elde edilebilecek GDB (The GNU Source-Level Debugger) adında bir debugger vardır (bu değişik platformlarda da bulunabilir). Bununla C, C++, Modula-2 ve assembler kodları debug edilebilir.

Muhtemelen, şu anda kullandığınız Linux bu yazılıma sahiptir, eğer değilse, Linux'ınızı yenileyin veya programın kaynak kodunu bulun. Bu birçok yerde bulunabilir;)

Diyelim ki, /usr/src dizini altına kaynak kodlarını kopyaladınız, sonra /usr/src/gdb-4.xxxx/gdb dizini altına gidin ve doc dizinine inin. Orada make gdb.dvi;make refcard.dvi komutunu kullanarak gdb dokümanlarını oluşturabilirsiniz. Bu dosyalar tüm linux sürümlerinde kolayca görüntülenebilir.

DDD nedir?

Gdb'nin ayrıntılı sunumu ve tüm komutlarını açıklamak yerine, kullanıcı tarafından çok daha kolaylıkla kullanılabilecek olan ddd (Display Data Debugger) isimli ortamı açıklamak, yeni kullanıcılar için çok daha anlamlı olacaktır.

DDD ortamı, genellikle konuşan, ayarlanması çok daha kolay olan ve hata bulma için kullanıcıya daha anlaşılır bir arayüz sunar. Yine de, belirtilmelidir ki, ddd sadece gdb üzerinde kullanılan bir grafik ortamdır. Bu nedenle ddd'nin çalıştırılması için gdb'ye gereksinim vardır. Aslında, ddd kullanıcının gdb üzerinde doğrudan değişiklik yapmasına izin vermektedir. DDD ile kullanılabilen dbx, xdb gibi başka debugger'lar da vardır.

DDD için iyi bir bilgi kaynağı http://www.cs.tu-bs.de/softech/ddd/ adresinden elde edilebilir. Ayrıca, eğer RedHat kullanıyorsanız kaynak kodlarını rpm formatında bulabilirsiniz. DDD'nin iki ayrı sürümünü bulabilirsiniz, Motif kitaplıklarıyla dinamik olarak derlenmiş sürümü, diğeri ise statik olarak derlenmiş sürümüdür. Statik sürüm kendi Motif kitaplüklarü olmayan kullanıcılar içindir.

DDD'nin LESSTIF(http://www.lesstif.org) karşısındaki şu andaki durumunu dikkate almıyorum. Motif'in ücretsiz bir benzeri olan lesstif'in şu andaki durumu hakkında pek bilgi sahibi değilim. Kısa bir zaman önce, bir yama sayesinde sadece lesstif altında derlenebiliyordu. Bunu 1.2.13 çekirdek ve lesstif 0.75 ile kullandım (Sanırım ;). Lütfen, lesstif projesinin sayfalarına bu proje ile ilgili daha fazla bilgi almak için bir göz atınız.

İşe girişiyoruz, ddd'yi çalıştırmamızla birlikte, şununla karşılaşıyoruz:


Resim 1: DDD ana ekranı

ddd'yi çağırmanın üç değişik yolları vardır; ilkinden daha önce bahsetmiştik ve diğerlerini de aşağıda bulacaksınız:

ddd <program> core
ddd <program> <process_id>

Core isimli dosya bir program çöktüğü zaman üretilir ve çöküşün sebebi ile ilgili hatanın oluştuğu sıradaki programın durumu ile ilgili yararlı bilgiler içerir. Eğer sizin sisteminiz core dosyaları yaratmıyorsa, core dosyaları için çevre değişkenlerine bir göz atınız ('ulimit -a' hepsini gösterir, ya da 'ulimit -c <değer>' diğer gerekli değerleri veya maksimum boyutları gösterir).

Proses id çalışma zamanı sırasında programı incelememizi sağlar.

ddd'nin grafik yapısı bir işi yapmak için birden fazla yol sunar; Burada hepsini açıklayamam, ancak en basit olanlarını açıklayacağım. DDD'nin ana konsolunun en altındaki pencere, ddd'nin çalıştırdığı tüm işlemlerin loglarını gösterir. Bu log penceresi gdb'nin komut satırından çalıştırılmasını öğrenmede çok yararlı olabilir.

GUI ortamı

1. resim ana pencerenin 3 alt pencereye bölündüğünü gösteriyor. En alttaki alt pencere yalın debugger consoludur (bizim durumumuzda bu gdb'dir). Burada, eğer ddd arayüzümüz olmasaydı burada doğrudan gdb komutlarını kullanabilirdik. Ortadaki alt pencere ise programın kaynak kodunu göstermektedir, ve üst alt pencere ise programın değişkenleri ve nesneleri için grafik bir ortamdır. Son olarak ise, araç barı (toolbar) ddd komutlarının çalıştırılmasının kontrolünü sağlar.

Ana pencere dışında ise çalışan proses için bir ve debug edilen programın kaynak kodu için de ayrı birer pencere vardır. Bunların ikisi de isteğe bağlıdır.

ddd ile birlikte, hata bulma sırasında gerekebilecek yardım için tüm kaynaklar gelmektedir. Örnek vermek gerekirse, imleç arayüz üzerinde bir değişken üzerine veya arayüz üzerindeki herhangi bir butonun üzerine geldiğinde ayrı bir dialog kutusu ekrana gelir; bu dialog kutusu o andaki durumla ilgili gerekli bilgi verir. Ayrıca, ana pencerenin alt tarafında ise, ddd'nin durumu, hangi komutun çalıştırıldığı ve o komutun çıktılarını göstermektedir. Sağ tarafta her türlü yardıma bir popup menü sayesinde ulaşılabilir. Açılan pencerede bir konu seçip F1 tuşuna bastığınızda daha fazla bilgi elde edilebilinir. Son olarak gdb konsoludan "help" yazarak debugger hakkında genel yardım veya belli bir konu üzerinde yardım alınabilir.

Benimsenmiş olarak, ddd tek çerçevede birleşmiş üç alt pencere sunmaktadır. Ayrıca, "Preferences" menüsü ddd arayüzüne benimsenmiş şekil yerine ayrı pencereler açtırabilir.


Resim 2. File menüsü için yardım

Dipten başlangıç

Debugger konsolu, debugger2ın kullanımı öğrenmemizde ilk adımlarımızı atacağımız yerdir; gdb üzerinde deneyimli kullanıcılar ddd ile buradan çalışabilirler. Benim durumumda bu konsol grafik arayüz üzerinden komutlar çalıştırıldıkça neler olduğunu izleyebilmem için yardımcı olmuştu. Commands-Command History seçimi o ana kadar çalıştırılmış tüm komutları listeler.

DDD'nin yapabileceklerini öğrenebilmek için orijinal dokümanlara bakmak daha yararlı olacaktır. Her durumda debugger ile bir kaç basit işlemin nasıl yapılabileceğini açıklayacağım.

Genel Görevler

Hata bulmak için, kaynak kodu yükleme işlemi menülerden File seçeneği seçilerek yapılabilir; kaynak kodunun içeriği bu alanda görüntülenir. Bu aşamadan itibaren, kaynak koduna göz atarak, bir değişkenin değeri ve tipi incelenebilir ve program kontrol altında çalıştırılabilir...

Programın çıktısı bir pencere ile izlenebilir ( Options menüsünden Run in Execution window ) veya debugger konsolundaki program çıktısından doğrudan izlenebilir ( bu yöntem program Motif veya başka bir GUI tabanlı kitaplıklar kullanıldıysa işe yaramaz).

Kaynak kodu içinde imleci herhangi bir değişken üzerine getirmeyi denerseniz, o değişkenin o andaki değerini ddd çıktısı içerisinde görebilirsiniz. Ayrıca, sağ fare butonuna tıklarsanız aşağıdaki menü çıkacaktır:


Bu menü fname isimli değişkenin değerini incelememizi sağlar, alttaki pencerede, çizim bölgesinde bu değişkenin bir işaretleyici veya gerçek bir değişken olup olmadığı gösterilir (işaretleyici başka bir değişkenin bellekteki adresini saklayan başka bir değişkendir). What is bölümü ise seçilmiş değişkenin yapısını veya tipini gösterir. Lookup rastlanan benzerlikleri takip etmemizi sağlar. Son olarak, Break at ve Clear at bölümlerinde kısaca anlatacağım breakpoint diye deyimlendirilen kullanımlardır.

Kaynak kodun altındaki düğmelerin bulunduğu barda da değişik seçenekler mevcuttur, sadece gerekli parametreleri soldaki boş kutuya yazıp gerekli eylemi seçmek yeterlidir.

Bir break-point, programı istediğiniz satırına kadar çaılıştırmanızı sağlar; belli bir noktada programın çalışması durur ve kullanıcı değişkenlerin bu noktadaki değerlerini izleyebilir. Ayrıca, bu noktadan sonra kullanıcı programın çalıştırılmasını elle adım adım yaptırabilir, ve aşama aşama programı izleyebilir. Breakpointlerin olmaması durumunda, program problemsiz çalışır veya bir hata sonucu çalışamadan sona erer, bu durumda programı incelemek için bir işlem yapmak için çok geçtir. Program çalıştırıldığı sırada hata bulma işleminden geçirilmelidir.

Programınıza bir breakpoint eklemek için aşağıdakileri yapınız:

  • Breakpoint koymak istediğiniz bölümün sol tarafına imleci getirip sağ fare butonuna tıkladıktan sonra Set Temporary Breakpoint seçeneğini seçmeniz yeterli olacaktır. İkisi arasındaki fark geçici olan breakpointlerin ilk çalıştırmadan sonra kaybolmasıdır. Diğeri ise sadece doğru komut verilirse kaldırılabilir (Bu komutu tahmin edebilir misiniz? :) ).
  • Break at isimli butonu kaynak kodu penceresinden seçerek
  • Debugger konsolundan break yazarak
  • Menü seçeneklerinden Source->Edit Breakpoints bölümünü seçerek, bu ayrıca bu programın kullanımı için ayrı bir pencerede açacaktır.

Resimde 70 ve 71. satırlarda, kaynak kodu içinde iki breakpoint görünmektedir. Breakpoint için kullanılan sembol kendi kendini çok iyi açıklamaktadır.

Aşağıdaki menü breakpointleri kullanmaya yarar:

Condition seçeneği ile, koşullu breakpointler yerleştirilebilir. Bu durumda, programın breakpoint satırında durması için koşulun gerçekleşmesi gerekir. Başka bir koşul çeşidi ise Ignore Count seçeneğidir. Bu durumda, koşulun doğru olması için breakpoint satırına <n> defa ulaşılması gerekir. Örneğin, herhangi bir döngünün 15. iterasyonundan sonra programı durdurmak için kullanılabilir.
Program herhangi bir breakpointte durduğunda, gerekli menülerin seçeneklerini kullanarak programdaki değişkenlerin değerlerini inceleyebiliriz. Bütün bu fonksiyonlar ana menüde bulunmaktadır (örnek; menu Data).
Kodun çalıştırılmasını kontrol etmek amacıyla, bu iş için kullanılan düğmelerin bulunduğu pencereyi kullanacağız. Bu pencere ana pencerenin sağ üst köşesinde bulunmaktadır.


Menü bar ile düğmelerin bulunduğu pencere arasındaki benzerlik görülebilir.

Programı çalıştırıp durdurabiliriz, menü barının kullanılması durumunda, dialog penceresini kullanarak programa bazı parametreler vermek olasıdır. Step komutu, programı satır satır çalıştırır, bu durumda, programın herhangi bir yerinde bir fonksiyon çağırılırsa, hata bulucu o fonksiyonun başına gidecek ve bir sonraki Step komutunu bekleyecektir. Öte yandan, Next komutu ise, fonksiyonları tek satır olarak kabul eder ve bu işlemleri tek aşamada yapar.

Continue komutu, herhangi bir breakpointte durulduktan sonra programın çalıştırılmasına devam edilmesini sağlar. Kill, Interrupt, Abort komutları ise programın çalıştırılmasını durdurmak için kullanılır.

Muhtemelen, bu grafik ortamın en önemli özelliği, pencerenin üst tarafında bulunan bilgi gösteren penceredir. Grafiklerle, bilginin yapısını, içeriğini ve diğer bilgiler ile arasındaki bağlantıları buradan izleyebiliriz. Bir sonraki örnekte, bir dizi (argümanlar) ve o dizinin dört elemanı görülmektedir.

Bu pencere, çok geniş bilgi sunar, Data->More Status Displays bölümünden yapılabilecek ayarlarla, data penceresinde görmek istediğiniz herşeyi ayarlayabilirsiniz. Bir önceki örnekte, işlemcinin kayıt değerlerini, gerekli dinamik kitaplıkları ve programın çalışma durumunu görebilirdik:


Son Sözler

DDD ortamı, aynı program kullanılarak, Options->Preferences menüsünden ayarlanabilir. Ayrıca, bu ayarlar Motif programlarının klasik yöntemi olan $HOME/.dddinit dosyasından da yapılabilir. Ayarlanabilecek tüm kaynakların açıklanması bu yazının dışındadır.

DDD ile gelen kitapçığın (ddd.ps)ve hata bulucunun kitapçığının (Debugging with GDB) okunması çok önemlidir. Yine de, kullanıcı bunları kısa bir zaman içinde kendi kendine de öğrenebilir. Yapılamsı gereken sadece iyice tanıdığınız bir kodu burada hata bulma işlemine tabii tutmanızdır. Bu şekilde hata bulucunun yapabilecekleri ortaya çıkacaktır.

Ve son olarak, yazıda hatalar yaptıysam özürlerimi sunarım :)

Daha Çok Bilgi İçin::
© 1998 Miguel Angel Sepulveda
Bu sanal yörenin bakımı Miguel A Sepulveda tarafından yapılmaktadır..