GDB je základní nástroj pro programátory k ladění jejich kódu.
Tento článek vysvětluje, jak můžete použít gdb k ladění programu pomocí základního souboru, jak zobrazit instrukce v assembleru vašeho programu a jak načíst programy sdílené knihovny pro ladění.
Ladění programu pomocí základního souboru
Soubor jádra nebo výpis jádra je soubor, který zaznamenává obraz paměti běžícího procesu a jeho stav. Používá se při post-mortem ladění programu, který se zhroutil, když běžel mimo ladicí program.
$ gdb executable_name core_file_name (gdb)
Výše uvedený příkaz načte soubor jádra pro spustitelný soubor a vyzve gdb shell.
Ke zkoumání toho, co se skutečně stalo, můžete použít gdb backtrace nebo jiné příkazy. Všimněte si, že soubor core_file bude ignorován, pokud spustitelný soubor běží pod gdb.
Vytiskněte si pokyny k sestavení
Pomocí příkazu disassemble můžete vytisknout instrukce pro sestavení funkce. Můžete také zadat 2 rozsahy adres a pokyny mezi nimi budou rozebrány a vytištěny v konzole gdb.
(gdb) disassemble main Dump of assembler code for function main: 0x00000000004004ac : push %rbp 0x00000000004004ad : mov %rsp,%rbp 0x00000000004004b0 : mov $0x0,%eax 0x00000000004004b5 : pop %rbp 0x00000000004004b6 : retq End of assembler dump.
Načíst symboly sdílené knihovny
Mnohokrát budou programátoři ve svém kódu používat sdílené knihovny. Někdy se možná budeme chtít podívat do samotné sdílené knihovny, abychom pochopili, co se děje. Zde ukážu příklad použití knihovny GLib a jak pro ni získat informace o ladění.
Ve výchozím nastavení všechny distribuce do určité míry odstraní knihovny. Kompletní informace o ladění budou uloženy v samostatném balíčku, který pojmenují jako „package-1.0-dbg“, a pouze v případě potřeby může uživatel nainstalovat.
Když nainstalujete „package-1.0-dbg“, ve výchozím nastavení gdb načte všechny ladicí informace, ale abychom pochopili tento koncept, uvidíme, jak ručně načíst soubor symbolu.
#include <stdio.h> #include <glib.h> struct a { int a; int b; }; void *print( struct a *obj,int as) { printf("%d:%d\n",obj->a,obj->b); } int main() { struct a *obj; obj = (struct a*)malloc(sizeof(struct a)); obj->a=3; obj->b=4; GList *list=NULL; list = g_list_append(list,obj); g_list_foreach(list,(GFunc)print,NULL); }
$ cc -g -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ -lglib-2.0 glib_test.c
Poznámka:Abyste mohli tento příklad vyzkoušet, musíte nainstalovat libglib2.0-0.
Nyní zahájíme ladění.
(gdb) b 1 Breakpoint 1 at 0x4007db: file a.c, line 1. (gdb) run ... (gdb) info sharedlibrary From To Syms Read Shared Object Library 0x00007ffff7dddaf0 0x00007ffff7df5c83 Yes (*) /lib64/ld-linux-x86-64.so.2 0x00007ffff7b016c0 0x00007ffff7b6e5cc Yes (*) /lib/x86_64-linux-gnu/libglib-2.0.so.0 0x00007ffff7779b80 0x00007ffff7890bcc Yes (*) /lib/x86_64-linux-gnu/libc.so.6 0x00007ffff751f9a0 0x00007ffff7546158 Yes (*) /lib/x86_64-linux-gnu/libpcre.so.3 0x00007ffff7307690 0x00007ffff7312c78 Yes (*) /lib/x86_64-linux-gnu/libpthread.so.0 0x00007ffff70fc190 0x00007ffff70ff4f8 Yes (*) /lib/x86_64-linux-gnu/librt.so.1 (*): Shared library is missing debugging information.
Z výše uvedených informací si všimněte, že knihovna libglib-2.0.so.0 má symboly, ale ladicí informace jako file_name, line_no atd... chybí.
Stáhněte si ladicí informace pro balíček z příslušné distribuce (libglib2.0-0-dbg v Debianu – Wheezy).
(gdb) add-symbol-file /home/lakshmanan/libglib-2.0.so.0.3200.4 0x00007ffff7b016c0 add symbol table from file "/home/lakshmanan/libglib-2.0.so.0.3200.4" at .text_addr = 0x7ffff7b016c0 (y or n) y Reading symbols from /home/lakshmanan/libglib-2.0.so.0.3200.4...done.
Adresa uvedená v příkazu add-symbol-file je adresa „Od“ vytištěná příkazem „info sharedlibrary“. Nyní jsou načteny ladicí informace.
... ... (gdb) n g_list_foreach (list=0x0, func=0x4007cc , user_data=0x0) at /tmp/buildd/glib2.0-2.33.12+really2.32.4/./glib/glist.c:897
Někdy sdílené knihovny nebudou mít ani žádné symboly a v takových situacích bude výše uvedená metoda užitečná.