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.
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:
- 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.
- 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.
- 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