Memakai GDB di Linux
GDB (GNU Debugger) adalah debugger cross platform. GDB biasanya dijalankan di mode command line, tapi bisa juga dalam mode tui (text user interface). Mode command line lebih sulit dan mungkin kurang nyaman bagi pemula, tapi mode ini selalu tersedia, dan berjalan baik. Mode tui kadang-kadang tidak berjalan baik di terminal tertentu (terutama kalau mengakses sistem via SSH).
GDB bisa digunakan untuk mendebug file dengan debugging information dan source, atau binary saja (tanpa info). Tutorial ini mencakup keduanya, tapi saya akan berkonsentrasi pada file executable tanpa informasi debug (stripped).
Versi gdb di tutorial ini adalah 7.6.2
, jika ada perintah yang tidak bekerja dan Anda memakai GDB yang lebih lama, upgradelah gdb Anda.
Memulai dan keluar dari GDB
Cara termudah adalah memulai dengan executable
gdb <executable>
Jika programnya memiliki parameter:
gdb --args <executable> <param1> <param2> ...
Jika program crash dan Anda mengeset environment sehingga menghasilkan file core (biasanya crash dengan pesan core dumped), maka kita bisa mendebug memori ketika crash terjadi
gdb <executable> <filecore>
Jika program sudah berjalan, kita bisa mendebug process id yang sudah berjalan:
gdb <executable> <pid>
Kita juga bisa langsung memulai gdb dan meload filenya belakangan
(gdb) file <namaexecutable>
Atau kita bisa attach ke pid tertentu
(gdb) attach <pid>
Setelah itu kita bisa mulai menjalankan program dengan run
:
(gdb) run
Tapi biasanya kita akan mengeset dulu breakpoint sebelum menjalankan program dengan run
.
Sebelum ke perintah lain, untuk keluar dari gdb, gunakan perintah quit
lalu enter.
Melihat source
Jika program dicompile dengan informasi debuga (misalnya gcc -g main.c
), kita bisa melihat source code dengan:
(gdb) list
Mengeset breakpoint
Untuk mengeset breakpoint, gunakan break
atau cuku b
saja. Ini bisa diikuti nama fungsi atau alamat. Contoh
(gdb) break main
(gdb) break *0x0000000000400c1e
Kita bisa melihat daftar breakpoint yang ada dengan info breakpoints
. Secara umum perintah gdb bisa dipersingkat asalkan tidak ambigu. Misalnya info breakpoints
bisa disingkat jadi info brea
atau bahkan i b
.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400c22 <main+4>
Melihat disassembly
Untuk melihat diassembly fungsi yang namanya diketahui, gunakan disas
diikuti nama fungsi:
(gdb) disas main
Jika nama tidak diketahui, kita bisa mengunaan x
(singkatan dari examine
):
(gdb) x/10i 0x0000000000400d5b
Perhatikan bahwa defaultnya disassembly menggunakan syntax att, jika Anda lebih suka sintaks intel
(gdb) set disassembly-flavor intel
Melihat status register
Untuk melihat register saat ini, gunakan info registers
atau cukup i r
.
Melihat isi memori
Perintah x
bisa digunakan untuk banyak hal, contohnya:
Tampilkan 5
byte (b
) sebagai hexa (x
), byte tersebut ada di alamat memori yang ditunjuk oleh register $edx
(gdb) x/5bx $edx
Atau untuk alamat memori absolut:
(gdb) x/5bx 0x10000
Di sini b
bisa diganti dengan h
(short/2 byte), w
(word/4 byte) atau g
(giant/8 byte). Secara default displaynya memakai signed decimal, tapi kita bisa memakai x
untuk heksadesimal dan u
untuk unsigned.
Anda bisa melihat lebih lengkap di sini
https://sourceware.org/gdb/current/onlinedocs/gdb/Data.html#Data
Melihat kondisi stack
Perintah bt
atau backtrace
akan mencetak stack backtrace. Perintah info frame
(atau i f
) akan mencetak frame saat ini.
Stepping
Jika source code tersedia, kita bisa menggunakan step
untuk ke baris berikutnya atau step in ke dalam fungsi, jika perintah berikut adalah function call. Jika kita ingin ke baris berikutnya tapi tidak ingin masuk ke dalam fungsi, gunakan next
.
Perintah tersebut juga bisa diikuti dengan angka, jika kita ingin mengulangi n
kali. Jadi:
next 10
Akan mengeksekusi next
sepuluh kali.
Jika kita ingin berhenti sampai
Mengikuti child ketika ada fork
Secara default gdb akan mengikuti parent ketika ada fork()
, supaya kita mengikuti child process
(gdb) set follow-fork-mode child
File .gdbinit
Setting-setting yang sering digunakan bisa disimpan di ~/.gdbinit
, misalnya Anda suka disassembly format intel dan kita sering mendebug child process, kita bisa memasukkan baris:
set disassembly-flavor intel
set follow-fork-mode child
Saya sering mengulangi perintah yang sama, jadi saya suka menyimpan history perintah di file:
set history filename ~/.gdb_history
set history save
Ketika mendebug assembly, perintah ini berguna, supaya otomatis menampilkan instruksi assembly berikut
set disassemble-next-line on
Copyright © 2009-2018 Yohanes Nugroho