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.
- Genel davranışı etkileyebilecek argümanları belirterek programı başlatın.
- Programı belirtilen koşullarda durdurun.
- Çökmeyi veya programın ne zaman durdurulduğunu inceleyin.
- 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…