Javítsa a kód minőségét, és megelőzze a váratlan eredményeket, ha megtanulja, hogyan használja a GNU Debuggert a nem kívánt hibák felfedésére a kódban.

A programozók és biztonsági kutatók nélkülözhetetlen készsége a hibakeresés. A hibakeresés erős megértése lehetővé teszi a végrehajtható fájl alacsonyabb szintű megértését, és az esetleges lappangó hibák észlelését.

A GNU debugger vagy GDB egy időtlen hibakereső eszköz, amelyre a programozók már évek óta támaszkodnak. Itt van a GDB használata Linuxon.

Mintaprogramok előkészítése

A GDB funkcióinak felfedezéséhez szükség lesz egy futtatható fájlra, amellyel kísérletezni lehet. A bemutató kedvéért a GDB-t egy kulcs-ellenőrző programmal fogod futtatni egyszer elérhető forráskóddal és hibakeresési szimbólumokkal, egyszer pedig anélkül. forráskódon és egy egyszerű többszálú programon, amely üzeneteket nyomtat a képernyőre, mind C nyelven írva, mind GCC-vel (GNU C) fordítva Fordítóprogram).

tudsz használjon bármilyen más C fordítót de ügyeljen arra, hogy ne csupaszítsa le a binárist.

instagram viewer

Valószínűleg a GDB-t fogod futtatni a saját programjaidon. Ezért feltétlenül állítsa össze őket a -g jelölje meg a gcc-vel a hibakeresési szimbólumok engedélyezéséhez.

A hibakeresési szimbólumok jelenléte nélkül, és egy erősen lecsupaszított binárissal, hibakeresést kell végrehajtania a program szétszerelésénél. Ez megköveteli, hogy jól ismerje az assembly nyelvet és hogyan működik a memóriafoglalás Linuxon a veremben és a regiszterekben lévő adatok megértéséhez.

Program futtatása GDB-ben

A GDB-ben több módon is futtathat egy programot. Vagy írd be gdb , és ha betöltődik, írja be fuss. Vagy indítsa el a gdb-t, majd használja a fájlt parancsot, töltse be a bináris fájlt a gdb-be, majd hajtsa végre a fuss parancs.

Ha a programnak parancssori argumentumokra van szüksége a megfelelő működéshez, ügyeljen arra, hogy az argumentumokat a program neve után adja hozzá. Íme a szintaxis a program GDB-re való betöltéséhez és argumentumokkal történő végrehajtásához:

gdb 
run

Vagy:

gdb
file
run

Töréspontok beállítása GDB-vel

A hibakeresés töréspontjai kézzel beállított kemény stopok a kódban, amelyek leállítják a végrehajtás folyamatát, amikor a program elér egy töréspontot. A töréspontok beállításával átléphet a kódon, és megvizsgálhatja, hogy a végrehajtás egyes szakaszai hogyan befolyásolják az adatokat és a változókat.

A GDB-ben egy program hibakeresése során hibakeresési szimbólumokkal beállíthat egy töréspontot a függvény neve alapján, vagy beállíthat egy töréspontot a sorszám alapján. Íme a szintaxis:

break main
break 47

Az aktuális hibakeresési munkamenet összes töréspontjának megtekintéséhez írja be:

info breakpoints

Egy adott vagy több töréspont törléséhez írja be:

delete 2
delete 3-5

A GDB lehetővé teszi feltételes töréspontok beállítását is, vagyis a program csak akkor áll le, ha egy adott feltétel teljesül a végrehajtás során. Ez lehet egy változó értékének változása vagy egy sikertelen függvényhívás, vagy bármi, amit akarsz. Íme a szintaxis a feltételes töréspontok beállításához:

break  if n == 2

Ha egy töréspont elérése után folytatni szeretné a program végrehajtását, írja be a folytatni parancs:

continue

Átlépés a kódon

A kódon való átlépés kulcsfontosságú annak megértéséhez, hogy a program hogyan kezeli az adatokat. A program különböző funkcióinak átlépésével és az adatok állapotának vizsgálatával jobban megértheti, hogy a program hogyan valósítja meg a kódban írt logikát.

Segít az összeomlások gyökerének és a tanulmányi programok viselkedésének sebészi pontossággal történő felismerésében is, mivel tetszés szerint léphet át a kód minden során. A GDB-ben három elsődleges módon léphet át a kódon:

  1. lépés: Ez a parancs arra utasítja a GDB-t, hogy lépjen a forrásfájl következő sorába. Ez lehetővé teszi, hogy lényegében soronként bejárja a forráskód hosszát.
  2. következő: Ez a parancs végrehajtja a forráskód következő sorát az aktuális függvényen belül, majd leáll. következő egy függvényt egyetlen sorként kezel, így ha a függvényhívás előtt használja a következőt, akkor egyetlen sorként kezeli, és átlép rajta, ellentétben a lépés parancs.
  3. Befejez: A befejező parancs végrehajtja az aktuális függvényen belüli összes többi sort, majd leáll.

Változók vizsgálata

A kódon való átlépés során meg szeretné vizsgálni a változók értékét, hogy megtudja, hogyan változtatja meg őket a program logikája. Íme a szintaxis a változók értékének megtekintéséhez a GDB-ben:

print 

Abban az esetben, ha egy változó értékének változásait minden frissítéskor ki szeretné nyomtatni, használja a display parancsot. Ez különösen akkor hasznos, ha egy változó értékét egy ciklusban szeretné nyomon követni és kinyomtatni:

display 

Figyelőpontok beállítása

A figyelési pontok és a feltételes töréspontok szorosan összefüggenek, mivel mindkettő reagál a program változásaira. A figyelőpontok a kódban lévő adatok változásainak nyomon követésére szolgálnak. Például előfordulhat, hogy a program megszakad, amikor egy változó értéke megváltozik. Íme, hogyan kell ezt megtenni a GDB-vel:

watch 

Szálspecifikus hibakeresés GDB-vel

A GDB lehetővé teszi szál-specifikus hibakeresés végrehajtását többszálú programokkal végzett munka során. A demonstráció kedvéért egy egyszerű C programmal fogunk dolgozni, amely négy szálat használ az üzenetek nyomtatásához az egyes szálakkal.

A programban jelenleg megjelent szálak megtekintéséhez használja a info parancs:

info threads

Egy adott szál kezeléséhez kiválaszthatja azt a listából az indexszámával. Például:

thread 2

A szál kiválasztása után végigléphet annak végrehajtási folyamatán a lépés, következő, és Befejez parancsokat a fent bemutatott módon.

Távoli hibakeresés GDB-vel

Távolról is hibakereshet egy másik rendszeren található programokat. Ehhez be kell állítania a gdbservert a célgépen. Könnyen telepítheti a disztribúció alapértelmezett csomagkezelőjével vagy más telepített csomagkezelők a rendszerén.

Például a gdbserver telepítéséhez Ubuntu vagy Debian alapú rendszereire használja az APT-t:

sudo apt install gdbserver

A telepítés után lépjen be a bináris mappába, és futtassa ezt a parancsot a gdbserver elindításához:

gdbserver :

A gdbservernek azt a kimenetet kell visszaadnia, hogy fent van, és a megadott porton figyel. Most az ügyfélgépen indítsa el a GDB-t, majd csatlakozzon a távoli kiszolgálóhoz a segítségével cél parancs:

target remote :

GDB-szkriptek írása a hibakeresés automatizálására

A GDB lehetővé teszi a programozóknak, hogy GDB-szkripteket írjanak, amelyek automatikusan végrehajtják a GDB-parancsokat. Ez rendkívül sokat segít, ha ugyanazt a kódrészletet többször próbálja hibakeresni. Ahelyett, hogy minden alkalommal be kellene állítania a töréspontot, át kellene lépnie a kódon, és ki kellene nyomtatnia a változó értékeket a bináris fájl minden egyes betöltésekor, használhat egy GDB-szkriptet a teljes folyamat automatizálására.

Íme egy példa:

set logging enabled on
set logging file sample.out
break main
command 1
backtrace
print N
continue
end
quit

A fenti szkriptben azt mondod a GDB-nek, hogy engedélyezze a naplózást, és mentse a naplót egy nevű fájlba minta.ki, majd állítson be egy töréspontot a fő- funkció.

Az 1-es számú törésponthoz, ebben az esetben a fő funkciónál lévő törésponthoz, futtassa a következő parancsokat: visszanyom, nyomtatás, folytatni. Alapvetően a GDB először egy visszakövetést fog futtatni, majd kiírja az "N" változó értékét, folytatja a végrehajtást, és végül kilép.

A szkript végrehajtásához használja a következőket:

gdb -x