Ladění programu pomocí gdb
Ladění programu pomocí gdb je vhodné pro práci v příkazovém řádku. Debugger gdb slouží pro krokování programu, inspekci proměnných, ale i analýzu core (soubory s obrazem paměti po pádu programu). Existují nadstavby jak pro textové rozhraní (např. cgdb), tak pro grafické rozhraní (např. ddd) nebo je možné ladit program přímo v integrovaném vývojovém prostředí (Eclipse). Text se bude dále zabývat použitím debuggeru přímo na příkazovém řádku.
Obsah
Ladění programu
Program, který chceme ladit pomocí gdb, je nutné přeložit s přepínačem -g
. Program natáhneme do debuggeru příkazem gdb vypocet
, načež je zobrazena licence a aktivuje se interní řádkové rozhraní debuggeru (v následujícím příkladu je vstup uživatel vyznačen tučně):
$ gdb vypocet GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-23.el5_5.2) Copyright (C) 2009 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". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /home/kerslage/vyuka/pre/vypocet...done. (gdb)
Pokud by program gdb vypíše hlášení no debugging symbols found, je potřeba zkontrolovat zadání parametru -g
při překladu jako parametr (pro překladač gcc
). V interním řádkovém rozhraní je možné zadávat příkazy, kterými je gdb řízen (viz dále).
Krokování programu
- list
- Příkaz list vypíše zdrojový kód programu včetně čísel řádků. Parametrem může být číslo řádku, jméno funkce, dvojice soubor:jménofunkce nebo rozsah řádků oddělený čárkou.
- break
- Příkaz break slouží k vytvoření bodu přerušení v programu (též zarážka). Parametrem může být číslo řádku nebo název funkce a oboje může být podobně jako u příkazu list upřesněno názvem souboru s dvojtečkou. Za parametr může být doplněno klíčové slovo if, za kterým je možné předepsat podmínku pro přerušení (např.
x>5
). - watch
- Příkaz watch definuje výraz, při jehož splnění je program pozastaven (např.
x>5
). - clear
- Příkaz clear slouží ke zrušení bodu přerušení definovaného příkazem break.
- next
- Příkaz next spustí program až do začátku následujícího příkazu ve zdrojovém kódu. Pokud je na aktuálním řádku volání funkce, je tato provedena celá.
- step
- Příkaz step udělá v programu jeden krok (tj. jeden příkaz). Pokud je na aktuálním řádku volání funkce, vstoupí se do ní a provádění se zastaví (bude možné funkci krokovat).
- until
- Příkaz unitl spustí program až do specifikovaného místa (číslo řádku, název funkce).
- finish
- Příkaz finish způsobí, že aktuální funkce je dokončena.
- continue
- Pokračování běhu programu (až do dalšího bodu přerušení).
- run
- Příkaz run slouží ke spuštění programu, který je do gdb natažen. Případné parametry uvedené za příkazem run jsou programu předány, jako by byl s nimi spuštěn z příkazového řádku.
Inspekce proměnných a paměti
- Příkaz print slouží k vypsání obsahu proměnné, která je zadána jako parametr. Předřazením znaku & je vypsána adresa, na které je proměnná umístěna (spolu s datovým typem).
- info locals
- Příkaz info locals vypíše všechny lokální proměnné v aktuálním kontextu programu.
- x
- Příkaz x slouží k inspekci obsahu paměti. Parametrem může být adresa v paměti, název funkce nebo znak & následovaný jménem proměnné (vypíše adresu paměti a její obsah).
- backtrace
- Příkaz backtrace vypíše obsah zásobníku ve smyslu seznamu aktuálního stavu volání funkcí (tj. všechna volání funkcí, resp. návratů z funkcí).
Ostatní
- quit
- Příkaz quit slouží k ukončení činnosti gdb.
- kill
- Příkaz kill ukončí běh právě zpracovávaného programu.
- help
- Příkaz help vypíše nápovědu. Parametrem může být libovolný příkaz.
- info
- Příkaz info vypisuje různé informace o stavu debuggeru. Parametrem může být například args (argumenty programu z příkazového řádku), breakpoints (výpis bodů přerušení), watchpoints (dtto), registers (obsah registrů procesoru), threads (spuštěné thready), set (interní nstavení gdb).
Příklad ladění programu
Mějme zdrojový kód programu v souboru vypocet.c
:
#include <stdio.h>
int main()
{
int a, x = 3;
a = x + 5;
printf("Vysledek: %d\n", a);
return 1;
}
Pak ho přeložíme spolu s ladícími informacemi (pomocí parametru -g
):
gcc -g -o vypocet vypocet.c
Dále je záznam práce s gdb, přičemž tučně jsou zvýrazněny vstupy uživatele. Komentář je pod příkladem (čísla řádků zcela vlevo jsou přidána dodatečně, aby bylo možné výpis komentovat):
1 $ gdb vypocet 2 Reading symbols from /home/ke/pokus/vypocet...done. 3 (gdb) break main 4 Breakpoint 1 at 0x4004cc: file vypocet.c, line 5. 5 (gdb) run 6 Starting program: /home/ke/pokus/vypocet 7 8 Breakpoint 1, main () at vypocet.c:5 9 5 int a, x = 3; 10 Missing separate debuginfos, use: debuginfo-install glibc-2.13-1.x86_64 11 (gdb) print a 12 $1 = 0 13 (gdb) print x 14 $2 = 0 15 (gdb) next 16 6 a = x + 5; 17 (gdb) print a 18 $3 = 0 19 (gdb) print x 20 $4 = 3 21 (gdb) next 22 7 printf("Vysledek: %d\n", a); 23 (gdb) print a 24 $5 = 8 25 (gdb) print x 26 $6 = 3 27 (gdb) continue 28 Continuing. 29 Vysledek: 8 30 31 Program exited with code 01. 32 (gdb) quit 33 $