Kihagyás

Debuggolás IDE-vel

A debuggolás olyan folyamat, amely segít megtalálni a program hibáit. Az IDE-kben található debugger (GDB vagy saját készítésű). Ahhoz, hogy használhassuk, fordítsuk/indítsuk a projektet Debug módban, így a debuggolást segítő extra szimbólumok kerülnek a binárisba. A printf alapú debuggolást bizonyára mindenki használta már. A Debug mód használata ezt a fajta debuggolást teszi gyorsabbá és konfigurálhatóbbá. A Debug módban futó kódhoz kapunk egy ilyesmi kezelőfelületet:

controls

Fukciók balról jobbra:

  • Continue: A Debug módú futás újraindítása, mikor breakpointnál áll a program
  • Stop: Futás leállítása
  • Pause: debugger futásának felfüggesztése (nem breakpointnál, hanem ahol éppen áll)
  • Restart: teljesen újraindítja a Debug módú futtatást
  • Show current line: odaugrik a sorra, ahol épp a végrehajtás áll
  • Step into: Következő utasítás végrehajtása úgy, hogy az esetleges függvényhívásokba is belelépünk
  • Next: Következő utasításra lépünk, de a függvényhívásokba nem lépünk bele
  • Step out: Befejeződik az aktuális metódus végrehajtása és a hívási ponton fog megint felfüggesztődni a program futása.

A képek CodeLite segítségével készültek. Minden IDE debugger felülete hasonló elveken alapszik.

Breakpoint

A legtöbb IDE-vel a kódsorok elé kattintva breakpointokat helyezhetünk el. Jelük általában egy piros pötty. Ha Debug módban indítottuk el a programot, akkor a megjelölt sorban lévő utasítás végrehajtása előtt fel lesz függesztve a program futása. Ilyenkor hasznos információkhoz juthatunk, például megnézhetjük a lokális változókat, azok adattagjait stb.

Feltételes breakpoint

Ha azt szeretnénk, hogy a breakpointnál csak bizonyos esetekben álljon meg a program futása, feltételeket is megfogalmazhatunk. Jobb egérgombbal kattintva a breakpointokra részletesen szerkeszthető.

br_cond

A képen a feltételt alulról a második szövegmezőben szerepel: i == 2, vagyis csak akkor fog megállni itt a debugger, ha a lokális i változó értéke 2 (igazra értékelődik ki a feltétel). Az alsó szövegmezőbe utasításokat lehet megadni, amik megálláskor hajtódnak végre. Például:

1
2
print i
continue

Kiíratja az i változó értékét, utána a continue paranccsal folytatódik a program végrehajtása. CodeLite esetén itt a gdb-ben adunk parancsokat. A gdb-ről és a lehetséges parancsokról a következő anyagban lesz szó.

Lépkedés az utasítások között

A végrehajtás az alsó képen látható breakpointnál áll. Ekkor a my_to_upper még nem hívódott meg.

br_started

A Step in megnyomására belépünk a my_to_upper-be.

br1

Ha megint Step in-t nyomunk, akkor a függvény utasításain kezdünk el lépkedni (mivel nincs függvényhívás egyik utasításba sem, ezért nem ugrik bele semmibe. Ebben az esetben ugyanaz a hatása, mintha Next-et nyomnánk.

Ha nem akarunk végigmenni a my_to_upper összes utasításán, a Step out-al gyorsan előreugorhatunk a hívás helyére. Vagyis befejeződik a my_to_upper futása és a végrehajtás a hívási helyen, azaz a main-ben fog állni. Következőleg a hívás utáni első utasítást fogja végrehajtani. Itt vagy újraindítjuk a program futását (continue) vagy lépkedünk tovább egyesével

Hasznos információk kinyerése

Az utasításonkénti végrehajtás során hasznos adatokat olvashatunk ki a programról. Megnézhetjük például a lokális változók értékeit, a hívási láncot, a végrehajtási szálakat, kiírathatjuk konkrét memóriaterületek tartalmát stb.

Lokális változók

A képen a fentebbi my_to_upper függvény lokális változóit láthatjuk. Megmondja nekünk a debugger, hogy a paraméterben kapott inp pointer, egy olyan memóriaterületre mutat, ami a halt and CATCH fire stringet tartalmazza. Ha szükséges, jobb egérgombbal felül tudjuk írni a változók értékeit.

locals

Call stack

Ha valahol megáll a debugger, akkor az aktuális stack frame lokális változói mellett a call stack-et is nézegethetjük, vagyis a hívási láncot, ami az adott állapothoz elvezetett. Ez nagyon hasznos lehet olyankor is, amikor a programunk kap egy segmentation fault-ot vagy kivétel dobódik.

cs

A képen a hívási lánc csak két elemű: a main-ből meg lett hívva a my_to_upper függvény. A táblázat legszélén látjuk a konkrét utasítások memóriacímét is, ahol a végrehajtás áll illetve ahonnan a rákövetkező függvény hívása megtörtént.

Watch

A watch (figyelő) feltételek egy változó vagy egy kifejezés aktuális értékének változását monitorozzák. Olyasmi, mint egy feltételes breakpoint, annyi különbséggel, hogy a watch az érték változása esetén állítja meg a futást (a feltételes breakpoint pedig akkor, ha az adott utasításra lépve teljesül a feltétel). A watch-t akkor tudjk beállítani, ha a program épp fel van függesztve és a hivatkozott változók scope-on belül vannak.

Példafeladatok


Utolsó frissítés: 2022-03-11 13:58:17