DEBUGGING | GDB'ye Giriş

01:00 ,
GDB (GNU Debugger) GNU ekosistemi içinde bulunan debugger'dır. Unix tabanlı pek çok sisteminde, C/C++ gibi birçok programlama dilinde hata ayıklamak için kullanılmaktadır. Biz de C dilini baz alarak nasıl kullanılacağını birkaç blog yazısında anlatmaya çalışacağız. 

GDB birçok unix tabanlı sistemde varsayılan olarak kurulu gelmektedir. Komut satırından gdb komutunu girdiğinizde aşağıdaki gibi bir çıktı alıyorsanız sistemizinde GDB 'nin var olduğu anlamına gelir. GDB ile sisteminizde var olan halihazırda çalışan programları debug edebileceğiniz gibi, uzak bir sistemde çalışan bir programı da remote debug ile debug edebiliriz. Fakat bu iki durum bu yazının konusu olmayacaktır.


Eğer bir sistemde gdb kurulu ise, gdb'nin sunduğu tüm olanaklar elimizin altında demektir. Artık bize sunduğu özellikleri öğrenmeye başlayabiliriz. 

GDB'yi burada bırakıp tekrar başa dönecek olursak yazdığımız programın hatalarını ayıklayabilmek için programı -g seçeneği ile derlemememiz sonrasında daha kolay bir hata ayıklama ortamı sağlayacaktır. Derleyici debugger için gerekli olan bilgileri bu derleme parametresi sayesinde çalıştırılabilir programın içine gömebilecek ve debugger bize daha fazla olanak sağlayabilecektir.


Yukarıda görüldüğü gibi programımız Segmentation Fault veriyor ve bizim bunu çözmemiz gerekmekte. Çalıştığımız ortam Unix environment bir ortam ise başta da dediğimiz gibi kullanabileceğimiz en büyük yardımcı gdb. Doğrudan gdb'yi çalıştırıp ilgili dosyayı içeriden verebileceğimiz gibi gdb a.out ile gdb'yi başlatma seçeneğini de kullanabiliriz. 

start

  • start komutu geçici olarak main'e breakpoint koyar ve programın GDB altında debug sürecinin başlamasını sağlar. 
  • start [Arguments] programa argüman geçilmesini sağlamak için start komutu yanına argümanları yazmamız yeterlidir.

file

gdb'yi doğrudan herhangi bir dosya vermeden çalıştırırsak, gdb içinde debug edilmek istenen binary dosyayı belirtmemiz gerekmektedir.


 Bunun için file dosyaismi şeklinde olan komutu kullanmamız gerekmektedir.

run & continue

  • r[un] ile bir sonraki breakpoint'e kadar veya breakpoint yoksa programın sonuna kadar çalışmasını sağlar.
  • r[un] [Arguments] : Programa arguman geçilmesini sağlamak için run komutu yanına argümanları yazmamız yeterlidir.
  • c[ontinue] ile devam eden debug işleminin durduğu yerden bir sonraki breakpoint'e kadar veya programın sonuna kadar devam etmesini sağlar.

list

List komutu ile programımızın kaynak kodunu görmek mümkündür.

break

Eğer debugger kullanım deneyiminiz varsa debug işleminin en kritik noktası, uygun yerlere breakpoint konulmasını sağlamaktır. Breakpoint ne işe yaramaktadır dersek? Debugger program kodlarını çalıştırmaya başlar ve bir breakpoint'e geldiğinde durur ve kontrolü bize bırakır. Ta ki biz devam komutunu verene kadar. Bu noktada kritik ve hata olabilecek noktalara breakpoint konulması gerektiğini söyleyebiliriz. Biz de öncelikle main'e ve malloc işleminin yapıldığı noktaya breakpoint koyalım.

  • info b[reakpoints] komutu ile tüm breakpoint'lerimizi listeleyebilirsiniz.
  • d[elete] komutuyla tüm breakpoint'leri silebilirsiniz.

step&next

  • s[tep] Tek adım ilerler, fonksiyon içerisine dallanabilir.
  • n[ext] Tek adım ilerler, fonksiyon içerisine dallanmaz.

finish

fin[ish] ile girilen fonksiyonun, döngünün veya buna benzer olayların sonlanmasını sağlarız.

whatis

Herhangi bir değişken, fonksiyon gibi ifadelerin türünü öğrenmek için kulanabileceğimiz bir komuttur. Örneğin
  • (gdb) whatis main dediğimizde
  • type = int ()
şeklinde bir çıktı alınacaktır.

where

Programın o an nerede olduğunu söyler. Program çalıştıktan sonra herhangi bir yerde çakılırsa sıkıntılı yerleri bulmamıza yardımcı da olur. Aşağıda segmentation fault aldıktan sonra where komutunu çalıştırırsak karşımıza olası üç stack frame listelenmektedir.

frame

where komutu çıktısından elde edilen verilerden sonra frame komutu ile ilgili stack frame noktasına  gidilebilmektedir. #0, #1, #2, #3 şeklinde listelenen frame'lerden olası nokta olduğunu düşündüğümüz yere yani frame 3 gidebiliriz.

info functions

Binary dosya içindeki fonksiyonların listelenmesi için info function komutunu girmemiz yeterlidir.


Bu komut ile olası breakpoint koyulacak fonksiyonları görmemiz mümkündür.

layout asm

layout asm ile pencere ikiye bölünerek assembly komutlarının görüleceği bir ekran daha karşımıza çıkacaktır.


Bu sayede rahatlıkla OpCode'ları izlemek mümkün hale gelecektir. Bu noktada bilmemiz gereken assembly çıktıları için AT&T ve Intel notasyonu şeklinde çıktı almak mümkün. Bu ayarı; set disassembly-flavor intel or att şeklinde ayarlamak mümkündür. 


Genellikle Intel notasyonu yaygın olduğu için biz de o notasyonu kullanacağız. Assembly çıktılarını görebileceğimiz bir diğer komut ise dissassemble fonksiyon ismi ile istediğimiz fonksiyonun assembly çıktılarını almak mümkün. Yukarıda main fonksiyonu için çıktıyı görmek mümkündür.

info locals

local değişkenlerin tamamının durumunu gözlemlemek için kullanılması gereken komut info locals 'dir.

info registers

register'ların tamamının durumunu gözlemlemek için kullanılması gereken komut info registers 'dir.

info source

debug edilen dosyaya ilişkin bilgilerin detaylı olarak görüntülendiği komut info source'dur.

print

Herhangi bir değişkenin değerinin görüntülenebildiği komut print'dir. print değişken ismi, register ismi şeklinde farklı biçimlerde kullanılabilir.


print işlemini /x, /d, /o ve /t gibi çıktıları istediğimiz formatta biçimlendirebiliriz.


Tüm çıktı formatlarını help x komutuyla rahatlıkla görebiliriz.


Note: GDB öğrenme bakımından zor ama kullanması kolay bir debuggerdır. Yolun başında biraz sabır gerekmektedir. Bu nedenle yolun başında, öğrenme sürecinde olanlara yolun zorlu ama aydınlık olacağını söyleyebilirim.



Podcast Tavsiyesi - II

05:13

Yalansavar

www.yalansavar.org


Skeptik, Şüpheci bir grup insanın safsatalarla ilgili yaptığı bir podcast yayını. Özellikle bizim gibi toplumlarda zihinsel kirlenmeyi engellemesi açısından herkese tavsiye ederim.

Muhabbet Teorisi

http://www.muhabbetteorisi.com/
www.muhabbetteorisi.com/feed/podcast/


Yayın hayatına 2011 Kasım ayında başlamış Açık Bilim oluşumunun sonlanmasının ardından Muhabbet Teorisi ismiyle yeniden ortaya çıktığı bir podcast yayını. Bilimle ilgilenenlere tavsiye edilir.

Havadan sudan

http://www.35milimetre.com/havadan-sudan/


Hande Turan ve Mehmet Turan çifti tarafından gündeme/hayata dair samimi izlenimlerini paylaştıkları bir podcast kanalı. Herkese tavsiye ederim. Kendilerine tavsiyem ise programlarına biraz daha konuk çıkarmaları. Böylece yayın içerikleri biraz daha zenginlik kazanmış olur.

Ottoman History Podcast

http://www.ottomanhistorypodcast.com/



Osmanlı tarihiyle ilgili eşi benzeri görülmemiş bir podcast. İngilizce ve Türkçe yayınlar bulmak mümkün. Kesinlikle tarihe karşı algılarınızın biraz da olsa düzeleceğini düşündüğüm bir podcast yayını. Tarih konusunda tarafsız-doğru yayın bulmak biz de her yerde olduğundan daha da zor olması bu podcast yayınını daha kıymetli hale getiriyor. Sadece Türkçe yayınların olduğu podcastler ise aşağıdaki linkte:

http://www.ottomanhistorypodcast.com/p/turkce.html


Girişimci Muhabbeti

http://www.girisimcimuhabbeti.com/


Samican Tandoğdu ve Baris Kocdur tarafindan sunulan bir podcast yayını. Temelde internet girişimleriyle (start up) ilgili konuşmaların yapıldığı bir yayın. Girişimci ruhlu insanlar ve start up dünyası hakkında fikir sahibi olmak isteyenlere tavsiye olunur.

FHE KÖLN Radyosu

http://www1.wdr.de/radio/podcasts/fhe/koeln_radyosu120.podcast


Almanya'dan Türkiye'nin nasıl göründüğü hakkında fikir sahibi olmak isteyenlere ve dinleyicilerin konuk olduğu pazar programı ile gurbetçilerimizin fikir ve zihin dünyasına giriş yapabilirsiniz.


Podcast Tavsiyesi

06:59


İstanbul gibi yaşam kalitesinin düşük olduğu bir şehirde (yöneticilere, yaşayan O çoğunluk kitleye buradan teşekkürler) ulaşım süresince kendimizi soyutlayabilmek (akıl ve ruh sağlığı açısından biraz da zorunlu) zamanızı iyi değerlendirmek açısından önem arzetmektedir. Bu  konuda sosyal medya hesaplarından arta kalan zamanlarda dinleyecebileceğiniz türkçe podcast tavsiyelerinde bulanacağım. Hem kendimizi geliştirebileceğimiz hem de hoş vakit geçirebileceğimiz podcastler aşağıda listelenmiştir.
  • http://www.acikbilim.com/

    Popüler bilim konularında türkçe podcast hazırlamaktadır. Popüler bilimle ilgilenenlerin tavsiye edilir.
  • http://devpod.org/

    Daha çok yazılım dünyası ile ilgili yayınların olduğu bir podcast. Meslek olarak bu alanda çalışıyorsanız takip etmenizi tavsiye derim.
  • http://www.galipdursun.com/gerisihikaye/

    Anadolu korku hikayeleri fikriyle başlayıp bir ayağı anadolu diğer ayağı tüm dünya olan bir podcast olan Gerisi Hikaye, ilk başlarda dinleyecek podcast olmadığından dinlediğim ama sıkı bir takipcisi olduğum korku hikayeleri konusunda başarılı ve tek türkçe podcast. Umarım ömrü  uzun olur. Bu topraklarda iyi şeylerin ömrü hep kısa olmuştur. Umarım bu konuda bizi yanıltırlar.
  • http://bilimkazani.org/

    Bilim kazanı, ismiyle müsemma bilimsel konulara getirdikleri farklı anlatım tarzları ile eğlenceli bir podcast. Genç bilim insanlarının Amerikadan ülkemize seslenmeleri de ayrı bir güzellik. Son zamanlarda podcast sıklığı 0 düzeyine yaklaştı. Umarım düzeltirler.
  • http://bahrikaracay.com/

    Değerli bir bilim adamı Bahri Karaçay'ın Amerikadan yaptığı podcast'ler bilimle ilgilenenler için faydalı olacaktır.
  • http://acikradyo.com.tr/

    Bir çok konuda faklı yayınlar bulabaliceğiniz bir oluşum. Yayınları bitmiş podcast arşivlerine de ulaşabilirsiniz. Mutlaka ilginizi çeken konular bulabilirsiniz.
  • http://kayitbasladi.com/

    Tam bir kafa boşaltma ve geyik ortamı. Şiddetle tavsiye edilir.
  • http://www.avustralyadakideliler.com/

    Yurt dışına çıkmak/çalışmak isteyenlerin Avustralya merkezli bir grup insanın deneyimlerini dinleyebileceğiniz bir podcast. Kayıtlarını biraz daha iyi cihazlarla yaparlarsa daha da dinlenilese olacak.
  • http://adaptasyon.tumblr.com/

    Adaptasyon, yeni teknoloji, yeni ekonomik dengelerin toplumdaki etkilerini Dünya ve Türkiye açısından değerlendirme çalışan bir podcast yayını.
  • https://teknoseyir.com/

    Bu işi gerçekten para merkezli değil iyi şeyler yapalım gayesiyle yapıldığına inandığım bir oluşum olan Teknoseyir ekibinin podcasti. Teknoloji konusunda meraklı iseniz dinlemenizi tavsiye ederim. Teknoseyir vasıtası ile tanıştığım Otoseyir tayfasından Can Akbulut & Emre Çelikkol ikilisini ise daha çok görmek dileğiyle.

Linux'te execl ile dosya çalıştırma


execl fonksiyonunu çağırdığımız anda parametre olarak verdiğimiz çalıştırılabilir dosya execute edilir ve program bu yeni process'e dönüşür. 


Aşağıda programda process fork edilip child process'i /bin/ls process'ine dönüştürülmektedir.


Çıktılardan istenilen sonuçların elde edildiği görülmektedir.



Linux'te child process oluşturma


Linux'te child process oluşturmak için ilk aşama fork fonksiyonunun çağrılmasıdır. 


 fork çağrıldığı anda processin bir kopyasını oluşturur. Genelde fork exec'le beraber kullanılarak ikinci bir process oluşturmak için kullanılır. Linux sistemlerde process oluşturmanın yolu fork ve ardından exec fonksiyonunu çağırmaktır. fork fonksiyonunun geri dönüş değeri 0'a eşitse child process anlamına gelmektedir. child process'in  bir process id'si bulunmaktadır ve bu process id'si fork fonksiyonunun geri dönüş değeri olan değer değildir.  Bu ikisi karıştırılmamalıdır.



Yukarıdaki basit kodun çıktısı aşağıdaki gibidir. Görüleceği üzere child process'in parent id'si fork işlemi yapılan processin id'si fork işlemi yapılan process'in id'si de bash programının process id'sine eşit olduğu ps -aux ile net bir şekilde incelenebilir.


atexit Fonksiyonu

06:13

Bir program exit yaparken programdan çıkmadan önce çağrılmasını istediğimiz fonksiyonlar varsa bunlar için atexit fonksiyonunu kullanmamız gerekir. Bu fonksiyon parametre olarak aşağıda görüldüğü gibi geri dönüşü void parametre almayan bir fonksiyon adresini istemektedir. Bu fonksiyon istenildiği gibi çağrıldıktan sonra exit yapılırken devreye girer ve belirtilen fonksiyonlar çağrılarak çalıştırılır ve program sonlanır.



Yukarıda görüldüğü gibi foo ve bar foksiyonları doğrudan çağrılmamasına rağmen çalışmış ve program sonlanmıştır. Çalışma sırası stack veri yapısına uygun sırada olmaktadır.

printf fonksiyonunun türevleri [ printf, sprintf, snprintf, fprintf ]

23:17

Program çıktılarını ekrana, dosyaya vb. yerlere yazmak için kullanılan printf, sprintf, snprintf, fprintf fonksiyonlarını kısaca inceleyelim:

printf:


printf formatlı olarak ekrana yazmak için kullanılan bir fonksiyondur. Ortalama herkesin bildiği bir fonksiyondur.

int printf(const char *format, ...);

sprintf:

sprintf ise formatlı olarak bir veri yapısına yazan fonksiyondur.

int sprintf(char *str, const char *format, ...);




snprintf:

snprintf ise sprintf ile benzer biçimde çalışsa da farkı 2. parametre olarak aldığı değer kadar veri yapısına yazmasıdır.

int snprintf(char *str, size_t size, const char *format, ...);




fprintf:


fprintf ise formatlı olarak dosyaya yazan bir fonksiyondur.

int fprintf(FILE *stream, const char *format, ...);