GNU Hata Ayıklayıcı veya GDB: Linux Programları için Güçlü Bir Kaynak Kodu Hata Ayıklama aracı


Hata ayıklayıcı herhangi bir yazılım geliştirme sisteminde hayati bir rol oynar. Hiç kimse aynı anda hatasız bir kod yazamaz. Geliştirme sürecinde hatalar ortaya çıkıyor ve daha fazla geliştirme için çözülmesi gerekiyor. Bir geliştirme sistemi hata ayıklayıcı olmadan tamamlanmış sayılmaz. Açık kaynak geliştiricileri topluluğu göz önüne alındığında, GNU Debugger onların en iyi seçimidir. UNIX tipi platformlarda ticari yazılım geliştirmek için de kullanılır.

GNU Hata Ayıklayıcı, aynı zamanda gdb olarak da bilinir, kod yürütülürken veya bir programın çökmeden önce ne yapmaya çalıştığını gizlice incelememize olanak tanır. GDB temel olarak kaynak kodundaki kusurları yakalamak için dört ana şeyi yapmamıza yardımcı olur.

  1. Genel davranışı etkileyebilecek argümanları belirterek programı başlatın.
  2. Programı belirtilen koşullarda durdurun.
  3. Çökmeyi veya programın ne zaman durdurulduğunu inceleyin.
  4. Kodu değiştirin ve değiştirilen kodla anında denemeler yapın.

Çok fazla çaba harcamadan C ve C++ ile yazılmış programların hatalarını ayıklamak için gdb'yi kullanabiliriz. Şu an itibariyle D, Modula-2, Fortran gibi diğer programlama dillerine yönelik destek kısmidir.

GNU Hata Ayıklayıcı veya GDB'yi kullanmaya başlama

GDB, gdb komutu kullanılarak çağrılır. gdb verildiğinde, platform hakkında bazı bilgiler görüntüler ve sizi aşağıda gösterildiği gibi (gdb) istemine bırakır. .

[root@fedora20 ~]# gdb
Örnek Çıktı
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20 
Copyright (C) 2013 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law.  Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-redhat-linux-gnu". 
Type "show configuration" for configuration details. 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
Find the GDB manual and other documentation resources online at: 
<http://www.gnu.org/software/gdb/documentation/>. 
For help, type "help". 
Type "apropos word" to search for commands related to "word". 
(gdb)

Gdb'de bulunan farklı komut sınıflarını görmek için help list yazın. O sınıftaki komutların listesi için yardım ve ardından sınıf adını yazın. Tüm komutların listesi için help all yazın. Komut adı kısaltmalarına, açık olmaları koşuluyla izin verilir. Örneğin, sonraki veya cn yazabilirsiniz. devam et için > vb.

En Sık Kullanılan GDB Komutları

Yaygın olarak kullanılan gdb komutları aşağıdaki tabloda listelenmiştir. Bu komutlar gdb komut isteminden (gdb) kullanılacaktır.

Command

Açıklama

run

Bir programın yürütülmesini başlatın

quit

gdb'den çık

print expr

expr değişken adı olabileceği yerde ifadeyi yazdır

next

Sonraki satıra git

step

Sonraki satıra geçin

continue

Geçerli satırdan programın sonuna veya bir sonraki kırılma noktasına kadar devam et

adım ve sonraki komutları arasındaki farka dikkat edin. Sonraki satır bir işlev çağrısıysa sonraki komutu işlevin içine girmez. Oysa step komutu fonksiyonun içine girip orada ne olduğunu görebilir.

GDB ile örnek bir oturum

Aşağıdaki kaynak kodunu göz önünde bulundurun.


// sum.c
#include <stdio.h> 

int sum (int a, int b) { 
	int c; 
	c = a + b; 
	return c; 
} 

int main() { 
	int x, y, z; 
	printf("\nEnter the first number: "); 
	scanf("%d", &x); 
	printf("Enter the second number: "); 
	scanf("%d", &y); 
	z = sum (x, y); 
	printf("The sum is %d\n\n", z); 
	return 0; 
}

Çıktı dosyasında hata ayıklamak için aynısını -g seçeneğiyle gcc'ye aşağıdaki gibi derlememiz gerekiyor.

gcc -g sum.c -o sum

sum çıktı dosyası aşağıdaki 2 yoldan biriyle gdb'ye eklenebilir:

1. Çıktı dosyasını gdb'ye argüman olarak belirterek.

gdb sum

2. file komutunu kullanarak çıktı dosyasını gdb içinde çalıştırmak.

gdb
(gdb) file sum

list komutu, kaynak kod dosyasındaki satırları listeler ve işaretçiyi hareket ettirir. Yani ilk liste ilk 10 satırı görüntüler ve sonraki liste sonraki 10 satırı görüntüler ve bu şekilde devam eder.

(gdb) list
1	#include <stdio.h>   
2	 
3	int sum (int a, int b) { 
4		int c; 
5		c = a + b; 
6		return c; 
7	} 
8	 
9	int main() { 
10		int x, y, z;

Yürütmeyi başlatmak için çalıştır komutunu verin. Artık program normal şekilde yürütülüyor. Ancak hata ayıklama için kaynak koduna bazı kesme noktaları koymayı unuttuk, değil mi? Bu kesme noktaları işlevler için veya belirtilen satırlarda belirtilebilir.

(gdb) b main

Not: break için b kısaltmasını kullandım.

Ana fonksiyonda kırılma noktası ayarlandıktan sonra programın tekrar çalıştırılması 11. satırda duracaktır. Satır numarası önceden biliniyorsa aynı şey geçerli olabilir.

(gdb) b sum.c:11

Şimdi sonraki veya n komutunu kullanarak kod satırlarında ilerleyin. İşlevde bir kesme noktası ayarlanmadıkça sonraki komutunun işlev kodunun içine girmediğini unutmamak önemlidir. Şimdi print komutunu deneyelim. Fonksiyon toplamındaki kırılma noktasını aşağıdaki gibi ayarlayın.

(gdb) b sum 
Breakpoint 1 at 0x4005aa: file sum.c, line 5. 
(gdb) r 
Starting program: /root/sum 

Enter the first number: 2 
Enter the second number: 3 

Breakpoint 1, sum (a=2, b=3) at sum.c:5 
5		c = a + b; 
(gdb) p a 
$1 = 2 
(gdb) p b 
$2 = 3
(gdb) c 
Continuing. 
The sum is 5 

[Inferior 1 (process 3444) exited normally]

Çalıştırılmakta olan program komut satırı parametreleri gerektiriyorsa, run komutuyla birlikte aynısını sağlayın.

(gdb) run   . . .

Mevcut çalışan programla ilişkili paylaşılan kütüphane dosyaları olarak listelenebilir.

(gdb) info share 
From                To                  Syms Read   Shared Object Library 
0x00000035a6000b10  0x00000035a6019c70  Yes         /lib64/ld-linux-x86-64.so.2 
0x00000035a641f560  0x00000035a6560bb4  Yes         /lib64/libc.so.6

Değişkenleri Değiştirme

GDB ayrıca programın yürütülmesi sırasında değişkenleri değiştirme yeteneğine de sahiptir. Hadi bunu deneyelim. Yukarıda bahsedildiği gibi 16. satıra kesme noktasını ayarlayın ve programı çalıştırın.

(gdb) r 
Starting program: /root/sum 

Enter the first number: 1 
Enter the second number: 2 

Breakpoint 1, main ( ) at sum.c:16 
16		printf("The sum is %d\n\n", z); 
(gdb) set z=4 
(gdb) c 
Continuing. 
The sum is 4

Şimdi a=1, b=2 ve sonuç z=3 olmalıdır. Ancak burada ana fonksiyonda nihai sonucu z=4 olarak değiştirdik. Bu şekilde gdb kullanılarak hata ayıklama daha kolay hale getirilebilir.

Kesme Noktalarını Etkinleştir/Devre Dışı Bırak

Tüm kesme noktalarının listesini almak için bilgi kesme noktaları yazın.

(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep y   0x00000000004005c2 in main at sum.c:11

Burada tek bir kırılma noktası vardır ve o da To'dur. etkin kesme noktalarını devre dışı bırakın disable komutuyla birlikte kesme noktası numarasını belirtin. Daha sonra etkinleştirmek için enable komutunu kullanın.

(gdb) disable 1 
(gdb) info breakpoints 
Num     Type           Disp Enb Address            What 
1       breakpoint     keep n   0x00000000004005c2 in main at sum.c:11

Kesme noktalarını delete komutuyla da silebilirsiniz.

Çalışan İşlemlerde hata ayıklama

Bir GNU/Linux sisteminde arka planda çok sayıda süreç çalışmaktadır. Çalışan bir süreçte hata ayıklamak için öncelikle o sürecin süreç kimliğini bulmamız gerekir. pidof komutu size bir sürecin pid'ini verir.

pidof <process_name>

Şimdi bu pid'i gdb'ye eklememiz gerekiyor. 2 yol var.

1. gdb ile birlikte pid'i de belirterek.

gdb -p <pid>

2. gdb'den attach komutunu kullanma.

(gdb) attach <pid>

Şimdilik bu kadar. Bunlar yalnızca kaynak kodunda hata ayıklamaya iyi bir başlangıç yapmak için gdb'nin temelleridir ve yukarıda açıklananlardan çok daha fazlasıdır. Örneğin yığın bilgilerini, ortam değişkenlerini ve çok daha fazlasını kullanarak hata ayıklayabiliriz. Tüm bu şeylerle oynamaya çalışın…